diff options
Diffstat (limited to 'sw/source/ui/vba')
165 files changed, 23920 insertions, 0 deletions
diff --git a/sw/source/ui/vba/vbaaddin.cxx b/sw/source/ui/vba/vbaaddin.cxx new file mode 100644 index 0000000000..8fdfb00480 --- /dev/null +++ b/sw/source/ui/vba/vbaaddin.cxx @@ -0,0 +1,92 @@ +/* -*- 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 "vbaaddin.hxx" +#include <tools/urlobj.hxx> +#include <osl/file.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaAddin::SwVbaAddin( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, OUString aFileURL ) : + SwVbaAddin_BASE( rParent, rContext ), msFileURL(std::move( aFileURL )), mbInstalled( true ) +{ +} + +SwVbaAddin::~SwVbaAddin() +{ +} + +OUString SAL_CALL SwVbaAddin::getName() +{ + OUString sName; + INetURLObject aURL( msFileURL ); + ::osl::File::getSystemPathFromFileURL( aURL.GetLastName(), sName ); + return sName; +} + +void SAL_CALL +SwVbaAddin::setName( const OUString& ) +{ + throw uno::RuntimeException(" Fail to set name" ); +} + +OUString SAL_CALL SwVbaAddin::getPath() +{ + INetURLObject aURL( msFileURL ); + aURL.CutLastName(); + return aURL.GetURLPath(); +} + +sal_Bool SAL_CALL SwVbaAddin::getAutoload() +{ + return true; +} + +sal_Bool SAL_CALL SwVbaAddin::getInstalled() +{ + return mbInstalled; +} + +void SAL_CALL SwVbaAddin::setInstalled( sal_Bool _installed ) +{ + if( bool(_installed) != mbInstalled ) + { + mbInstalled = _installed; + // TODO: should call AutoExec and AutoExit etc. + } +} + +OUString +SwVbaAddin::getServiceImplName() +{ + return "SwVbaAddin"; +} + +uno::Sequence< OUString > +SwVbaAddin::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Addin" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaaddin.hxx b/sw/source/ui/vba/vbaaddin.hxx new file mode 100644 index 0000000000..f177e7935d --- /dev/null +++ b/sw/source/ui/vba/vbaaddin.hxx @@ -0,0 +1,53 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAADDIN_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAADDIN_HXX + +#include <ooo/vba/word/XAddin.hpp> +#include <vbahelper/vbahelperinterface.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XAddin> SwVbaAddin_BASE; + +class SwVbaAddin : public SwVbaAddin_BASE +{ +private: + OUString msFileURL; + bool mbInstalled; + +public: + /// @throws css::uno::RuntimeException + SwVbaAddin(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, OUString aFileURL); + virtual ~SwVbaAddin() override; + + // Attributes + virtual OUString SAL_CALL getName() override; + virtual void SAL_CALL setName(const OUString& _name) override; + virtual OUString SAL_CALL getPath() override; + virtual sal_Bool SAL_CALL getAutoload() override; + virtual sal_Bool SAL_CALL getInstalled() override; + virtual void SAL_CALL setInstalled(sal_Bool _installed) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAADDIN_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaaddins.cxx b/sw/source/ui/vba/vbaaddins.cxx new file mode 100644 index 0000000000..6fd6e42f86 --- /dev/null +++ b/sw/source/ui/vba/vbaaddins.cxx @@ -0,0 +1,96 @@ +/* -*- 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 "vbaaddins.hxx" +#include "vbaaddin.hxx" +#include <unotools/pathoptions.hxx> +#include <sal/log.hxx> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/ucb/SimpleFileAccess.hpp> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +static uno::Reference< container::XIndexAccess > lcl_getAddinCollection( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) +{ + XNamedObjectCollectionHelper< word::XAddin >::XNamedVec aAddins; + + // first get the autoload addins in the directory STARTUP + uno::Reference< lang::XMultiComponentFactory > xMCF( xContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference<ucb::XSimpleFileAccess3> xSFA(ucb::SimpleFileAccess::create(xContext)); + SvtPathOptions aPathOpt; + // FIXME: temporary the STARTUP path is located in $OO/basic3.1/program/addin + const OUString& aAddinPath = aPathOpt.GetAddinPath(); + SAL_INFO("sw.vba", "lcl_getAddinCollection: " << aAddinPath ); + if( xSFA->isFolder( aAddinPath ) ) + { + const uno::Sequence< OUString > sEntries = xSFA->getFolderContents( aAddinPath, false ); + for( const OUString& sUrl : sEntries ) + { + if( !xSFA->isFolder( sUrl ) && sUrl.endsWithIgnoreAsciiCase( ".dot" ) ) + { + aAddins.push_back( uno::Reference< word::XAddin >( new SwVbaAddin( xParent, xContext, sUrl ) ) ); + } + } + } + + // TODO: second get the customize addins in the org.openoffice.Office.Writer/GlobalTemplateList + + uno::Reference< container::XIndexAccess > xAddinsAccess( new XNamedObjectCollectionHelper< word::XAddin >( std::move(aAddins) ) ); + return xAddinsAccess; +} + +SwVbaAddins::SwVbaAddins( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext ): SwVbaAddins_BASE( xParent, xContext, lcl_getAddinCollection( xParent,xContext ) ) +{ +} +// XEnumerationAccess +uno::Type +SwVbaAddins::getElementType() +{ + return cppu::UnoType<word::XAddin>::get(); +} +uno::Reference< container::XEnumeration > +SwVbaAddins::createEnumeration() +{ + uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); + return xEnumerationAccess->createEnumeration(); +} + +uno::Any +SwVbaAddins::createCollectionObject( const css::uno::Any& aSource ) +{ + return aSource; +} + +OUString +SwVbaAddins::getServiceImplName() +{ + return "SwVbaAddins"; +} + +css::uno::Sequence<OUString> +SwVbaAddins::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.Addins" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaaddins.hxx b/sw/source/ui/vba/vbaaddins.hxx new file mode 100644 index 0000000000..0072b36d5a --- /dev/null +++ b/sw/source/ui/vba/vbaaddins.hxx @@ -0,0 +1,46 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAADDINS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAADDINS_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XAddins.hpp> + +typedef CollTestImplHelper<ooo::vba::word::XAddins> SwVbaAddins_BASE; + +class SwVbaAddins : public SwVbaAddins_BASE +{ +public: + /// @throws css::uno::RuntimeException + SwVbaAddins(const css::uno::Reference<ov::XHelperInterface>& xParent, + const css::uno::Reference<css::uno::XComponentContext>& xContext); + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override; + + // SwVbaAddins_BASE + virtual css::uno::Any createCollectionObject(const css::uno::Any& aSource) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAADDINS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaapplication.cxx b/sw/source/ui/vba/vbaapplication.cxx new file mode 100644 index 0000000000..d3f290db28 --- /dev/null +++ b/sw/source/ui/vba/vbaapplication.cxx @@ -0,0 +1,529 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column:100 -*- */ +/* + * 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/task/XStatusIndicatorSupplier.hpp> +#include <com/sun/star/task/XStatusIndicator.hpp> +#include <com/sun/star/util/thePathSettings.hpp> +#include <com/sun/star/awt/XDevice.hpp> + +#include "vbaapplication.hxx" +#include "vbadocument.hxx" +#include "vbafilterpropsfromformat.hxx" +#include <sal/log.hxx> +#include <osl/file.hxx> +#include <vcl/svapp.hxx> +#include <vbahelper/vbahelper.hxx> +#include "vbawindow.hxx" +#include "vbasystem.hxx" +#include "vbaoptions.hxx" +#include "vbaselection.hxx" +#include "vbadocuments.hxx" +#include "vbaaddins.hxx" +#include "vbamailmerge.hxx" +#include "vbadialogs.hxx" +#include "vbawordbasic.hxx" +#include <ooo/vba/XConnectionPoint.hpp> +#include <ooo/vba/word/WdEnableCancelKey.hpp> +#include <ooo/vba/word/WdWindowState.hpp> +#include <ooo/vba/word/XApplicationOutgoing.hpp> +#include <ooo/vba/word/XBookmarks.hpp> +#include <comphelper/processfactory.hxx> +#include <comphelper/propertyvalue.hxx> +#include <cppu/unotype.hxx> +#include <editeng/acorrcfg.hxx> +#include <swdll.hxx> +#include <swmodule.hxx> +#include "vbalistgalleries.hxx" +#include <tools/urlobj.hxx> + +using namespace ::ooo; +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class SwVbaApplicationOutgoingConnectionPoint : public cppu::WeakImplHelper<XConnectionPoint> +{ +private: + SwVbaApplication* mpApp; + +public: + SwVbaApplicationOutgoingConnectionPoint( SwVbaApplication* pApp ); + + // XConnectionPoint + sal_uInt32 SAL_CALL Advise(const uno::Reference< XSink >& Sink ) override; + void SAL_CALL Unadvise( sal_uInt32 Cookie ) override; +}; + +} + +SwVbaApplication::SwVbaApplication( uno::Reference<uno::XComponentContext >& xContext ): + SwVbaApplication_BASE( xContext ) +{ +} + +SwVbaApplication::~SwVbaApplication() +{ +} + +sal_uInt32 +SwVbaApplication::AddSink( const uno::Reference< XSink >& xSink ) +{ + { + SolarMutexGuard aGuard; + SwGlobals::ensure(); + } + // No harm in potentially calling this several times + SW_MOD()->RegisterAutomationApplicationEventsCaller( uno::Reference< XSinkCaller >(this) ); + mvSinks.push_back(xSink); + return mvSinks.size(); +} + +void +SwVbaApplication::RemoveSink( sal_uInt32 nNumber ) +{ + if (nNumber < 1 || nNumber > mvSinks.size()) + return; + + mvSinks[nNumber-1] = uno::Reference< XSink >(); +} + +OUString SAL_CALL +SwVbaApplication::getName() +{ + return "Microsoft Word"; +} + +uno::Reference< word::XDocument > SAL_CALL +SwVbaApplication::getActiveDocument() +{ + return new SwVbaDocument( this, mxContext, getCurrentDocument() ); +} + +rtl::Reference<SwVbaWindow> +SwVbaApplication::getActiveSwVbaWindow() +{ + // #FIXME so far can't determine Parent + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW ); + uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); + return new SwVbaWindow( uno::Reference< XHelperInterface >(), mxContext, xModel, xController ); +} + +uno::Reference< css::uno::XComponentContext > const & +SwVbaApplication::getContext() const +{ + return mxContext; +} + +uno::Reference< word::XWindow > SAL_CALL +SwVbaApplication::getActiveWindow() +{ + return getActiveSwVbaWindow(); +} + +uno::Reference<word::XSystem > SAL_CALL +SwVbaApplication::getSystem() +{ + return uno::Reference< word::XSystem >( new SwVbaSystem( mxContext ) ); +} + +uno::Reference<word::XOptions > SAL_CALL +SwVbaApplication::getOptions() +{ + return uno::Reference< word::XOptions >( new SwVbaOptions( mxContext ) ); +} + +uno::Any SAL_CALL +SwVbaApplication::CommandBars( const uno::Any& aIndex ) +{ + try + { + return VbaApplicationBase::CommandBars( aIndex ); + } + catch (const uno::RuntimeException&) + { + return uno::Any(); + } +} + +uno::Reference< word::XSelection > SAL_CALL +SwVbaApplication::getSelection() +{ + return new SwVbaSelection( this, mxContext, getCurrentDocument() ); +} + +uno::Reference< word::XWordBasic > SAL_CALL +SwVbaApplication::getWordBasic() +{ + uno::Reference< word::XWordBasic > xWB( new SwWordBasic( this ) ); + return xWB; +} + +uno::Any SAL_CALL +SwVbaApplication::Documents( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaDocuments( this, mxContext ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaApplication::Addins( const uno::Any& index ) +{ + static uno::Reference< XCollection > xCol( new SwVbaAddins( this, mxContext ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaApplication::Dialogs( const uno::Any& index ) +{ + uno::Reference< word::XDialogs > xCol( new SwVbaDialogs( this, mxContext, getCurrentDocument() )); + if ( index.hasValue() ) + return xCol->Item( index ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaApplication::ListGalleries( const uno::Any& index ) +{ + uno::Reference< text::XTextDocument > xTextDoc( getCurrentDocument(), uno::UNO_QUERY_THROW ); + uno::Reference< XCollection > xCol( new SwVbaListGalleries( this, mxContext, xTextDoc ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +sal_Bool SAL_CALL SwVbaApplication::getDisplayAutoCompleteTips() +{ + return SvxAutoCorrCfg::Get().IsAutoTextTip(); +} + +void SAL_CALL SwVbaApplication::setDisplayAutoCompleteTips( sal_Bool _displayAutoCompleteTips ) +{ + SvxAutoCorrCfg::Get().SetAutoTextTip( _displayAutoCompleteTips ); +} + +sal_Int32 SAL_CALL SwVbaApplication::getEnableCancelKey() +{ + // the default value is wdCancelInterrupt in Word + return word::WdEnableCancelKey::wdCancelInterrupt; +} + +void SAL_CALL SwVbaApplication::setEnableCancelKey( sal_Int32/* _enableCancelKey */) +{ + // seems not supported in Writer +} + +sal_Int32 SAL_CALL SwVbaApplication::getWindowState() +{ + auto xWindow = getActiveWindow(); + if (xWindow.is()) + { + uno::Any aState = xWindow->getWindowState(); + sal_Int32 nState; + if (aState >>= nState) + return nState; + } + + return word::WdWindowState::wdWindowStateNormal; // ? +} + +void SAL_CALL SwVbaApplication::setWindowState( sal_Int32 _windowstate ) +{ + try + { + auto xWindow = getActiveWindow(); + if (xWindow.is()) + { + uno::Any aState; + aState <<= _windowstate; + xWindow->setWindowState( aState ); + } + } + catch (const uno::RuntimeException&) + { + } +} + +sal_Int32 SAL_CALL SwVbaApplication::getWidth() +{ + auto pWindow = getActiveSwVbaWindow(); + return pWindow->getWidth(); +} + +void SAL_CALL SwVbaApplication::setWidth( sal_Int32 _width ) +{ + auto pWindow = getActiveSwVbaWindow(); + pWindow->setWidth( _width ); +} + +sal_Int32 SAL_CALL SwVbaApplication::getHeight() +{ + auto pWindow = getActiveSwVbaWindow(); + return pWindow->getHeight(); +} + +void SAL_CALL SwVbaApplication::setHeight( sal_Int32 _height ) +{ + auto pWindow = getActiveSwVbaWindow(); + pWindow->setHeight( _height ); +} + +sal_Int32 SAL_CALL SwVbaApplication::getLeft() +{ + auto pWindow = getActiveSwVbaWindow(); + return pWindow->getLeft(); +} + +void SAL_CALL SwVbaApplication::setLeft( sal_Int32 _left ) +{ + auto pWindow = getActiveSwVbaWindow(); + pWindow->setLeft( _left ); +} + +sal_Int32 SAL_CALL SwVbaApplication::getTop() +{ + auto pWindow = getActiveSwVbaWindow(); + return pWindow->getTop(); +} + +void SAL_CALL SwVbaApplication::setTop( sal_Int32 _top ) +{ + auto pWindow = getActiveSwVbaWindow(); + pWindow->setTop( _top ); +} + +OUString SAL_CALL SwVbaApplication::getStatusBar() +{ + return ""; +} + +uno::Any SAL_CALL SwVbaApplication::getCustomizationContext() +{ + return uno::Any(); // ??? +} + +void SAL_CALL SwVbaApplication::setCustomizationContext(const uno::Any& /*_customizationcontext*/) +{ + // ??? +} + +void SAL_CALL SwVbaApplication::setStatusBar( const OUString& _statusbar ) +{ + // ScVbaAppSettings::setStatusBar() also uses the XStatusIndicator to show this, so maybe that is OK? + uno::Reference< frame::XModel > xModel = getCurrentDocument(); + if (xModel.is()) + { + uno::Reference< task::XStatusIndicatorSupplier > xStatusIndicatorSupplier( xModel->getCurrentController(), uno::UNO_QUERY ); + if (xStatusIndicatorSupplier.is()) + { + uno::Reference< task::XStatusIndicator > xStatusIndicator = xStatusIndicatorSupplier->getStatusIndicator(); + if (xStatusIndicator.is()) + xStatusIndicator->start( _statusbar, 100 ); + } + } + + // Yes, we intentionally use the "extensions.olebridge" tag here even if this is sw. We + // interpret setting the StatusBar property as a request from an Automation client to display + // the string in LibreOffice's debug output, and all other generic Automation support debug + // output (in extensions/source/ole) uses that tag. If the check for "cross-module" or mixed log + // areas in compilerplugins/clang/sallogareas.cxx is re-activated, this will have to be added as + // a special case. + + SAL_INFO("extensions.olebridge", "Client debug output: " << _statusbar); +} + +float SAL_CALL SwVbaApplication::CentimetersToPoints( float Centimeters ) +{ + return o3tl::convert(Centimeters, o3tl::Length::cm, o3tl::Length::pt); +} + +float SAL_CALL SwVbaApplication::PointsToCentimeters( float Points ) +{ + return o3tl::convert(Points, o3tl::Length::pt, o3tl::Length::cm); +} + +float SAL_CALL SwVbaApplication::PixelsToPoints( float Pixels, ::sal_Bool fVertical ) +{ + //Set up xDevice + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW ); + uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); + uno::Reference< frame::XFrame > xFrame( xController->getFrame(), uno::UNO_SET_THROW ); + uno::Reference< awt::XWindow > xWindow( xFrame->getContainerWindow(), uno::UNO_SET_THROW ); + css::uno::Reference< css::awt::XDevice > xDevice( xWindow, css::uno::UNO_QUERY ); + + return ooo::vba::PixelsToPoints(xDevice, Pixels, fVertical); +} + +float SAL_CALL SwVbaApplication::PointsToPixels( float Pixels, ::sal_Bool fVertical ) +{ + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW ); + uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); + uno::Reference< frame::XFrame > xFrame( xController->getFrame(), uno::UNO_SET_THROW ); + uno::Reference< awt::XWindow > xWindow( xFrame->getContainerWindow(), uno::UNO_SET_THROW ); + css::uno::Reference< css::awt::XDevice > xDevice( xWindow, css::uno::UNO_QUERY ); + + return ooo::vba::PointsToPixels(xDevice, Pixels, fVertical); +} + +float SAL_CALL SwVbaApplication::InchesToPoints( float Inches ) +{ + return o3tl::convert(Inches, o3tl::Length::in, o3tl::Length::pt); +} + +float SAL_CALL SwVbaApplication::PointsToInches( float Points ) +{ + return o3tl::convert(Points, o3tl::Length::pt, o3tl::Length::in); +} + +float SAL_CALL SwVbaApplication::MillimetersToPoints( float Millimeters ) +{ + return o3tl::convert(Millimeters, o3tl::Length::mm, o3tl::Length::pt); +} + +float SAL_CALL SwVbaApplication::PointsToMillimeters( float Points ) +{ + return o3tl::convert(Points, o3tl::Length::pt, o3tl::Length::mm); +} + +float SAL_CALL SwVbaApplication::PicasToPoints( float Picas ) +{ + return o3tl::convert(Picas, o3tl::Length::pc, o3tl::Length::pt); +} + +float SAL_CALL SwVbaApplication::PointsToPicas( float Points ) +{ + return o3tl::convert(Points, o3tl::Length::pt, o3tl::Length::pc); +} + +void SAL_CALL SwVbaApplication::ShowMe() +{ + // Method no longer supported in word - deprecated +} + +void SAL_CALL SwVbaApplication::Resize( sal_Int32 Width, sal_Int32 Height ) +{ + // Have to do it like this as the Width and Height are hidden away in the ooo::vba::XWindowBase + // which ooo::vba::word::XApplication does not inherit from. SwVbaWindow, however, does inherit + // from XWindowBase. Ugh. + auto pWindow = getActiveSwVbaWindow(); + pWindow->setWidth( Width ); + pWindow->setHeight( Height ); +} + +void SAL_CALL SwVbaApplication::Move( sal_Int32 Left, sal_Int32 Top ) +{ + // See comment in Resize(). + auto pWindow = getActiveSwVbaWindow(); + pWindow->setLeft( Left ); + pWindow->setTop( Top ); +} + +// XInterfaceWithIID + +OUString SAL_CALL +SwVbaApplication::getIID() +{ + return "{82154421-0FBF-11d4-8313-005004526AB4}"; +} + +// XConnectable + +OUString SAL_CALL +SwVbaApplication::GetIIDForClassItselfNotCoclass() +{ + return "{82154423-0FBF-11D4-8313-005004526AB4}"; +} + +TypeAndIID SAL_CALL +SwVbaApplication::GetConnectionPoint() +{ + TypeAndIID aResult = + { cppu::UnoType<word::XApplicationOutgoing>::get(), + "{82154422-0FBF-11D4-8313-005004526AB4}" + }; + + return aResult; +} + +uno::Reference<XConnectionPoint> SAL_CALL +SwVbaApplication::FindConnectionPoint() +{ + uno::Reference<XConnectionPoint> xCP(new SwVbaApplicationOutgoingConnectionPoint(this)); + return xCP; +} + +OUString +SwVbaApplication::getServiceImplName() +{ + return "SwVbaApplication"; +} + +uno::Sequence< OUString > +SwVbaApplication::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Application" + }; + return aServiceNames; +} + +uno::Reference< frame::XModel > +SwVbaApplication::getCurrentDocument() +{ + return getCurrentWordDoc( mxContext ); +} + +// XSinkCaller + +void SAL_CALL +SwVbaApplication::CallSinks( const OUString& Method, uno::Sequence< uno::Any >& Arguments ) +{ + for (auto& i : mvSinks) + { + if (i.is()) + i->Call(Method, Arguments); + } +} + +// SwVbaApplicationOutgoingConnectionPoint + +SwVbaApplicationOutgoingConnectionPoint::SwVbaApplicationOutgoingConnectionPoint( SwVbaApplication* pApp ) : + mpApp(pApp) +{ +} + +// XConnectionPoint +sal_uInt32 SAL_CALL +SwVbaApplicationOutgoingConnectionPoint::Advise( const uno::Reference< XSink >& Sink ) +{ + return mpApp->AddSink(Sink); +} + +void SAL_CALL +SwVbaApplicationOutgoingConnectionPoint::Unadvise( sal_uInt32 Cookie ) +{ + mpApp->RemoveSink( Cookie ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaapplication.hxx b/sw/source/ui/vba/vbaapplication.hxx new file mode 100644 index 0000000000..90b4322835 --- /dev/null +++ b/sw/source/ui/vba/vbaapplication.hxx @@ -0,0 +1,129 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAAPPLICATION_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAAPPLICATION_HXX + +#include <vector> + +#include <ooo/vba/XSink.hpp> +#include <ooo/vba/XSinkCaller.hpp> +#include <ooo/vba/word/XApplication.hpp> +#include <ooo/vba/word/XDocument.hpp> +#include <ooo/vba/word/XWindow.hpp> +#include <ooo/vba/word/XSystem.hpp> +#include <ooo/vba/word/XOptions.hpp> +#include <ooo/vba/word/XSelection.hpp> +#include <vbahelper/vbaapplicationbase.hxx> +#include <cppuhelper/implbase.hxx> +#include <rtl/ref.hxx> + +#include "vbawindow.hxx" + +typedef cppu::ImplInheritanceHelper< VbaApplicationBase, ooo::vba::word::XApplication, ooo::vba::XSinkCaller > SwVbaApplication_BASE; + +// This class is currently not a singleton. One instance is created per document with (potential?) +// StarBasic code in it, I think, and a shared one for all Automation clients connected to the +// ooo::vba::word::Application (Writer.Application) service. (Of course it probably is not common to +// have several Automation clients at once.) + +// Should it be a true singleton? Hard to say. Anyway, it is actually the SwVbaGlobals class that +// should be a singleton in that case, I think. + +class SwVbaApplication : public SwVbaApplication_BASE +{ + std::vector<css::uno::Reference< ooo::vba::XSink >> mvSinks; + +public: + explicit SwVbaApplication( css::uno::Reference< css::uno::XComponentContext >& xContext ); + virtual ~SwVbaApplication() override; + + sal_uInt32 AddSink( const css::uno::Reference< ooo::vba::XSink >& xSink ); + void RemoveSink( sal_uInt32 nNumber ); + + rtl::Reference<SwVbaWindow> getActiveSwVbaWindow(); + css::uno::Reference< css::uno::XComponentContext > const & getContext() const; + + // XApplication + virtual OUString SAL_CALL getName() override; + virtual css::uno::Reference< ooo::vba::word::XSystem > SAL_CALL getSystem() override; + virtual css::uno::Reference< ov::word::XDocument > SAL_CALL getActiveDocument() override; + virtual css::uno::Reference< ov::word::XWindow > SAL_CALL getActiveWindow() override; + virtual css::uno::Reference< ooo::vba::word::XOptions > SAL_CALL getOptions() override; + virtual css::uno::Reference< ooo::vba::word::XSelection > SAL_CALL getSelection() override; + virtual css::uno::Reference< ooo::vba::word::XWordBasic > SAL_CALL getWordBasic() override; + virtual css::uno::Any SAL_CALL CommandBars( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL Documents( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL Addins( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL Dialogs( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL ListGalleries( const css::uno::Any& aIndex ) override; + virtual sal_Bool SAL_CALL getDisplayAutoCompleteTips() override; + virtual void SAL_CALL setDisplayAutoCompleteTips( sal_Bool _displayAutoCompleteTips ) override; + virtual sal_Int32 SAL_CALL getEnableCancelKey() override; + virtual void SAL_CALL setEnableCancelKey( sal_Int32 _enableCancelKey ) override; + virtual sal_Int32 SAL_CALL getWindowState() override; + virtual void SAL_CALL setWindowState( sal_Int32 _windowstate ) override; + virtual sal_Int32 SAL_CALL getWidth() override; + virtual void SAL_CALL setWidth( sal_Int32 _width ) override; + virtual sal_Int32 SAL_CALL getHeight() override; + virtual void SAL_CALL setHeight( sal_Int32 _height ) override; + virtual sal_Int32 SAL_CALL getLeft() override; + virtual void SAL_CALL setLeft( sal_Int32 _left ) override; + virtual sal_Int32 SAL_CALL getTop() override; + virtual void SAL_CALL setTop( sal_Int32 _top ) override; + virtual OUString SAL_CALL getStatusBar() override; + virtual void SAL_CALL setStatusBar( const OUString& _statusbar ) override; + virtual css::uno::Any SAL_CALL getCustomizationContext() override; + virtual void SAL_CALL setCustomizationContext( const css::uno::Any& _customizationcontext ) override; + virtual float SAL_CALL CentimetersToPoints( float Centimeters ) override; + virtual float SAL_CALL PointsToCentimeters( float Points ) override; + virtual float SAL_CALL PixelsToPoints( float Pixels, ::sal_Bool fVertical ) override; + virtual float SAL_CALL PointsToPixels( float Pixels, ::sal_Bool fVertical ) override; + virtual float SAL_CALL InchesToPoints( float Inches ) override; + virtual float SAL_CALL PointsToInches( float Points ) override; + virtual float SAL_CALL MillimetersToPoints( float Millimeters ) override; + virtual float SAL_CALL PointsToMillimeters( float Points ) override; + virtual float SAL_CALL PicasToPoints( float Picas ) override; + virtual float SAL_CALL PointsToPicas( float Points ) override; + + + + virtual void SAL_CALL ShowMe() override; + virtual void SAL_CALL Resize( sal_Int32 Width, sal_Int32 Height ) override; + virtual void SAL_CALL Move( sal_Int32 Left, sal_Int32 Top ) override; + + // XInterfaceWithIID + virtual OUString SAL_CALL getIID() override; + + // XConnectable + virtual OUString SAL_CALL GetIIDForClassItselfNotCoclass() override; + virtual ov::TypeAndIID SAL_CALL GetConnectionPoint() override; + virtual css::uno::Reference<ov::XConnectionPoint> SAL_CALL FindConnectionPoint() override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + + // XSinkCaller + virtual void SAL_CALL CallSinks( const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments ) override; + + virtual css::uno::Reference< css::frame::XModel > getCurrentDocument() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAAPPLICATION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaautotextentry.cxx b/sw/source/ui/vba/vbaautotextentry.cxx new file mode 100644 index 0000000000..dd1f17f16f --- /dev/null +++ b/sw/source/ui/vba/vbaautotextentry.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 "vbaautotextentry.hxx" +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include <com/sun/star/text/XParagraphCursor.hpp> +#include "wordvbahelper.hxx" +#include "vbarange.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaAutoTextEntry::SwVbaAutoTextEntry( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XAutoTextEntry > xEntry ) : + SwVbaAutoTextEntry_BASE( rParent, rContext ), mxEntry(std::move( xEntry )) +{ +} + +SwVbaAutoTextEntry::~SwVbaAutoTextEntry() +{ +} + +uno::Reference< word::XRange > SAL_CALL SwVbaAutoTextEntry::Insert( const uno::Reference< word::XRange >& _where, const uno::Any& _richtext ) +{ + SwVbaRange* pWhere = dynamic_cast<SwVbaRange*>( _where.get() ); + if( pWhere ) + { + uno::Reference< text::XTextRange > xTextRange = pWhere->getXTextRange(); + xTextRange->setString( "x" ); // set marker + uno::Reference< text::XTextRange > xEndMarker = xTextRange->getEnd(); + xEndMarker->setString( "x" ); // set marker + uno::Reference< text::XText > xText = pWhere->getXText(); + mxEntry->applyTo( xEndMarker->getStart() ); + uno::Reference< text::XTextCursor > xTC = xText->createTextCursorByRange( xTextRange->getStart() ); + xTC->goRight( 1, true ); + xTC->setString( "" ); // remove marker + // remove the blank paragraph if it is a rich text + bool bRich = false; + _richtext >>= bRich; + if( bRich ) + { + // check if it is a blank paragraph + uno::Reference< text::XParagraphCursor > xParaCursor( xTC, uno::UNO_QUERY_THROW ); + if( xParaCursor->isStartOfParagraph() && xParaCursor->isEndOfParagraph() ) + { + //remove the blank paragraph + uno::Reference< frame::XModel > xModel( getCurrentWordDoc( mxContext ), uno::UNO_SET_THROW ); + uno::Reference< text::XTextViewCursor > xTVCursor = word::getXTextViewCursor( xModel ); + uno::Reference< text::XTextRange > xCurrentRange( xTC->getEnd(), uno::UNO_SET_THROW ); + xTVCursor->gotoRange( xCurrentRange, false ); + dispatchRequests( xModel,".uno:Delete" ); + xTVCursor->gotoRange( xEndMarker->getEnd(), false ); + } + } + xEndMarker->setString( "" ); // remove marker + xTC = xText->createTextCursorByRange( xEndMarker->getEnd() ); + pWhere->setXTextCursor( xTC ); + } + return uno::Reference< word::XRange >( pWhere ); +} + +OUString +SwVbaAutoTextEntry::getServiceImplName() +{ + return "SwVbaAutoTextEntry"; +} + +uno::Sequence< OUString > +SwVbaAutoTextEntry::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.AutoTextEntry" + }; + return aServiceNames; +} + +SwVbaAutoTextEntries::SwVbaAutoTextEntries( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess ) : SwVbaAutoTextEntries_BASE( xParent, xContext, xIndexAccess ) +{ +} + +// XEnumerationAccess +uno::Type +SwVbaAutoTextEntries::getElementType() +{ + return cppu::UnoType<word::XAutoTextEntry>::get(); +} +uno::Reference< container::XEnumeration > +SwVbaAutoTextEntries::createEnumeration() +{ + throw uno::RuntimeException("Not implemented" ); +} + +uno::Any +SwVbaAutoTextEntries::createCollectionObject( const css::uno::Any& aSource ) +{ + uno::Reference< text::XAutoTextEntry > xEntry( aSource, uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< word::XAutoTextEntry >( new SwVbaAutoTextEntry( this, mxContext, xEntry ) ) ); +} + +OUString +SwVbaAutoTextEntries::getServiceImplName() +{ + return "SwVbaAutoTextEntries"; +} + +css::uno::Sequence<OUString> +SwVbaAutoTextEntries::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.AutoTextEntries" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaautotextentry.hxx b/sw/source/ui/vba/vbaautotextentry.hxx new file mode 100644 index 0000000000..9a8ab4ad1d --- /dev/null +++ b/sw/source/ui/vba/vbaautotextentry.hxx @@ -0,0 +1,69 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAAUTOTEXTENTRY_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAAUTOTEXTENTRY_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XAutoTextEntries.hpp> +#include <ooo/vba/word/XAutoTextEntry.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <ooo/vba/word/XRange.hpp> +#include <com/sun/star/text/XAutoTextEntry.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XAutoTextEntry > SwVbaAutoTextEntry_BASE; + +class SwVbaAutoTextEntry : public SwVbaAutoTextEntry_BASE +{ +private: + css::uno::Reference< css::text::XAutoTextEntry > mxEntry; + +public: + /// @throws css::uno::RuntimeException + SwVbaAutoTextEntry( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XAutoTextEntry > xEntry ); + virtual ~SwVbaAutoTextEntry() override; + + // XAutoTextEntry + virtual css::uno::Reference< ooo::vba::word::XRange > SAL_CALL Insert( const css::uno::Reference< ooo::vba::word::XRange >& _where, const css::uno::Any& _richtext ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +typedef CollTestImplHelper< ooo::vba::word::XAutoTextEntries > SwVbaAutoTextEntries_BASE; + +class SwVbaAutoTextEntries : public SwVbaAutoTextEntries_BASE +{ +public: + /// @throws css::uno::RuntimeException + SwVbaAutoTextEntries( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess ); + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaAutoTextEntries_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAAUTOTEXTENTRY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbabookmark.cxx b/sw/source/ui/vba/vbabookmark.cxx new file mode 100644 index 0000000000..aecc0760bc --- /dev/null +++ b/sw/source/ui/vba/vbabookmark.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 "vbabookmark.hxx" +#include <com/sun/star/text/XBookmarksSupplier.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XTextContent.hpp> +#include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <utility> +#include "vbarange.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaBookmark::SwVbaBookmark( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, + css::uno::Reference< frame::XModel > xModel, OUString aBookmarkName ) : + SwVbaBookmark_BASE( rParent, rContext ), mxModel(std::move( xModel )), maBookmarkName(std::move( aBookmarkName )), mbValid( true ) +{ + uno::Reference< text::XBookmarksSupplier > xBookmarksSupplier( mxModel, uno::UNO_QUERY_THROW ); + mxBookmark.set( xBookmarksSupplier->getBookmarks()->getByName( maBookmarkName ), uno::UNO_QUERY_THROW ); +} + +SwVbaBookmark::~SwVbaBookmark() +{ +} + +void SwVbaBookmark::checkVality() +{ + if( !mbValid ) + throw uno::RuntimeException("The bookmark is not valid" ); +} + +void SAL_CALL SwVbaBookmark::Delete() +{ + checkVality(); + uno::Reference< text::XTextDocument > xTextDocument( mxModel, uno::UNO_QUERY_THROW ); + xTextDocument->getText()->removeTextContent( mxBookmark ); + mbValid = false; +} + +void SAL_CALL SwVbaBookmark::Select() +{ + checkVality(); + uno::Reference< view::XSelectionSupplier > xSelectSupp( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); + xSelectSupp->select( uno::Any( mxBookmark ) ); +} + +OUString SAL_CALL SwVbaBookmark::getName() +{ + return maBookmarkName; +} + +void SAL_CALL SwVbaBookmark::setName( const OUString& _name ) +{ + uno::Reference< container::XNamed > xNamed( mxBookmark, uno::UNO_QUERY_THROW ); + xNamed->setName( _name ); +} + +uno::Any SAL_CALL SwVbaBookmark::Range() +{ + uno::Reference< text::XTextContent > xTextContent( mxBookmark, uno::UNO_SET_THROW ); + uno::Reference< text::XTextDocument > xTextDocument( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextRange > xTextRange( xTextContent->getAnchor(), uno::UNO_SET_THROW ); + return uno::Any( uno::Reference< word::XRange>( new SwVbaRange( this, mxContext, xTextDocument, xTextRange->getStart(), xTextRange->getEnd(), xTextRange->getText() ) ) ); +} + +OUString +SwVbaBookmark::getServiceImplName() +{ + return "SwVbaBookmark"; +} + +uno::Sequence< OUString > +SwVbaBookmark::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Bookmark" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbabookmark.hxx b/sw/source/ui/vba/vbabookmark.hxx new file mode 100644 index 0000000000..24524df618 --- /dev/null +++ b/sw/source/ui/vba/vbabookmark.hxx @@ -0,0 +1,60 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBABOOKMARK_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBABOOKMARK_HXX + +#include <ooo/vba/word/XBookmark.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextContent.hpp> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XBookmark> SwVbaBookmark_BASE; + +class SwVbaBookmark : public SwVbaBookmark_BASE +{ +private: + css::uno::Reference<css::frame::XModel> mxModel; + css::uno::Reference<css::text::XTextContent> mxBookmark; + OUString maBookmarkName; + bool mbValid; + +private: + /// @throws css::uno::RuntimeException + void checkVality(); + +public: + /// @throws css::uno::RuntimeException + SwVbaBookmark(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, + css::uno::Reference<css::frame::XModel> xModel, OUString aName); + virtual ~SwVbaBookmark() override; + + // Methods + virtual OUString SAL_CALL getName() override; + virtual void SAL_CALL setName(const OUString&) override; + virtual void SAL_CALL Delete() override; + virtual void SAL_CALL Select() override; + virtual css::uno::Any SAL_CALL Range() override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBABOOKMARK_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbabookmarks.cxx b/sw/source/ui/vba/vbabookmarks.cxx new file mode 100644 index 0000000000..6755413796 --- /dev/null +++ b/sw/source/ui/vba/vbabookmarks.cxx @@ -0,0 +1,229 @@ +/* -*- 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 "vbabookmarks.hxx" +#include "vbabookmark.hxx" +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XTextViewCursor.hpp> +#include <ooo/vba/word/WdBookmarkSortBy.hpp> +#include "vbarange.hxx" +#include "wordvbahelper.hxx" +#include <cppuhelper/implbase.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class BookmarksEnumeration : public EnumerationHelperImpl +{ + uno::Reference< frame::XModel > mxModel; +public: + /// @throws uno::RuntimeException + BookmarksEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, uno::Reference< frame::XModel > xModel ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mxModel(std::move( xModel )) {} + + virtual uno::Any SAL_CALL nextElement( ) override + { + uno::Reference< container::XNamed > xNamed( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); + OUString aName = xNamed->getName(); + return uno::Any( uno::Reference< word::XBookmark > ( new SwVbaBookmark( m_xParent, m_xContext, mxModel, aName ) ) ); + } + +}; + +// Bookmarks use case-insensitive name lookup in MS Word. +class BookmarkCollectionHelper : public ::cppu::WeakImplHelper< container::XNameAccess, + container::XIndexAccess > +{ +private: + uno::Reference< container::XNameAccess > mxNameAccess; + uno::Reference< container::XIndexAccess > mxIndexAccess; + uno::Any m_cachePos; +public: + /// @throws uno::RuntimeException + explicit BookmarkCollectionHelper( uno::Reference< container::XIndexAccess > xIndexAccess ) : mxIndexAccess(std::move( xIndexAccess )) + { + mxNameAccess.set( mxIndexAccess, uno::UNO_QUERY_THROW ); + } + // XElementAccess + virtual uno::Type SAL_CALL getElementType( ) override { return mxIndexAccess->getElementType(); } + virtual sal_Bool SAL_CALL hasElements( ) override { return mxIndexAccess->hasElements(); } + // XNameAccess + virtual uno::Any SAL_CALL getByName( const OUString& aName ) override + { + if ( !hasByName(aName) ) + throw container::NoSuchElementException(); + return m_cachePos; + } + virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override + { + return mxNameAccess->getElementNames(); + } + virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override + { + if( mxNameAccess->hasByName( aName ) ) + { + m_cachePos = mxNameAccess->getByName( aName ); + return true; + } + else + { + for( sal_Int32 nIndex = 0; nIndex < mxIndexAccess->getCount(); nIndex++ ) + { + uno::Reference< container::XNamed > xNamed( mxIndexAccess->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + OUString aBookmarkName = xNamed->getName(); + if( aName.equalsIgnoreAsciiCase( aBookmarkName ) ) + { + m_cachePos <<= xNamed; + return true; + } + } + } + return false; + } + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override + { + return mxIndexAccess->getCount(); + } + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override + { + return mxIndexAccess->getByIndex( Index ); + } +}; + +} + +SwVbaBookmarks::SwVbaBookmarks( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xBookmarks, uno::Reference< frame::XModel > xModel ): SwVbaBookmarks_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new BookmarkCollectionHelper( xBookmarks ) ) ), mxModel(std::move( xModel )) +{ + mxBookmarksSupplier.set( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextDocument > xDocument( mxModel, uno::UNO_QUERY_THROW ); +} +// XEnumerationAccess +uno::Type +SwVbaBookmarks::getElementType() +{ + return cppu::UnoType<word::XBookmark>::get(); +} +uno::Reference< container::XEnumeration > +SwVbaBookmarks::createEnumeration() +{ + uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); + return new BookmarksEnumeration( getParent(), mxContext,xEnumAccess->createEnumeration(), mxModel ); +} + +uno::Any +SwVbaBookmarks::createCollectionObject( const css::uno::Any& aSource ) +{ + uno::Reference< container::XNamed > xNamed( aSource, uno::UNO_QUERY_THROW ); + OUString aName = xNamed->getName(); + return uno::Any( uno::Reference< word::XBookmark > ( new SwVbaBookmark( getParent(), mxContext, mxModel, aName ) ) ); +} + +void SwVbaBookmarks::removeBookmarkByName( const OUString& rName ) +{ + uno::Reference< text::XTextContent > xBookmark( m_xNameAccess->getByName( rName ), uno::UNO_QUERY_THROW ); + word::getXTextViewCursor( mxModel )->getText()->removeTextContent( xBookmark ); +} + +void SwVbaBookmarks::addBookmarkByName( const uno::Reference< frame::XModel >& xModel, const OUString& rName, const uno::Reference< text::XTextRange >& rTextRange ) +{ + uno::Reference< lang::XMultiServiceFactory > xDocMSF( xModel, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextContent > xBookmark( xDocMSF->createInstance("com.sun.star.text.Bookmark"), uno::UNO_QUERY_THROW ); + uno::Reference< container::XNamed > xNamed( xBookmark, uno::UNO_QUERY_THROW ); + xNamed->setName( rName ); + rTextRange->getText()->insertTextContent( rTextRange, xBookmark, false ); +} + +uno::Any SAL_CALL +SwVbaBookmarks::Add( const OUString& rName, const uno::Any& rRange ) +{ + uno::Reference< text::XTextRange > xTextRange; + uno::Reference< word::XRange > xRange; + if( rRange >>= xRange ) + { + SwVbaRange* pRange = dynamic_cast< SwVbaRange* >( xRange.get() ); + if( pRange ) + xTextRange = pRange->getXTextRange(); + } + else + { + // FIXME: insert the bookmark into current view cursor + xTextRange.set( word::getXTextViewCursor( mxModel ), uno::UNO_QUERY_THROW ); + } + + // remove the exist bookmark + if( m_xNameAccess->hasByName( rName ) ) + removeBookmarkByName( rName ); + + addBookmarkByName( mxModel, rName, xTextRange ); + + return uno::Any( uno::Reference< word::XBookmark >( new SwVbaBookmark( getParent(), mxContext, mxModel, rName ) ) ); +} + +sal_Int32 SAL_CALL +SwVbaBookmarks::getDefaultSorting() +{ + return word::WdBookmarkSortBy::wdSortByName; +} + +void SAL_CALL +SwVbaBookmarks::setDefaultSorting( sal_Int32/* _type*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL +SwVbaBookmarks::getShowHidden() +{ + return true; +} + +void SAL_CALL +SwVbaBookmarks::setShowHidden( sal_Bool /*_hidden*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL +SwVbaBookmarks::Exists( const OUString& rName ) +{ + bool bExist = m_xNameAccess->hasByName( rName ); + return bExist; +} + +OUString +SwVbaBookmarks::getServiceImplName() +{ + return "SwVbaBookmarks"; +} + +css::uno::Sequence<OUString> +SwVbaBookmarks::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.Bookmarks" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbabookmarks.hxx b/sw/source/ui/vba/vbabookmarks.hxx new file mode 100644 index 0000000000..1b264fb6b7 --- /dev/null +++ b/sw/source/ui/vba/vbabookmarks.hxx @@ -0,0 +1,66 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBABOOKMARKS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBABOOKMARKS_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XBookmarks.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/text/XBookmarksSupplier.hpp> +#include <com/sun/star/text/XTextRange.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XBookmarks > SwVbaBookmarks_BASE; + +class SwVbaBookmarks : public SwVbaBookmarks_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::text::XBookmarksSupplier > mxBookmarksSupplier; + +private: + /// @throws css::uno::RuntimeException + void removeBookmarkByName( const OUString& rName ); + +public: + SwVbaBookmarks( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xBookmarks, css::uno::Reference< css::frame::XModel > xModel ); + + /// @throws css::uno::RuntimeException + static void addBookmarkByName( const css::uno::Reference< css::frame::XModel >& xModel, const OUString& rName, const css::uno::Reference< css::text::XTextRange >& rTextRange ); + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaBookmarks_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + + // XBookmarks + virtual sal_Int32 SAL_CALL getDefaultSorting() override; + virtual void SAL_CALL setDefaultSorting( sal_Int32 _type ) override; + virtual sal_Bool SAL_CALL getShowHidden() override; + virtual void SAL_CALL setShowHidden( sal_Bool _hidden ) override; + + virtual css::uno::Any SAL_CALL Add( const OUString& rName, const css::uno::Any& rRange ) override; + virtual sal_Bool SAL_CALL Exists( const OUString& rName ) override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBABOOKMARKS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaborders.cxx b/sw/source/ui/vba/vbaborders.cxx new file mode 100644 index 0000000000..9e780fe210 --- /dev/null +++ b/sw/source/ui/vba/vbaborders.cxx @@ -0,0 +1,366 @@ +/* -*- 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 "vbaborders.hxx" +#include <ooo/vba/word/XBorder.hpp> +#include <ooo/vba/word/WdBorderType.hpp> +#include <ooo/vba/word/WdLineStyle.hpp> +#include <sal/macros.h> +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/table/TableBorder.hpp> +#include <utility> +#include "vbapalette.hxx" + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +typedef ::cppu::WeakImplHelper<container::XIndexAccess > RangeBorders_Base; +typedef InheritedHelperInterfaceWeakImpl<word::XBorder > SwVbaBorder_Base; + +// #TODO sort these indexes to match the order in which Word iterates over the +// borders, the enumeration will match the order in this list +const sal_Int16 supportedIndexTable[] = { word::WdBorderType::wdBorderBottom, word::WdBorderType::wdBorderDiagonalDown, word::WdBorderType::wdBorderDiagonalUp, word::WdBorderType::wdBorderHorizontal, word::WdBorderType::wdBorderLeft, word::WdBorderType::wdBorderRight, word::WdBorderType::wdBorderTop, word::WdBorderType::wdBorderVertical }; + +// Equiv widths in 1/100 mm +const sal_Int32 OOLineHairline = 2; + +namespace { + +class SwVbaBorder : public SwVbaBorder_Base +{ +private: + uno::Reference< beans::XPropertySet > m_xProps; + sal_Int32 m_LineType; + void setBorderLine( table::BorderLine const & rBorderLine ) + { + table::TableBorder aTableBorder; + m_xProps->getPropertyValue( "TableBorder" ) >>= aTableBorder; + + switch ( m_LineType ) + { + case word::WdBorderType::wdBorderLeft: + aTableBorder.IsLeftLineValid = true; + aTableBorder.LeftLine= rBorderLine; + break; + case word::WdBorderType::wdBorderTop: + aTableBorder.IsTopLineValid = true; + aTableBorder.TopLine = rBorderLine; + break; + + case word::WdBorderType::wdBorderBottom: + aTableBorder.IsBottomLineValid = true; + aTableBorder.BottomLine = rBorderLine; + break; + case word::WdBorderType::wdBorderRight: + aTableBorder.IsRightLineValid = true; + aTableBorder.RightLine = rBorderLine; + break; + case word::WdBorderType::wdBorderVertical: + aTableBorder.IsVerticalLineValid = true; + aTableBorder.VerticalLine = rBorderLine; + break; + case word::WdBorderType::wdBorderHorizontal: + aTableBorder.IsHorizontalLineValid = true; + aTableBorder.HorizontalLine = rBorderLine; + break; + case word::WdBorderType::wdBorderDiagonalDown: + case word::WdBorderType::wdBorderDiagonalUp: + // #TODO have to ignore at the moment, would be + // nice to investigate what we can do here + break; + default: + return; + } + m_xProps->setPropertyValue( "TableBorder", uno::Any(aTableBorder) ); + } + + bool getBorderLine( table::BorderLine& rBorderLine ) + { + table::TableBorder aTableBorder; + m_xProps->getPropertyValue( "TableBorder" ) >>= aTableBorder; + switch ( m_LineType ) + { + case word::WdBorderType::wdBorderLeft: + if ( aTableBorder.IsLeftLineValid ) + rBorderLine = aTableBorder.LeftLine; + break; + case word::WdBorderType::wdBorderTop: + if ( aTableBorder.IsTopLineValid ) + rBorderLine = aTableBorder.TopLine; + break; + case word::WdBorderType::wdBorderBottom: + if ( aTableBorder.IsBottomLineValid ) + rBorderLine = aTableBorder.BottomLine; + break; + case word::WdBorderType::wdBorderRight: + if ( aTableBorder.IsRightLineValid ) + rBorderLine = aTableBorder.RightLine; + break; + case word::WdBorderType::wdBorderVertical: + if ( aTableBorder.IsVerticalLineValid ) + rBorderLine = aTableBorder.VerticalLine; + break; + case word::WdBorderType::wdBorderHorizontal: + if ( aTableBorder.IsHorizontalLineValid ) + rBorderLine = aTableBorder.HorizontalLine; + break; + + case word::WdBorderType::wdBorderDiagonalDown: + case word::WdBorderType::wdBorderDiagonalUp: + // #TODO have to ignore at the moment, would be + // nice to investigate what we can do here + break; + default: + return false; + } + return true; + } + +protected: + virtual OUString getServiceImplName() override + { + return "SwVbaBorder"; + } + + virtual css::uno::Sequence<OUString> getServiceNames() override + { + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Border" + }; + return aServiceNames; + } +public: + SwVbaBorder( const uno::Reference< beans::XPropertySet > & xProps, const uno::Reference< uno::XComponentContext >& xContext, sal_Int32 lineType ) : SwVbaBorder_Base( uno::Reference< XHelperInterface >( xProps, uno::UNO_QUERY ), xContext ), m_xProps( xProps ), m_LineType( lineType ) {} + + uno::Any SAL_CALL getLineStyle() override + { + sal_Int32 nLineStyle = word::WdLineStyle::wdLineStyleNone; + table::BorderLine aBorderLine; + if ( getBorderLine( aBorderLine ) ) + { + if( aBorderLine.InnerLineWidth !=0 && aBorderLine.OuterLineWidth !=0 ) + { + nLineStyle = word::WdLineStyle::wdLineStyleDouble; + } + else if( aBorderLine.InnerLineWidth !=0 || aBorderLine.OuterLineWidth !=0 ) + { + nLineStyle = word::WdLineStyle::wdLineStyleSingle; + } + else + { + nLineStyle = word::WdLineStyle::wdLineStyleNone; + } + } + return uno::Any( nLineStyle ); + } + void SAL_CALL setLineStyle( const uno::Any& _linestyle ) override + { + // Urk no choice but to silently ignore we don't support this attribute + // #TODO would be nice to support the word line styles + sal_Int32 nLineStyle = 0; + _linestyle >>= nLineStyle; + table::BorderLine aBorderLine; + if ( !getBorderLine( aBorderLine ) ) + throw uno::RuntimeException("Method failed" ); + + switch ( nLineStyle ) + { + case word::WdLineStyle::wdLineStyleNone: + { + aBorderLine.InnerLineWidth = 0; + aBorderLine.OuterLineWidth = 0; + break; + } + case word::WdLineStyle::wdLineStyleDashDot: + case word::WdLineStyle::wdLineStyleDashDotDot: + case word::WdLineStyle::wdLineStyleDashDotStroked: + case word::WdLineStyle::wdLineStyleDashLargeGap: + case word::WdLineStyle::wdLineStyleDashSmallGap: + case word::WdLineStyle::wdLineStyleDot: + case word::WdLineStyle::wdLineStyleDouble: + case word::WdLineStyle::wdLineStyleDoubleWavy: + case word::WdLineStyle::wdLineStyleEmboss3D: + case word::WdLineStyle::wdLineStyleEngrave3D: + case word::WdLineStyle::wdLineStyleInset: + case word::WdLineStyle::wdLineStyleOutset: + case word::WdLineStyle::wdLineStyleSingle: + case word::WdLineStyle::wdLineStyleSingleWavy: + case word::WdLineStyle::wdLineStyleThickThinLargeGap: + case word::WdLineStyle::wdLineStyleThickThinMedGap: + case word::WdLineStyle::wdLineStyleThickThinSmallGap: + case word::WdLineStyle::wdLineStyleThinThickLargeGap: + case word::WdLineStyle::wdLineStyleThinThickMedGap: + case word::WdLineStyle::wdLineStyleThinThickSmallGap: + case word::WdLineStyle::wdLineStyleThinThickThinLargeGap: + case word::WdLineStyle::wdLineStyleThinThickThinMedGap: + case word::WdLineStyle::wdLineStyleThinThickThinSmallGap: + case word::WdLineStyle::wdLineStyleTriple: + { + aBorderLine.InnerLineWidth = 0; + aBorderLine.OuterLineWidth = OOLineHairline; + break; + } + default: + throw uno::RuntimeException("Bad param" ); + } + setBorderLine( aBorderLine ); + + } +}; + +class RangeBorders : public RangeBorders_Base +{ +private: + uno::Reference< table::XCellRange > m_xRange; + uno::Reference< uno::XComponentContext > m_xContext; + VbaPalette m_Palette; + sal_Int32 getTableIndex( sal_Int32 nConst ) + { + // okay return position of the index in the table + sal_Int32 nIndexes = getCount(); + sal_Int32 realIndex = 0; + const sal_Int16* pTableEntry = supportedIndexTable; + for ( ; realIndex < nIndexes; ++realIndex, ++pTableEntry ) + { + if ( *pTableEntry == nConst ) + return realIndex; + } + return getCount(); // error condition + } +public: + RangeBorders( uno::Reference< table::XCellRange > xRange, uno::Reference< uno::XComponentContext > xContext, VbaPalette aPalette ) : m_xRange(std::move( xRange )), m_xContext(std::move( xContext )), m_Palette(std::move( aPalette )) + { + } + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override + { + return SAL_N_ELEMENTS( supportedIndexTable ); + } + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override + { + + sal_Int32 nIndex = getTableIndex( Index ); + if ( nIndex >= 0 && nIndex < getCount() ) + { + uno::Reference< beans::XPropertySet > xProps( m_xRange, uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< word::XBorder >( new SwVbaBorder( xProps, m_xContext, supportedIndexTable[ nIndex ] )) ); + } + throw lang::IndexOutOfBoundsException(); + } + virtual uno::Type SAL_CALL getElementType( ) override + { + return cppu::UnoType<word::XBorder>::get(); + } + virtual sal_Bool SAL_CALL hasElements( ) override + { + return true; + } +}; + +} + +static uno::Reference< container::XIndexAccess > +rangeToBorderIndexAccess( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< uno::XComponentContext > & xContext, VbaPalette const & rPalette ) +{ + return new RangeBorders( xRange, xContext, rPalette ); +} + +namespace { + +class RangeBorderEnumWrapper : public EnumerationHelper_BASE +{ + uno::Reference<container::XIndexAccess > m_xIndexAccess; + sal_Int32 m_nIndex; +public: + explicit RangeBorderEnumWrapper( uno::Reference< container::XIndexAccess > xIndexAccess ) : m_xIndexAccess(std::move( xIndexAccess )), m_nIndex( 0 ) {} + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( m_nIndex < m_xIndexAccess->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( m_nIndex < m_xIndexAccess->getCount() ) + return m_xIndexAccess->getByIndex( m_nIndex++ ); + throw container::NoSuchElementException(); + } +}; + +} + +// for Table borders +SwVbaBorders::SwVbaBorders( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< table::XCellRange >& xRange, VbaPalette const & rPalette ): SwVbaBorders_BASE( xParent, xContext, rangeToBorderIndexAccess( xRange ,xContext, rPalette ) ) +{ + m_xProps.set( xRange, uno::UNO_QUERY_THROW ); +} + +uno::Reference< container::XEnumeration > +SwVbaBorders::createEnumeration() +{ + return new RangeBorderEnumWrapper( m_xIndexAccess ); +} + +uno::Any +SwVbaBorders::createCollectionObject( const css::uno::Any& aSource ) +{ + return aSource; // it's already a Border object +} + +uno::Type +SwVbaBorders::getElementType() +{ + return cppu::UnoType<word::XBorders>::get(); +} + +uno::Any +SwVbaBorders::getItemByIntIndex( const sal_Int32 nIndex ) +{ + return createCollectionObject( m_xIndexAccess->getByIndex( nIndex ) ); +} + +sal_Bool SAL_CALL SwVbaBorders::getShadow() +{ + // always return False for table border in MS Word + return false; +} + +void SAL_CALL SwVbaBorders::setShadow( sal_Bool /*_shadow*/ ) +{ + // not support in Table border in Word + // TODO: +} + +OUString +SwVbaBorders::getServiceImplName() +{ + return "SwVbaBorders"; +} + +uno::Sequence< OUString > +SwVbaBorders::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Borders" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaborders.hxx b/sw/source/ui/vba/vbaborders.hxx new file mode 100644 index 0000000000..a4ca819f67 --- /dev/null +++ b/sw/source/ui/vba/vbaborders.hxx @@ -0,0 +1,54 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBABORDERS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBABORDERS_HXX + +#include <ooo/vba/word/XBorders.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <vbahelper/vbacollectionimpl.hxx> + +typedef CollTestImplHelper< ov::word::XBorders > SwVbaBorders_BASE; +class VbaPalette; +class SwVbaBorders : public SwVbaBorders_BASE +{ + // XEnumerationAccess + virtual css::uno::Any getItemByIntIndex( const sal_Int32 nIndex ) override; + css::uno::Reference< css::beans::XPropertySet > m_xProps; +public: + SwVbaBorders( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::table::XCellRange >& xRange, VbaPalette const & rPalette ); + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaCollectionBaseImpl + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + + virtual sal_Bool SAL_CALL getShadow() override; + virtual void SAL_CALL setShadow( sal_Bool _shadow ) override; + + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBABORDERS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacell.cxx b/sw/source/ui/vba/vbacell.cxx new file mode 100644 index 0000000000..a24dd3dd1c --- /dev/null +++ b/sw/source/ui/vba/vbacell.cxx @@ -0,0 +1,102 @@ +/* -*- 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 <utility> + +#include "vbacell.hxx" +#include "vbatablehelper.hxx" +#include "vbarow.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaCell::SwVbaCell( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextTable > xTextTable, sal_Int32 nColumn, sal_Int32 nRow ) : + SwVbaCell_BASE( rParent, rContext ), mxTextTable(std::move( xTextTable )), mnColumn( nColumn ), mnRow( nRow ) +{ +} + +SwVbaCell::~SwVbaCell() +{ +} + +::sal_Int32 SAL_CALL SwVbaCell::getWidth() +{ + SwVbaTableHelper aTableHelper( mxTextTable ); + return aTableHelper.GetColWidth( mnColumn, mnRow ); +} + +void SAL_CALL SwVbaCell::setWidth( ::sal_Int32 _width ) +{ + SwVbaTableHelper aTableHelper( mxTextTable ); + aTableHelper.SetColWidth( _width, mnColumn, mnRow, true ); +} + +uno::Any SAL_CALL SwVbaCell::getHeight() +{ + uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, mnRow ) ); + return xRow->getHeight(); +} + +void SAL_CALL SwVbaCell::setHeight( const uno::Any& _height ) +{ + uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, mnRow ) ); + xRow->setHeight( _height ); +} + +::sal_Int32 SAL_CALL SwVbaCell::getHeightRule() +{ + uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, mnRow ) ); + return xRow->getHeightRule(); +} + +void SAL_CALL SwVbaCell::setHeightRule( ::sal_Int32 _heightrule ) +{ + uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, mnRow ) ); + xRow->setHeightRule( _heightrule ); +} + +void SAL_CALL SwVbaCell::SetWidth( float width, sal_Int32 /*rulestyle*/ ) +{ + // FIXME: handle the argument: rulestyle + setWidth( static_cast<sal_Int32>(width) ); +} + +void SAL_CALL SwVbaCell::SetHeight( float height, sal_Int32 heightrule ) +{ + // FIXME: handle the argument: heightrule + setHeightRule( heightrule ); + setHeight( uno::Any( height ) ); +} + +OUString +SwVbaCell::getServiceImplName() +{ + return "SwVbaCell"; +} + +uno::Sequence< OUString > +SwVbaCell::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Cell" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacell.hxx b/sw/source/ui/vba/vbacell.hxx new file mode 100644 index 0000000000..8ca9f0adad --- /dev/null +++ b/sw/source/ui/vba/vbacell.hxx @@ -0,0 +1,58 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBACELL_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBACELL_HXX + +#include <ooo/vba/word/XCell.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextTable.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XCell > SwVbaCell_BASE; + +class SwVbaCell : public SwVbaCell_BASE +{ +private: + css::uno::Reference< css::text::XTextTable > mxTextTable; + sal_Int32 mnColumn; + sal_Int32 mnRow; + +public: + /// @throws css::uno::RuntimeException + SwVbaCell( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextTable > xTextTable, sal_Int32 nColumn, sal_Int32 nRow ); + virtual ~SwVbaCell() override; + + // Attributes + virtual ::sal_Int32 SAL_CALL getWidth() override; + virtual void SAL_CALL setWidth( ::sal_Int32 _width ) override; + virtual css::uno::Any SAL_CALL getHeight() override; + virtual void SAL_CALL setHeight( const css::uno::Any& _height ) override; + virtual ::sal_Int32 SAL_CALL getHeightRule() override; + virtual void SAL_CALL setHeightRule( ::sal_Int32 _heightrule ) override; + + // Methods + virtual void SAL_CALL SetWidth( float width, sal_Int32 rulestyle ) override; + virtual void SAL_CALL SetHeight( float height, sal_Int32 heightrule ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBACELL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacells.cxx b/sw/source/ui/vba/vbacells.cxx new file mode 100644 index 0000000000..e30c2ed370 --- /dev/null +++ b/sw/source/ui/vba/vbacells.cxx @@ -0,0 +1,214 @@ +/* -*- 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 "vbacells.hxx" +#include "vbacell.hxx" +#include "vbarow.hxx" +#include <cppuhelper/implbase.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class CellsEnumWrapper : public EnumerationHelper_BASE +{ + uno::Reference< container::XIndexAccess > mxIndexAccess; + sal_Int32 mnIndex; + +public: + explicit CellsEnumWrapper( uno::Reference< container::XIndexAccess > xIndexAccess ) : mxIndexAccess(std::move( xIndexAccess )), mnIndex( 0 ) + { + } + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( mnIndex < mxIndexAccess->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if( mnIndex < mxIndexAccess->getCount() ) + { + return mxIndexAccess->getByIndex( mnIndex++ ); + } + throw container::NoSuchElementException(); + } +}; + +class CellCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess, + container::XEnumerationAccess > +{ +private: + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< css::text::XTextTable > mxTextTable; + sal_Int32 mnLeft; + sal_Int32 mnTop; + sal_Int32 mnRight; + sal_Int32 mnBottom; + +public: + /// @throws css::uno::RuntimeException + CellCollectionHelper( css::uno::Reference< ov::XHelperInterface > xParent, css::uno::Reference< css::uno::XComponentContext > xContext, css::uno::Reference< css::text::XTextTable > xTextTable, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ): mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxTextTable(std::move( xTextTable )), mnLeft( nLeft ), mnTop( nTop ), mnRight( nRight ), mnBottom( nBottom ) + { + } + + virtual sal_Int32 SAL_CALL getCount( ) override + { + return ( mnRight - mnLeft + 1 ) * ( mnBottom - mnTop + 1 ); + } + virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override + { + if ( Index < 0 || Index >= getCount() ) + throw css::lang::IndexOutOfBoundsException(); + + for( sal_Int32 row = mnTop; row <= mnBottom; row++ ) + { + for( sal_Int32 col = mnLeft; col <= mnRight; col++ ) + { + if( Index == ( ( row - mnTop ) * ( mnRight - mnLeft + 1 ) + ( col - mnLeft ) ) ) + return uno::Any( uno::Reference< word::XCell >( new SwVbaCell( mxParent, mxContext, mxTextTable, col, row ) ) ); + } + } + throw css::lang::IndexOutOfBoundsException(); + + } + virtual uno::Type SAL_CALL getElementType( ) override + { + return cppu::UnoType<word::XCell>::get(); + } + virtual sal_Bool SAL_CALL hasElements( ) override + { + return true; + } + // XEnumerationAccess + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override + { + return new CellsEnumWrapper( this ); + } +}; + +} + +SwVbaCells::SwVbaCells( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< text::XTextTable >& xTextTable, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) : SwVbaCells_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new CellCollectionHelper( xParent, xContext, xTextTable, nLeft, nTop, nRight, nBottom ) ) ), mxTextTable( xTextTable ), mnTop( nTop ), mnBottom( nBottom ) +{ +} + +::sal_Int32 SAL_CALL SwVbaCells::getWidth() +{ + uno::Reference< word::XCell > xCell( m_xIndexAccess->getByIndex( 0 ), uno::UNO_QUERY_THROW ); + return xCell->getWidth(); +} + +void SAL_CALL SwVbaCells::setWidth( ::sal_Int32 _width ) +{ + sal_Int32 nIndex = 0; + while( nIndex < m_xIndexAccess->getCount() ) + { + uno::Reference< word::XCell > xCell( m_xIndexAccess->getByIndex( nIndex++ ), uno::UNO_QUERY_THROW ); + xCell->setWidth( _width ); + } +} + +uno::Any SAL_CALL SwVbaCells::getHeight() +{ + uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, mnTop ) ); + return xRow->getHeight(); +} + +void SAL_CALL SwVbaCells::setHeight( const uno::Any& _height ) +{ + for( sal_Int32 row = mnTop; row <= mnBottom; row++ ) + { + uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, row ) ); + xRow->setHeight( _height ); + } +} + +::sal_Int32 SAL_CALL SwVbaCells::getHeightRule() +{ + uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, mnTop ) ); + return xRow->getHeightRule(); +} + +void SAL_CALL SwVbaCells::setHeightRule( ::sal_Int32 _heightrule ) +{ + for( sal_Int32 row = mnTop; row <= mnBottom; row++ ) + { + uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, row ) ); + xRow->setHeightRule( _heightrule ); + } +} + +void SAL_CALL SwVbaCells::SetWidth( float width, sal_Int32 rulestyle ) +{ + sal_Int32 nIndex = 0; + while( nIndex < m_xIndexAccess->getCount() ) + { + uno::Reference< word::XCell > xCell( m_xIndexAccess->getByIndex( nIndex++ ), uno::UNO_QUERY_THROW ); + xCell->SetWidth( width, rulestyle ); + } +} + +void SAL_CALL SwVbaCells::SetHeight( float height, sal_Int32 heightrule ) +{ + for( sal_Int32 row = mnTop; row <= mnBottom; row++ ) + { + uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, row ) ); + xRow->SetHeight( height, heightrule ); + } +} + +// XEnumerationAccess +uno::Type +SwVbaCells::getElementType() +{ + return cppu::UnoType<word::XCell>::get(); +} + +uno::Reference< container::XEnumeration > +SwVbaCells::createEnumeration() +{ + uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); + return xEnumAccess->createEnumeration(); +} + +uno::Any +SwVbaCells::createCollectionObject( const uno::Any& aSource ) +{ + return aSource; +} + +OUString +SwVbaCells::getServiceImplName() +{ + return "SwVbaCells"; +} + +uno::Sequence<OUString> +SwVbaCells::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.Cells" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacells.hxx b/sw/source/ui/vba/vbacells.hxx new file mode 100644 index 0000000000..e9de9f532f --- /dev/null +++ b/sw/source/ui/vba/vbacells.hxx @@ -0,0 +1,63 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBACELLS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBACELLS_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XCells.hpp> +#include <com/sun/star/text/XTextTable.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XCells > SwVbaCells_BASE; + +class SwVbaCells : public SwVbaCells_BASE +{ +private: + css::uno::Reference< css::text::XTextTable > mxTextTable; + sal_Int32 mnTop; + sal_Int32 mnBottom; + +public: + /// @throws css::uno::RuntimeException + SwVbaCells( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::text::XTextTable >& xTextTable, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ); + + // Attributes + virtual ::sal_Int32 SAL_CALL getWidth() override; + virtual void SAL_CALL setWidth( ::sal_Int32 _width ) override; + virtual css::uno::Any SAL_CALL getHeight() override; + virtual void SAL_CALL setHeight( const css::uno::Any& _height ) override; + virtual ::sal_Int32 SAL_CALL getHeightRule() override; + virtual void SAL_CALL setHeightRule( ::sal_Int32 _heightrule ) override; + + // Methods + virtual void SAL_CALL SetWidth( float width, sal_Int32 rulestyle ) override; + virtual void SAL_CALL SetHeight( float height, sal_Int32 heightrule ) override; + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaCells_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBACELLS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacolumn.cxx b/sw/source/ui/vba/vbacolumn.cxx new file mode 100644 index 0000000000..c4411bfab4 --- /dev/null +++ b/sw/source/ui/vba/vbacolumn.cxx @@ -0,0 +1,91 @@ +/* -*- 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 "vbacolumn.hxx" +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include "vbatablehelper.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaColumn::SwVbaColumn( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextTable > xTextTable, sal_Int32 nIndex ) : + SwVbaColumn_BASE( rParent, rContext ), mxTextTable(std::move( xTextTable )), mnIndex( nIndex ) +{ +} + +SwVbaColumn::~SwVbaColumn() +{ +} + +sal_Int32 SAL_CALL +SwVbaColumn::getWidth( ) +{ + SwVbaTableHelper aTableHelper( mxTextTable ); + return aTableHelper.GetColWidth( mnIndex ); +} + +void SAL_CALL +SwVbaColumn::setWidth( sal_Int32 _width ) +{ + + SwVbaTableHelper aTableHelper( mxTextTable ); + aTableHelper.SetColWidth( _width, mnIndex ); +} + +void SAL_CALL +SwVbaColumn::Select( ) +{ + SelectColumn( getCurrentWordDoc(mxContext), mxTextTable, mnIndex, mnIndex ); +} + +void SwVbaColumn::SelectColumn( const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextTable >& xTextTable, sal_Int32 nStartColumn, sal_Int32 nEndColumn ) +{ + OUString sStartCol = SwVbaTableHelper::getColumnStr( nStartColumn ); + OUString aRangeName = sStartCol + OUString::number( 1 ); + OUString sEndCol = SwVbaTableHelper::getColumnStr( nEndColumn ); + sal_Int32 nRowCount = xTextTable->getRows()->getCount(); + aRangeName += ":" + sEndCol + OUString::number(nRowCount); + + uno::Reference< table::XCellRange > xCellRange( xTextTable, uno::UNO_QUERY_THROW ); + uno::Reference< table::XCellRange > xSelRange = xCellRange->getCellRangeByName( aRangeName ); + + uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW ); + xSelection->select( uno::Any( xSelRange ) ); +} + +OUString +SwVbaColumn::getServiceImplName() +{ + return "SwVbaColumn"; +} + +uno::Sequence< OUString > +SwVbaColumn::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Column" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacolumn.hxx b/sw/source/ui/vba/vbacolumn.hxx new file mode 100644 index 0000000000..4fe34de54a --- /dev/null +++ b/sw/source/ui/vba/vbacolumn.hxx @@ -0,0 +1,53 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBACOLUMN_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBACOLUMN_HXX + +#include <ooo/vba/word/XColumn.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextTable.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XColumn > SwVbaColumn_BASE; + +class SwVbaColumn : public SwVbaColumn_BASE +{ +private: + css::uno::Reference< css::text::XTextTable > mxTextTable; + sal_Int32 mnIndex; + +public: + /// @throws css::uno::RuntimeException + SwVbaColumn( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextTable > xTextTable, sal_Int32 nIndex ); + virtual ~SwVbaColumn() override; + + // Methods + virtual sal_Int32 SAL_CALL getWidth() override; + virtual void SAL_CALL setWidth( sal_Int32 _width ) override; + virtual void SAL_CALL Select( ) override; + + /// @throws css::uno::RuntimeException + static void SelectColumn( const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextTable >& xTextTable, sal_Int32 nStartColumn, sal_Int32 nEndColumn ); + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBACOLUMN_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacolumns.cxx b/sw/source/ui/vba/vbacolumns.cxx new file mode 100644 index 0000000000..ffaf662029 --- /dev/null +++ b/sw/source/ui/vba/vbacolumns.cxx @@ -0,0 +1,149 @@ +/* -*- 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 <utility> + +#include "vbacolumns.hxx" +#include "vbacolumn.hxx" +#include "vbatablehelper.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class ColumnsEnumWrapper : public EnumerationHelper_BASE +{ + uno::WeakReference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< text::XTextTable > mxTextTable; + uno::Reference< container::XIndexAccess > mxIndexAccess; + sal_Int32 mnIndex; + +public: + ColumnsEnumWrapper( const uno::Reference< XHelperInterface >& xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< text::XTextTable > xTextTable ) : mxParent( xParent ), mxContext(std::move( xContext )), mxTextTable(std::move( xTextTable )), mnIndex( 0 ) + { + mxIndexAccess = mxTextTable->getColumns(); + } + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( mnIndex < mxIndexAccess->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if( mnIndex < mxIndexAccess->getCount() ) + { + return uno::Any( uno::Reference< word::XColumn > ( new SwVbaColumn( mxParent, mxContext, mxTextTable, mnIndex++ ) ) ); + } + throw container::NoSuchElementException(); + } +}; + +} + +SwVbaColumns::SwVbaColumns( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< text::XTextTable > xTextTable, const uno::Reference< table::XTableColumns >& xTableColumns ) : SwVbaColumns_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( xTableColumns, uno::UNO_QUERY_THROW ) ), mxTextTable(std::move( xTextTable )) +{ + mnStartColumnIndex = 0; + SwVbaTableHelper aTableHelper( mxTextTable ); + mnEndColumnIndex = aTableHelper.getTabColumnsMaxCount( ) - 1; +} + +SwVbaColumns::SwVbaColumns( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< text::XTextTable > xTextTable, const uno::Reference< table::XTableColumns >& xTableColumns, sal_Int32 nStartCol, sal_Int32 nEndCol ) : SwVbaColumns_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( xTableColumns, uno::UNO_QUERY_THROW ) ), mxTextTable(std::move( xTextTable )), mnStartColumnIndex( nStartCol ), mnEndColumnIndex( nEndCol ) +{ + if( mnEndColumnIndex < mnStartColumnIndex ) + throw uno::RuntimeException(); +} + +uno::Reference< word::XColumn > SwVbaColumns::getColumnAtIndex( sal_Int32 index ) +{ + return uno::Reference< word::XColumn >( new SwVbaColumn( this, mxContext, mxTextTable, index ) ); +} + +::sal_Int32 SAL_CALL SwVbaColumns::getWidth() +{ + return getColumnAtIndex( mnStartColumnIndex )->getWidth(); +} + +void SAL_CALL SwVbaColumns::setWidth( ::sal_Int32 _width ) +{ + for( sal_Int32 index = mnStartColumnIndex; index <= mnEndColumnIndex; index++ ) + { + getColumnAtIndex( index )->setWidth( _width ); + } +} + +void SAL_CALL SwVbaColumns::Select( ) +{ + SwVbaColumn::SelectColumn( getCurrentWordDoc(mxContext), mxTextTable, mnStartColumnIndex, mnEndColumnIndex ); +} + +::sal_Int32 SAL_CALL SwVbaColumns::getCount() +{ + return ( mnEndColumnIndex - mnStartColumnIndex + 1 ); +} + +uno::Any SAL_CALL SwVbaColumns::Item( const uno::Any& Index1, const uno::Any& /*not processed in this base class*/ ) +{ + sal_Int32 nIndex = 0; + if( Index1 >>= nIndex ) + { + if( nIndex <= 0 || nIndex > getCount() ) + { + throw lang::IndexOutOfBoundsException("Index out of bounds" ); + } + return uno::Any( uno::Reference< word::XColumn >( new SwVbaColumn( this, mxContext, mxTextTable, nIndex - 1 ) ) ); + } + throw uno::RuntimeException("Index out of bounds" ); +} + +// XEnumerationAccess +uno::Type +SwVbaColumns::getElementType() +{ + return cppu::UnoType<word::XColumn>::get(); +} +uno::Reference< container::XEnumeration > +SwVbaColumns::createEnumeration() +{ + return new ColumnsEnumWrapper( this, mxContext, mxTextTable ); +} + +uno::Any +SwVbaColumns::createCollectionObject( const uno::Any& aSource ) +{ + return aSource; +} + +OUString +SwVbaColumns::getServiceImplName() +{ + return "SwVbaColumns"; +} + +uno::Sequence<OUString> +SwVbaColumns::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.Columns" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacolumns.hxx b/sw/source/ui/vba/vbacolumns.hxx new file mode 100644 index 0000000000..712dc03f0b --- /dev/null +++ b/sw/source/ui/vba/vbacolumns.hxx @@ -0,0 +1,66 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBACOLUMNS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBACOLUMNS_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XColumns.hpp> +#include <ooo/vba/word/XColumn.hpp> +#include <com/sun/star/table/XTableColumns.hpp> +#include <com/sun/star/text/XTextTable.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XColumns > SwVbaColumns_BASE; + +class SwVbaColumns : public SwVbaColumns_BASE +{ +private: + css::uno::Reference< css::text::XTextTable > mxTextTable; + sal_Int32 mnStartColumnIndex; + sal_Int32 mnEndColumnIndex; + +private: + /// @throws css::uno::RuntimeException + css::uno::Reference< ooo::vba::word::XColumn > getColumnAtIndex( sal_Int32 index ); + +public: + /// @throws css::uno::RuntimeException + SwVbaColumns( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::text::XTextTable > xTextTable, const css::uno::Reference< css::table::XTableColumns >& xTableColumns ); + /// @throws css::uno::RuntimeException + SwVbaColumns( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::text::XTextTable > xTextTable, const css::uno::Reference< css::table::XTableColumns >& xTableColumns, sal_Int32 nStartCol, sal_Int32 nEndCol ); + + virtual sal_Int32 SAL_CALL getWidth( ) override; + virtual void SAL_CALL setWidth( sal_Int32 _width ) override; + virtual void SAL_CALL Select( ) override; + + //XCollection + virtual ::sal_Int32 SAL_CALL getCount() override; + virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& /*not processed in this base class*/ ) override; + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaColumns_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBACOLUMNS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacontentcontrol.cxx b/sw/source/ui/vba/vbacontentcontrol.cxx new file mode 100644 index 0000000000..dc4e4afc23 --- /dev/null +++ b/sw/source/ui/vba/vbacontentcontrol.cxx @@ -0,0 +1,753 @@ +/* -*- 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/. + */ + +#include <ooo/vba/word/WdColor.hpp> +#include <ooo/vba/word/WdCalendarType.hpp> +#include <ooo/vba/word/WdContentControlType.hpp> +#include <ooo/vba/word/WdLanguageID.hpp> + +#include <sal/log.hxx> + +#include <ndtxt.hxx> +#include <unotextrange.hxx> + +#include "vbacontentcontrol.hxx" +#include "vbacontentcontrollistentries.hxx" +#include "vbarange.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +/** + * Content controls are the modern version of FormFields, providing inline functionality similar + * to that of ActiveX form controls. Individual content controls may contain contents + * such as dates, lists, or paragraphs of formatted text. + * + * Not all functions are applicable to each type of control, so use getType verification liberally. + */ +SwVbaContentControl::SwVbaContentControl(const uno::Reference<XHelperInterface>& rParent, + const uno::Reference<uno::XComponentContext>& rContext, + const uno::Reference<text::XTextDocument>& xTextDocument, + std::shared_ptr<SwContentControl> pContentControl) + : SwVbaContentControl_BASE(rParent, rContext) + , mxTextDocument(xTextDocument) + , m_pCC(pContentControl) +{ + assert(m_pCC && "SwVbaContentControl created without a shared_ptr. Why would you do that?"); +} + +SwVbaContentControl::~SwVbaContentControl() {} + +sal_Bool SwVbaContentControl::getAllowInsertDeleteSection() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getAllowInsertDeleteSection stub"); + return false; +} + +void SwVbaContentControl::setAllowInsertDeleteSection(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setAllowInsertDeleteSection stub"); +} + +sal_Int32 SwVbaContentControl::getAppearance() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getAppearance stub"); + // wdContentControlBoundingBox / wdContentControlHidden / wdContentControlTags + return 0; +} + +void SwVbaContentControl::setAppearance(sal_Int32 nSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setAppearance[" << nSet << "] stub"); +} + +OUString SwVbaContentControl::getBuildingBlockCategory() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getBuildingBlockCategory stub"); + return OUString(); +} + +void SwVbaContentControl::setBuildingBlockCategory(const OUString& sSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setBuildingBlockCategory[" << sSet << "] stub"); +} + +sal_Int32 SwVbaContentControl::getBuildingBlockType() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getBuildingBlockType stub"); + // returns a WdBuildingBlockTypes that represents the type of building block + return 0; +} + +void SwVbaContentControl::setBuildingBlockType(sal_Int32 nSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setBuildingBlockType[" << nSet << "] stub"); +} + +sal_Bool SwVbaContentControl::getChecked() { return m_pCC->GetCheckbox() && m_pCC->GetChecked(); } + +void SwVbaContentControl::setChecked(sal_Bool bSet) +{ + // Word 2010: if locked, then the checked status is changed, but not the underlying text. + // Do we really want to do that? That is pretty bizarre behaviour... + // For now, just implement what seems to be a more logical response. + // TODO: test with modern versions. + if (getLockContents()) + return; + + if (m_pCC->GetCheckbox() && m_pCC->GetChecked() != static_cast<bool>(bSet)) + { + m_pCC->SetChecked(bSet); + m_pCC->SetShowingPlaceHolder(false); + if (m_pCC->GetTextAttr()) + m_pCC->GetTextAttr()->Invalidate(); + } +} + +sal_Int32 SwVbaContentControl::getColor() +{ + //This is just an assumed implementation - I have no testing environment to confirm. + OUString sColor = m_pCC->GetColor(); + if (sColor == "wdColorAutomatic") + return word::WdColor::wdColorAutomatic; + if (sColor == "wdColorBlack") + return word::WdColor::wdColorBlack; + if (sColor == "wdColorBlue") + return word::WdColor::wdColorBlue; + if (sColor == "wdColorBlueGray") + return word::WdColor::wdColorBlueGray; + if (sColor == "wdColorBrightGreen") + return word::WdColor::wdColorBrightGreen; + if (sColor == "wdColorBrown") + return word::WdColor::wdColorBrown; + if (sColor == "wdColorDarkBlue") + return word::WdColor::wdColorDarkBlue; + if (sColor == "wdColorDarkGreen") + return word::WdColor::wdColorDarkGreen; + if (sColor == "wdColorDarkRed") + return word::WdColor::wdColorDarkRed; + if (sColor == "wdColorDarkTeal") + return word::WdColor::wdColorDarkTeal; + if (sColor == "wdColorDarkYellow") + return word::WdColor::wdColorDarkYellow; + if (sColor == "wdColorGold") + return word::WdColor::wdColorGold; + if (sColor == "wdColorGray05") + return word::WdColor::wdColorGray05; + if (sColor == "wdColorGray10") + return word::WdColor::wdColorGray10; + if (sColor == "wdColorGray125") + return word::WdColor::wdColorGray125; + if (sColor == "wdColorGray15") + return word::WdColor::wdColorGray15; + if (sColor == "wdColorGray20") + return word::WdColor::wdColorGray20; + if (sColor == "wdColorGray25") + return word::WdColor::wdColorGray25; + if (sColor == "wdColorGray30") + return word::WdColor::wdColorGray30; + if (sColor == "wdColorGray35") + return word::WdColor::wdColorGray35; + if (sColor == "wdColorGray375") + return word::WdColor::wdColorGray375; + if (sColor == "wdColorGray40") + return word::WdColor::wdColorGray40; + if (sColor == "wdColorGray45") + return word::WdColor::wdColorGray45; + if (sColor == "wdColorGray50") + return word::WdColor::wdColorGray50; + if (sColor == "wdColorGray55") + return word::WdColor::wdColorGray55; + if (sColor == "wdColorGray60") + return word::WdColor::wdColorGray60; + if (sColor == "wdColorGray625") + return word::WdColor::wdColorGray625; + if (sColor == "wdColorGray65") + return word::WdColor::wdColorGray65; + if (sColor == "wdColorGray70") + return word::WdColor::wdColorGray70; + if (sColor == "wdColorGray75") + return word::WdColor::wdColorGray75; + if (sColor == "wdColorGray80") + return word::WdColor::wdColorGray80; + if (sColor == "wdColorGray85") + return word::WdColor::wdColorGray85; + if (sColor == "wdColorGray875") + return word::WdColor::wdColorGray875; + if (sColor == "wdColorGray90") + return word::WdColor::wdColorGray90; + if (sColor == "wdColorGray95") + return word::WdColor::wdColorGray95; + if (sColor == "wdColorGreen") + return word::WdColor::wdColorGreen; + if (sColor == "wdColorIndigo") + return word::WdColor::wdColorIndigo; + if (sColor == "wdColorLavender") + return word::WdColor::wdColorLavender; + if (sColor == "wdColorLightBlue") + return word::WdColor::wdColorLightBlue; + if (sColor == "wdColorLightGreen") + return word::WdColor::wdColorLightGreen; + if (sColor == "wdColorLightOrange") + return word::WdColor::wdColorLightOrange; + if (sColor == "wdColorLightTurquoise") + return word::WdColor::wdColorLightTurquoise; + if (sColor == "wdColorLightYellow") + return word::WdColor::wdColorLightYellow; + if (sColor == "wdColorLime") + return word::WdColor::wdColorLime; + if (sColor == "wdColorOliveGreen") + return word::WdColor::wdColorOliveGreen; + if (sColor == "wdColorOrange") + return word::WdColor::wdColorOrange; + if (sColor == "wdColorPaleBlue") + return word::WdColor::wdColorPaleBlue; + if (sColor == "wdColorPink") + return word::WdColor::wdColorPink; + if (sColor == "wdColorPlum") + return word::WdColor::wdColorPlum; + if (sColor == "wdColorRed") + return word::WdColor::wdColorRed; + if (sColor == "wdColorRose") + return word::WdColor::wdColorRose; + if (sColor == "wdColorSeaGreen") + return word::WdColor::wdColorSeaGreen; + if (sColor == "wdColorSkyBlue") + return word::WdColor::wdColorSkyBlue; + if (sColor == "wdColorTan") + return word::WdColor::wdColorTan; + if (sColor == "wdColorTeal") + return word::WdColor::wdColorTeal; + if (sColor == "wdColorTurquoise") + return word::WdColor::wdColorTurquoise; + if (sColor == "wdColorViolet") + return word::WdColor::wdColorViolet; + if (sColor == "wdColorWhite") + return word::WdColor::wdColorWhite; + if (sColor == "wdColorYellow") + return word::WdColor::wdColorYellow; + + return word::WdColor::wdColorBlack; +} + +void SwVbaContentControl::setColor(sal_Int32 nWdColor) +{ + switch (nWdColor) + { + case word::WdColor::wdColorAqua: + m_pCC->SetColor("wdColorAqua"); + break; + case word::WdColor::wdColorAutomatic: + m_pCC->SetColor("wdColorAutomatic"); + break; + case word::WdColor::wdColorBlack: + m_pCC->SetColor("wdColorBlack"); + break; + case word::WdColor::wdColorBlue: + m_pCC->SetColor("wdColorBlue"); + break; + case word::WdColor::wdColorBlueGray: + m_pCC->SetColor("wdColorBlueGray"); + break; + case word::WdColor::wdColorBrightGreen: + m_pCC->SetColor("wdColorBrightGreen"); + break; + case word::WdColor::wdColorBrown: + m_pCC->SetColor("wdColorBrown"); + break; + case word::WdColor::wdColorDarkBlue: + m_pCC->SetColor("wdColorDarkBlue"); + break; + case word::WdColor::wdColorDarkGreen: + m_pCC->SetColor("wdColorDarkGreen"); + break; + case word::WdColor::wdColorDarkRed: + m_pCC->SetColor("wdColorDarkRed"); + break; + case word::WdColor::wdColorDarkTeal: + m_pCC->SetColor("wdColorDarkTeal"); + break; + case word::WdColor::wdColorDarkYellow: + m_pCC->SetColor("wdColorDarkYellow"); + break; + case word::WdColor::wdColorGold: + m_pCC->SetColor("wdColorGold"); + break; + case word::WdColor::wdColorGray05: + m_pCC->SetColor("wdColorGray05"); + break; + case word::WdColor::wdColorGray10: + m_pCC->SetColor("wdColorGray10"); + break; + case word::WdColor::wdColorGray125: + m_pCC->SetColor("wdColorGray125"); + break; + case word::WdColor::wdColorGray15: + m_pCC->SetColor("wdColorGray15"); + break; + case word::WdColor::wdColorGray20: + m_pCC->SetColor("wdColorGray20"); + break; + case word::WdColor::wdColorGray25: + m_pCC->SetColor("wdColorGray25"); + break; + case word::WdColor::wdColorGray30: + m_pCC->SetColor("wdColorGray30"); + break; + case word::WdColor::wdColorGray35: + m_pCC->SetColor("wdColorGray35"); + break; + case word::WdColor::wdColorGray375: + m_pCC->SetColor("wdColorGray375"); + break; + case word::WdColor::wdColorGray40: + m_pCC->SetColor("wdColorGray40"); + break; + case word::WdColor::wdColorGray45: + m_pCC->SetColor("wdColorGray45"); + break; + case word::WdColor::wdColorGray50: + m_pCC->SetColor("wdColorGray50"); + break; + case word::WdColor::wdColorGray55: + m_pCC->SetColor("wdColorGray55"); + break; + case word::WdColor::wdColorGray60: + m_pCC->SetColor("wdColorGray60"); + break; + case word::WdColor::wdColorGray625: + m_pCC->SetColor("wdColorGray625"); + break; + case word::WdColor::wdColorGray65: + m_pCC->SetColor("wdColorGray65"); + break; + case word::WdColor::wdColorGray70: + m_pCC->SetColor("wdColorGray70"); + break; + case word::WdColor::wdColorGray75: + m_pCC->SetColor("wdColorGray75"); + break; + case word::WdColor::wdColorGray80: + m_pCC->SetColor("wdColorGray80"); + break; + case word::WdColor::wdColorGray85: + m_pCC->SetColor("wdColorGray85"); + break; + case word::WdColor::wdColorGray875: + m_pCC->SetColor("wdColorGray875"); + break; + case word::WdColor::wdColorGray90: + m_pCC->SetColor("wdColorGray90"); + break; + case word::WdColor::wdColorGray95: + m_pCC->SetColor("wdColorGray95"); + break; + case word::WdColor::wdColorGreen: + m_pCC->SetColor("wdColorGreen"); + break; + case word::WdColor::wdColorIndigo: + m_pCC->SetColor("wdColorIndigo"); + break; + case word::WdColor::wdColorLavender: + m_pCC->SetColor("wdColorLavender"); + break; + case word::WdColor::wdColorLightBlue: + m_pCC->SetColor("wdColorLightBlue"); + break; + case word::WdColor::wdColorLightGreen: + m_pCC->SetColor("wdColorLightGreen"); + break; + case word::WdColor::wdColorLightOrange: + m_pCC->SetColor("wdColorLightOrange"); + break; + case word::WdColor::wdColorLightTurquoise: + m_pCC->SetColor("wdColorLightTurquoise"); + break; + case word::WdColor::wdColorLightYellow: + m_pCC->SetColor("wdColorLightYellow"); + break; + case word::WdColor::wdColorLime: + m_pCC->SetColor("wdColorLime"); + break; + case word::WdColor::wdColorOliveGreen: + m_pCC->SetColor("wdColorOliveGreen"); + break; + case word::WdColor::wdColorOrange: + m_pCC->SetColor("wdColorOrange"); + break; + case word::WdColor::wdColorPaleBlue: + m_pCC->SetColor("wdColorPaleBlue"); + break; + case word::WdColor::wdColorPink: + m_pCC->SetColor("wdColorPink"); + break; + case word::WdColor::wdColorPlum: + m_pCC->SetColor("wdColorPlum"); + break; + case word::WdColor::wdColorRed: + m_pCC->SetColor("wdColorRed"); + break; + case word::WdColor::wdColorRose: + m_pCC->SetColor("wdColorRose"); + break; + case word::WdColor::wdColorSeaGreen: + m_pCC->SetColor("wdColorSeaGreen"); + break; + case word::WdColor::wdColorSkyBlue: + m_pCC->SetColor("wdColorSkyBlue"); + break; + case word::WdColor::wdColorTan: + m_pCC->SetColor("wdColorTan"); + break; + case word::WdColor::wdColorTeal: + m_pCC->SetColor("wdColorTeal"); + break; + case word::WdColor::wdColorTurquoise: + m_pCC->SetColor("wdColorTurquoise"); + break; + case word::WdColor::wdColorViolet: + m_pCC->SetColor("wdColorViolet"); + break; + case word::WdColor::wdColorWhite: + m_pCC->SetColor("wdColorWhite"); + break; + default:; + } +} + +sal_Int32 SwVbaContentControl::getDateCalendarType() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getDateCalendarType stub"); + // returns a WdCalendarTypes that represents the type of building block + return word::WdCalendarType::wdCalendarWestern; +} + +void SwVbaContentControl::setDateCalendarType(sal_Int32 nSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setDateCalendarType[" << nSet << "] stub"); +} + +OUString SwVbaContentControl::getDateDisplayFormat() { return m_pCC->GetDateFormat(); } + +void SwVbaContentControl::setDateDisplayFormat(const OUString& sSet) { m_pCC->SetDateFormat(sSet); } + +sal_Int32 SwVbaContentControl::getDateStorageFormat() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getDateStorageFormat stub"); + // returns a WdContentControlDateStorageFormat when bound to the XML data store. + return 0; +} + +void SwVbaContentControl::setDateStorageFormat(sal_Int32 nSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setDateStorageFormat[" << nSet << "] stub"); +} + +sal_Int32 SwVbaContentControl::getDateDisplayLocale() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getDateDisplayLocale stub"); + // returns a WdLanguageID that represents the language format for a date content control. + return word::WdLanguageID::wdEnglishUS; +} + +uno::Any SwVbaContentControl::getDropdownListEntries() +{ + if (!m_pCC->GetDropDown() && !m_pCC->GetComboBox()) + return uno::Any(); + + return uno::Any( + uno::Reference<XCollection>(new SwVbaContentControlListEntries(this, mxContext, m_pCC))); +} + +OUString SwVbaContentControl::getID() +{ + // This signed integer is treated in VBA as if it was an unsigned int. + return OUString::number(static_cast<sal_uInt32>(m_pCC->GetId())); +} + +sal_Int32 SwVbaContentControl::getLevel() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getLevel stub"); + // returns a WdContentControlLevel + return 0; +} + +sal_Bool SwVbaContentControl::getLockContentControl() +{ + std::optional<bool> oLock = m_pCC->GetLock(/*bControl=*/true); + return oLock.has_value() && *oLock; +} + +void SwVbaContentControl::setLockContentControl(sal_Bool bSet) +{ + std::optional<bool> oLock = m_pCC->GetLock(/*bControl=*/false); + m_pCC->SetLock(/*bContents=*/oLock.has_value() && *oLock, /*bControl=*/bSet); +} + +sal_Bool SwVbaContentControl::getLockContents() +{ + // If the theoretical design model says it is locked, then report as locked. + std::optional<bool> oLock = m_pCC->GetLock(/*bControl=*/false); + if (oLock.has_value() && *oLock) + return true; + + // Now check the real implementation. + // Checkbox/DropDown/Picture are normally locked - but not in this sense. Report as unlocked. + if (m_pCC->GetType() == SwContentControlType::CHECKBOX + || m_pCC->GetType() == SwContentControlType::DROP_DOWN_LIST + || m_pCC->GetType() == SwContentControlType::PICTURE) + { + return false; + } + + return m_pCC->GetReadWrite(); +} + +void SwVbaContentControl::setLockContents(sal_Bool bSet) +{ + // Set the lock both theoretically and actually. + std::optional<bool> oLock = m_pCC->GetLock(/*bControl=*/true); + m_pCC->SetLock(/*bContents=*/bSet, /*bControl=*/oLock.has_value() && *oLock); + + // Checkbox/DropDown/Picture are normally locked in LO implementation - don't unlock them. + if (m_pCC->GetType() == SwContentControlType::CHECKBOX + || m_pCC->GetType() == SwContentControlType::DROP_DOWN_LIST + || m_pCC->GetType() == SwContentControlType::PICTURE) + { + return; + } + m_pCC->SetReadWrite(bSet); +} + +sal_Bool SwVbaContentControl::getMultiLine() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getMultiLine stub"); + return false; +} + +void SwVbaContentControl::setMultiLine(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setMultiLine stub"); +} + +OUString SwVbaContentControl::getPlaceholderText() +{ + // return m_pCC->GetPlaceholderDocPart(); // This is not correct. Much more complex than this... + SAL_INFO("sw.vba", "SwVbaContentControl::getPlaceholderText stub"); + return OUString(); +} + +sal_Bool SwVbaContentControl::getShowingPlaceholderText() { return m_pCC->GetShowingPlaceHolder(); } + +uno::Reference<word::XRange> SwVbaContentControl::getRange() +{ + uno::Reference<word::XRange> xRet; + SwTextNode* pTextNode = m_pCC->GetTextNode(); + if (pTextNode && m_pCC->GetTextAttr()) + { + // Don't select the text attribute itself at the start. + SwPosition aStart(*pTextNode, m_pCC->GetTextAttr()->GetStart() + 1); + // Don't select the CH_TXTATR_BREAKWORD itself at the end. + SwPosition aEnd(*pTextNode, *m_pCC->GetTextAttr()->End() - 1); + uno::Reference<text::XTextRange> xText( + SwXTextRange::CreateXTextRange(pTextNode->GetDoc(), aStart, &aEnd)); + if (xText.is()) + xRet = new SwVbaRange(mxParent, mxContext, mxTextDocument, xText->getStart(), + xText->getEnd()); + } + return xRet; +} + +OUString SwVbaContentControl::getRepeatingSectionItemTitle() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getRepeatingSectionItemTitle stub"); + return OUString(); +} + +void SwVbaContentControl::setRepeatingSectionItemTitle(const OUString& rSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setRepeatingSectionItemTitle[" << rSet << "] stub"); +} + +OUString SwVbaContentControl::getTag() { return m_pCC->GetTag(); } + +void SwVbaContentControl::setTag(const OUString& rSet) { return m_pCC->SetTag(rSet); } + +sal_Bool SwVbaContentControl::getTemporary() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getTemporary stub"); + // Is content control removed when user edits (one time use)? Not implemented in LO. + return false; +} + +void SwVbaContentControl::setTemporary(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setTemporary stub"); +} + +OUString SwVbaContentControl::getTitle() { return m_pCC->GetAlias(); } + +void SwVbaContentControl::setTitle(const OUString& rSet) { return m_pCC->SetAlias(rSet); } + +sal_Int32 SwVbaContentControl::getType() +{ + SwContentControlType eType = m_pCC->GetType(); + sal_Int32 eVbaType = word::WdContentControlType::wdContentControlRichText; + + switch (eType) + { + case SwContentControlType::CHECKBOX: + eVbaType = word::WdContentControlType::wdContentControlCheckbox; + break; + case SwContentControlType::DROP_DOWN_LIST: + eVbaType = word::WdContentControlType::wdContentControlDropdownList; + break; + case SwContentControlType::PICTURE: + eVbaType = word::WdContentControlType::wdContentControlPicture; + break; + case SwContentControlType::DATE: + eVbaType = word::WdContentControlType::wdContentControlDate; + break; + case SwContentControlType::PLAIN_TEXT: + eVbaType = word::WdContentControlType::wdContentControlText; + break; + case SwContentControlType::COMBO_BOX: + eVbaType = word::WdContentControlType::wdContentControlComboBox; + break; + case SwContentControlType::RICH_TEXT: + default:; + } + return eVbaType; +} + +void SwVbaContentControl::setType(sal_Int32 nSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setType[" << nSet << "] stub"); + // SwContentControlType eType = SwContentControlType::RICH_TEXT; + // switch(nSet) + // { + // case word::WdContentControlType::wdContentControlCheckbox: + // eType = SwContentControlType::CHECKBOX; + // break; + // case word::WdContentControlType::wdContentControlDropdownList: + // eType = SwContentControlType::DROP_DOWN_LIST; + // break; + // case word::WdContentControlType::wdContentControlPicture: + // eType = SwContentControlType::PICTURE; + // break; + // case word::WdContentControlType::wdContentControlDate: + // eType = SwContentControlType::DATE; + // break; + // case word::WdContentControlType::wdContentControlText: + // eType = SwContentControlType::PLAIN_TEXT; + // break; + // case word::WdContentControlType::wdContentControlComboBox: + // eType = SwContentControlType::COMBO_BOX; + // break; + // case word::WdContentControlType::wdContentControlRichText: + // default:; + // } + // m_pCC->SetType(eType); +} + +void SwVbaContentControl::Copy() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::Copy[" << getID() << "] stub"); +} + +void SwVbaContentControl::Cut() +{ + if (getLockContentControl() || !m_pCC->GetTextAttr()) + return; + + SAL_INFO("sw.vba", + "SwVbaContentControl::Cut[" << getID() << "], but missing sending to clipboard"); + + m_pCC->GetTextAttr()->Delete(/*bSaveContents=*/getLockContents()); +} + +void SwVbaContentControl::Delete(const uno::Any& DeleteContents) +{ + if (getLockContentControl() || !m_pCC->GetTextAttr()) + return; + + bool bDeleteContents = false; + DeleteContents >>= bDeleteContents; + + m_pCC->GetTextAttr()->Delete(/*bSaveContents=*/!bDeleteContents || getLockContents()); +} + +void SwVbaContentControl::SetCheckedSymbol(sal_Int32 Character, const uno::Any& Font) +{ + if (!m_pCC->GetTextAttr()) + return; + + SAL_INFO_IF(Font.hasValue(), "sw.vba", "SetCheckedSymbol Font[" << Font << "] stub"); + if (Character < 31 || Character > SAL_MAX_UINT16) + return; // unsupported character. Would such a thing exist in VBA? + + m_pCC->SetCheckedState(OUString(static_cast<sal_Unicode>(Character))); + + if (m_pCC->GetCheckbox() && m_pCC->GetChecked() && !m_pCC->GetShowingPlaceHolder()) + m_pCC->GetTextAttr()->Invalidate(); +} + +void SwVbaContentControl::SetUnCheckedSymbol(sal_Int32 Character, const uno::Any& Font) +{ + if (!m_pCC->GetTextAttr()) + return; + + SAL_INFO_IF(Font.hasValue(), "sw.vba", "SetUnCheckedSymbol Font[" << Font << "] stub"); + if (Character < 31 || Character > SAL_MAX_UINT16) + return; // unsupported character. Would such a thing exist in VBA? + + m_pCC->SetUncheckedState(OUString(static_cast<sal_Unicode>(Character))); + + if (m_pCC->GetCheckbox() && !m_pCC->GetChecked() && !m_pCC->GetShowingPlaceHolder()) + m_pCC->GetTextAttr()->Invalidate(); +} + +void SwVbaContentControl::SetPlaceholderText(const uno::Any& BuildingBlock, const uno::Any& Range, + const uno::Any& Text) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::SetPlaceholderText stub"); + if (BuildingBlock.hasValue()) + { + // Set placeholder text to the building block - whatever that is. + } + else if (Range.hasValue()) + { + // Set placeholder text to the contents of the Range, however you do that. + } + else if (Text.hasValue()) + { + // Set placeholder text to the provided string + } + else + { + // Remove placeholder text. + m_pCC->SetPlaceholderDocPart(""); + } + if (m_pCC->GetShowingPlaceHolder() && !getLockContents() && m_pCC->GetTextAttr()) + { + //replace the text and ensure showing placeholder is still set + } +} + +void SwVbaContentControl::Ungroup() { SAL_INFO("sw.vba", "SwVbaContentControl::UnGroup stub"); } + +OUString SwVbaContentControl::getServiceImplName() { return "SwVbaContentControl"; } + +uno::Sequence<OUString> SwVbaContentControl::getServiceNames() +{ + static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.ContentControl" }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacontentcontrol.hxx b/sw/source/ui/vba/vbacontentcontrol.hxx new file mode 100644 index 0000000000..9f98b92468 --- /dev/null +++ b/sw/source/ui/vba/vbacontentcontrol.hxx @@ -0,0 +1,142 @@ +/* -*- 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/. + */ +#pragma once + +#include <com/sun/star/text/XTextDocument.hpp> +#include <ooo/vba/word/XContentControl.hpp> + +#include <vbahelper/vbahelperinterface.hxx> + +#include <textcontentcontrol.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XContentControl> SwVbaContentControl_BASE; + +class SwVbaContentControl : public SwVbaContentControl_BASE +{ +private: + css::uno::Reference<css::text::XTextDocument> mxTextDocument; + std::shared_ptr<SwContentControl> m_pCC; + +public: + /// @throws css::uno::RuntimeException + SwVbaContentControl(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, + const css::uno::Reference<css::text::XTextDocument>& xTextDocument, + std::shared_ptr<SwContentControl> pContentControl); + ~SwVbaContentControl() override; + + // XContentControl Properties + sal_Bool SAL_CALL getAllowInsertDeleteSection() override; + void SAL_CALL setAllowInsertDeleteSection(sal_Bool bSet) override; + + sal_Int32 SAL_CALL getAppearance() override; + void SAL_CALL setAppearance(sal_Int32 nSet) override; + + OUString SAL_CALL getBuildingBlockCategory() override; + void SAL_CALL setBuildingBlockCategory(const OUString& sSet) override; + + sal_Int32 SAL_CALL getBuildingBlockType() override; + void SAL_CALL setBuildingBlockType(sal_Int32 nSet) override; + + sal_Bool SAL_CALL getChecked() override; + void SAL_CALL setChecked(sal_Bool bSet) override; + + // returns or sets a WdColor (@since after 2010 I assume) + sal_Int32 SAL_CALL getColor() override; + void SAL_CALL setColor(sal_Int32 nSet) override; + + sal_Int32 SAL_CALL getDateCalendarType() override; + void SAL_CALL setDateCalendarType(sal_Int32 nSet) override; + + OUString SAL_CALL getDateDisplayFormat() override; + void SAL_CALL setDateDisplayFormat(const OUString& sSet) override; + + sal_Int32 SAL_CALL getDateDisplayLocale() override; + + sal_Int32 SAL_CALL getDateStorageFormat() override; + void SAL_CALL setDateStorageFormat(sal_Int32 nSet) override; + + css::uno::Any SAL_CALL getDropdownListEntries() override; + + // This is an integer used as a unique identifier string + OUString SAL_CALL getID() override; + + sal_Int32 SAL_CALL getLevel() override; + + // returns or sets if the user can delete the control + sal_Bool SAL_CALL getLockContentControl() override; + void SAL_CALL setLockContentControl(sal_Bool bSet) override; + + // returns or sets if the user can edit the contents (i.e. read-only flag) + sal_Bool SAL_CALL getLockContents() override; + void SAL_CALL setLockContents(sal_Bool bSet) override; + + sal_Bool SAL_CALL getMultiLine() override; + void SAL_CALL setMultiLine(sal_Bool bSet) override; + + // WRONG- THIS SHOULD RETURN XBUILDINGBLOCK + OUString SAL_CALL getPlaceholderText() override; + + sal_Bool SAL_CALL getShowingPlaceholderText() override; + + OUString SAL_CALL getRepeatingSectionItemTitle() override; + void SAL_CALL setRepeatingSectionItemTitle(const OUString& rSet) override; + + css::uno::Reference<ooo::vba::word::XRange> SAL_CALL getRange() override; + + OUString SAL_CALL getTag() override; + void SAL_CALL setTag(const OUString& rSet) override; + + // returns or sets if the control is removed after accepting user change (i.e. control -> text) + sal_Bool SAL_CALL getTemporary() override; + void SAL_CALL setTemporary(sal_Bool bSet) override; + + OUString SAL_CALL getTitle() override; + void SAL_CALL setTitle(const OUString& rSet) override; + + // returns or sets a WdContentControlType that represents the type for a content control. + sal_Int32 SAL_CALL getType() override; + void SAL_CALL setType(sal_Int32 nSet) override; + + // XContentControl Methods + + // Copies the content control from the active document to the Clipboard. + // Retrieve from the clipboard using the Paste method of the Selection object + // or of the Range object, or use the Paste function from within Microsoft Word. + void SAL_CALL Copy() override; + + // Removes the control from the active document and moves it to the Clipboard. + void SAL_CALL Cut() override; + + // Specifies whether to delete the contents of the content control. The default value is False. + // True removes both the content control and its contents. + // False removes the control but leaves the contents of the content control in the document. + void SAL_CALL Delete(const css::uno::Any& bDeleteContents) override; + + // Set the Unicode character used to display the checked state. + void SAL_CALL SetCheckedSymbol(sal_Int32 Character, const css::uno::Any& sFont) override; + + // Set the Unicode character used to display the unchecked state. + void SAL_CALL SetUnCheckedSymbol(sal_Int32 Character, const css::uno::Any& sFont) override; + + // Sets the placeholder text that displays until a user enters their own text. + // Only one of the parameters is used when specifying placeholder text. + // If more than one parameter is provided, use the text specified in the first parameter. + // If all parameters are omitted, the placeholder text is blank. + void SAL_CALL SetPlaceholderText(const css::uno::Any& BuildingBlock, const css::uno::Any& Range, + const css::uno::Any& sText) override; + + void SAL_CALL Ungroup() override; + + // XHelperInterface + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacontentcontrollistentries.cxx b/sw/source/ui/vba/vbacontentcontrollistentries.cxx new file mode 100644 index 0000000000..552397e156 --- /dev/null +++ b/sw/source/ui/vba/vbacontentcontrollistentries.cxx @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "vbacontentcontrollistentries.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace +{ +class ContentControlListEntriesEnumWrapper : public EnumerationHelper_BASE +{ + uno::Reference<container::XIndexAccess> mxIndexAccess; + sal_Int32 mnIndex; + +public: + explicit ContentControlListEntriesEnumWrapper( + uno::Reference<container::XIndexAccess> xIndexAccess) + : mxIndexAccess(xIndexAccess) + , mnIndex(0) + { + } + + virtual sal_Bool SAL_CALL hasMoreElements() override + { + return (mnIndex < mxIndexAccess->getCount()); + } + + virtual uno::Any SAL_CALL nextElement() override + { + if (mnIndex < mxIndexAccess->getCount()) + { + return mxIndexAccess->getByIndex(mnIndex++); + } + throw container::NoSuchElementException(); + } +}; + +class ContentControlListEntryCollectionHelper + : public ::cppu::WeakImplHelper<container::XIndexAccess, container::XEnumerationAccess> +{ +private: + uno::Reference<XHelperInterface> mxParent; + uno::Reference<uno::XComponentContext> mxContext; + std::shared_ptr<SwContentControl> m_pCC; + +public: + /// @throws css::uno::RuntimeException + ContentControlListEntryCollectionHelper(uno::Reference<ov::XHelperInterface> xParent, + uno::Reference<uno::XComponentContext> xContext, + std::shared_ptr<SwContentControl> pCC) + : mxParent(xParent) + , mxContext(xContext) + , m_pCC(pCC) + { + } + + sal_Int32 SAL_CALL getCount() override { return m_pCC->GetListItems().size(); } + + uno::Any SAL_CALL getByIndex(sal_Int32 Index) override + { + if (Index < 0 || Index >= getCount()) + throw lang::IndexOutOfBoundsException(); + + return uno::Any(uno::Reference<word::XContentControlListEntry>( + new SwVbaContentControlListEntry(mxParent, mxContext, m_pCC, Index))); + } + + uno::Type SAL_CALL getElementType() override + { + return cppu::UnoType<word::XContentControlListEntry>::get(); + } + + sal_Bool SAL_CALL hasElements() override { return getCount() != 0; } + + // XEnumerationAccess + uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override + { + return new ContentControlListEntriesEnumWrapper(this); + } +}; +} + +/** + * DropDownLists and ComboBoxes contain a list of name/value pairs to choose from. + * Use of DropDownListEntries from any other control is invalid. + */ +SwVbaContentControlListEntries::SwVbaContentControlListEntries( + const uno::Reference<XHelperInterface>& xParent, + const uno::Reference<uno::XComponentContext>& xContext, std::shared_ptr<SwContentControl> pCC) + : SwVbaContentControlListEntries_BASE( + xParent, xContext, + uno::Reference<container::XIndexAccess>( + new ContentControlListEntryCollectionHelper(xParent, xContext, pCC))) + , m_pCC(pCC) +{ +} + +uno::Reference<word::XContentControlListEntry> +SwVbaContentControlListEntries::Add(const OUString& rName, const uno::Any& rValue, + const uno::Any& rIndex) +{ + // No duplicate Names allowed in VBA + for (auto& rListItem : m_pCC->GetListItems()) + { + if (rListItem.ToString() == rName) + return uno::Reference<word::XContentControlListEntry>(); + } + + sal_Int32 nZIndex = SAL_MAX_INT32; + rIndex >>= nZIndex; + // rIndex is 1-based, nZIndex is 0-based. If rIndex is not given, then add as the last choice. + assert(nZIndex > 0); + --nZIndex; + nZIndex = std::min(static_cast<size_t>(nZIndex), m_pCC->GetListItems().size()); + + OUString sValue; + rValue >>= sValue; + if (m_pCC->AddListItem(nZIndex, rName, sValue)) + { + return uno::Reference<word::XContentControlListEntry>( + new SwVbaContentControlListEntry(mxParent, mxContext, m_pCC, nZIndex)); + } + + return uno::Reference<word::XContentControlListEntry>(); +} + +void SwVbaContentControlListEntries::Clear() { m_pCC->ClearListItems(); } + +sal_Int32 SwVbaContentControlListEntries::getCount() { return m_pCC->GetListItems().size(); } + +// XEnumerationAccess +uno::Type SwVbaContentControlListEntries::getElementType() +{ + return cppu::UnoType<word::XContentControlListEntry>::get(); +} + +uno::Reference<container::XEnumeration> SwVbaContentControlListEntries::createEnumeration() +{ + return new ContentControlListEntriesEnumWrapper(m_xIndexAccess); +} + +// SwVbaContentControlListEntries_BASE +uno::Any SwVbaContentControlListEntries::createCollectionObject(const uno::Any& aSource) +{ + return aSource; +} + +OUString SwVbaContentControlListEntries::getServiceImplName() +{ + return "SwVbaContentControlListEntries"; +} + +uno::Sequence<OUString> SwVbaContentControlListEntries::getServiceNames() +{ + static uno::Sequence<OUString> const sNames{ "ooo.vba.word.ContentControlListEntries" }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacontentcontrollistentries.hxx b/sw/source/ui/vba/vbacontentcontrollistentries.hxx new file mode 100644 index 0000000000..dc32203179 --- /dev/null +++ b/sw/source/ui/vba/vbacontentcontrollistentries.hxx @@ -0,0 +1,51 @@ +/* -*- 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/. + */ +#pragma once + +#include <ooo/vba/word/XContentControlListEntries.hpp> +#include <ooo/vba/word/XContentControlListEntry.hpp> + +#include <vbahelper/vbacollectionimpl.hxx> + +#include <textcontentcontrol.hxx> + +#include "vbacontentcontrollistentries.hxx" +#include "vbacontentcontrollistentry.hxx" + +typedef CollTestImplHelper<ooo::vba::word::XContentControlListEntries> + SwVbaContentControlListEntries_BASE; + +class SwVbaContentControlListEntries : public SwVbaContentControlListEntries_BASE +{ +private: + std::shared_ptr<SwContentControl> m_pCC; + +public: + /// @throws css::uno::RuntimeException + SwVbaContentControlListEntries(const css::uno::Reference<ov::XHelperInterface>& xParent, + const css::uno::Reference<css::uno::XComponentContext>& xContext, + std::shared_ptr<SwContentControl> pCC); + + // XContentControlListEntries + css::uno::Reference<ooo::vba::word::XContentControlListEntry> SAL_CALL + Add(const OUString& rName, const css::uno::Any& rValue, const css::uno::Any& rIndex) override; + void SAL_CALL Clear() override; + sal_Int32 SAL_CALL getCount() override; + + // XEnumerationAccess + css::uno::Type SAL_CALL getElementType() override; + css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override; + + // SwVbaContentControlListEntries_BASE + css::uno::Any createCollectionObject(const css::uno::Any& aSource) override; + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacontentcontrollistentry.cxx b/sw/source/ui/vba/vbacontentcontrollistentry.cxx new file mode 100644 index 0000000000..73f5e9d0a2 --- /dev/null +++ b/sw/source/ui/vba/vbacontentcontrollistentry.cxx @@ -0,0 +1,161 @@ +/* -*- 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/. + */ + +#include "vbacontentcontrollistentry.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaContentControlListEntry::SwVbaContentControlListEntry( + const uno::Reference<ooo::vba::XHelperInterface>& rParent, + const uno::Reference<uno::XComponentContext>& rContext, std::shared_ptr<SwContentControl> pCC, + size_t nZIndex) + : SwVbaContentControlListEntry_BASE(rParent, rContext) + , m_pCC(pCC) + , m_nZIndex(nZIndex) +{ +} + +SwVbaContentControlListEntry::~SwVbaContentControlListEntry() {} + +sal_Int32 SwVbaContentControlListEntry::getIndex() { return m_nZIndex + 1; } + +void SwVbaContentControlListEntry::setIndex(sal_Int32 nSet) +{ + if (nSet < 1 || static_cast<size_t>(nSet) == m_nZIndex + 1) + return; + + // Given a one-based index to set to + size_t nIndex = std::min(static_cast<size_t>(nSet), m_pCC->GetListItems().size()); + // change to zero-based index + --nIndex; + while (nIndex < m_nZIndex) + MoveUp(); + while (m_nZIndex < nIndex) + MoveDown(); +} + +OUString SwVbaContentControlListEntry::getText() +{ + assert(m_nZIndex < m_pCC->GetListItems().size()); + const SwContentControlListItem& rListItem = m_pCC->GetListItems()[m_nZIndex]; + return rListItem.ToString(); +} + +void SwVbaContentControlListEntry::setText(const OUString& rSet) +{ + std::vector<SwContentControlListItem> vListItems = m_pCC->GetListItems(); + assert(m_nZIndex < vListItems.size()); + + // prevent duplicates + for (size_t i = 0; i < vListItems.size(); ++i) + { + if (vListItems[i].ToString() == rSet) + return; + } + + const std::optional<size_t> oSel(m_pCC->GetSelectedListItem(/*bCheckDocModel=*/true)); + const bool bNeedsInvalidation = m_pCC->GetDropDown() && oSel && *oSel == m_nZIndex; + + vListItems[m_nZIndex].m_aDisplayText = rSet; + m_pCC->SetListItems(vListItems); + + if (bNeedsInvalidation) + { + m_pCC->SetSelectedListItem(m_nZIndex); + if (m_pCC->GetTextAttr()) + m_pCC->GetTextAttr()->Invalidate(); + } +} + +OUString SwVbaContentControlListEntry::getValue() +{ + assert(m_nZIndex < m_pCC->GetListItems().size()); + const SwContentControlListItem& rListItem = m_pCC->GetListItems()[m_nZIndex]; + + return rListItem.m_aValue; +} + +void SwVbaContentControlListEntry::setValue(const OUString& rSet) +{ + assert(m_nZIndex < m_pCC->GetListItems().size()); + std::vector<SwContentControlListItem> vListItems = m_pCC->GetListItems(); + + // LO may pull the display text from Value. Ensure changing Value doesn't alter display text. + if (vListItems[m_nZIndex].m_aDisplayText.isEmpty()) + vListItems[m_nZIndex].m_aDisplayText = vListItems[m_nZIndex].ToString(); + + vListItems[m_nZIndex].m_aValue = rSet; + m_pCC->SetListItems(vListItems); +} + +void SwVbaContentControlListEntry::Delete() { m_pCC->DeleteListItem(m_nZIndex); } + +void SwVbaContentControlListEntry::MoveDown() +{ + // if already at last position, can't move down + if (m_nZIndex >= m_pCC->GetListItems().size() - 1) + return; + + const std::optional<size_t> oSelected = m_pCC->GetSelectedListItem(/*bCheckDocModel=*/false); + if (oSelected) + { + if (*oSelected == m_nZIndex) + m_pCC->SetSelectedListItem(m_nZIndex + 1); + else if (*oSelected == m_nZIndex + 1) + m_pCC->SetSelectedListItem(*oSelected - 1); + } + std::vector<SwContentControlListItem> vListItems = m_pCC->GetListItems(); + std::swap(vListItems[m_nZIndex], vListItems[m_nZIndex + 1]); + m_pCC->SetListItems(vListItems); + ++m_nZIndex; +} + +void SwVbaContentControlListEntry::MoveUp() +{ + // if already at position 0, can't move up + if (!m_nZIndex || m_nZIndex >= m_pCC->GetListItems().size()) + return; + + const std::optional<size_t> oSelected = m_pCC->GetSelectedListItem(/*bCheckDocModel=*/false); + if (oSelected) + { + if (*oSelected == m_nZIndex) + m_pCC->SetSelectedListItem(m_nZIndex - 1); + else if (*oSelected == m_nZIndex - 1) + m_pCC->SetSelectedListItem(*oSelected + 1); + } + std::vector<SwContentControlListItem> vListItems = m_pCC->GetListItems(); + std::swap(vListItems[m_nZIndex], vListItems[m_nZIndex - 1]); + m_pCC->SetListItems(vListItems); + --m_nZIndex; +} + +void SwVbaContentControlListEntry::Select() +{ + assert(m_nZIndex < m_pCC->GetListItems().size()); + m_pCC->SetSelectedListItem(m_nZIndex); + m_pCC->SetShowingPlaceHolder(false); + if (m_pCC->GetTextAttr()) + m_pCC->GetTextAttr()->Invalidate(); +} + +// XHelperInterface +OUString SwVbaContentControlListEntry::getServiceImplName() +{ + return "SwVbaContentControlListEntry"; +} + +uno::Sequence<OUString> SwVbaContentControlListEntry::getServiceNames() +{ + static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.ContentControlListEntry" }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacontentcontrollistentry.hxx b/sw/source/ui/vba/vbacontentcontrollistentry.hxx new file mode 100644 index 0000000000..bb55eade34 --- /dev/null +++ b/sw/source/ui/vba/vbacontentcontrollistentry.hxx @@ -0,0 +1,54 @@ +/* -*- 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/. + */ +#pragma once + +#include <ooo/vba/word/XContentControlListEntry.hpp> + +#include <vbahelper/vbahelperinterface.hxx> + +#include <textcontentcontrol.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XContentControlListEntry> + SwVbaContentControlListEntry_BASE; + +class SwVbaContentControlListEntry : public SwVbaContentControlListEntry_BASE +{ +private: + std::shared_ptr<SwContentControl> m_pCC; + // All LO and internal UNO functions are 0-based. Convert to 1-based when sending to VBA + size_t m_nZIndex; + +public: + /// @throws css::uno::RuntimeException + SwVbaContentControlListEntry(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, + std::shared_ptr<SwContentControl> pCC, size_t nZIndex); + ~SwVbaContentControlListEntry() override; + + // XContentControlListEntry + sal_Int32 SAL_CALL getIndex() override; + void SAL_CALL setIndex(sal_Int32 nSet) override; + + OUString SAL_CALL getText() override; + void SAL_CALL setText(const OUString& sSet) override; + + OUString SAL_CALL getValue() override; + void SAL_CALL setValue(const OUString& sSet) override; + + void SAL_CALL Delete() override; + void SAL_CALL MoveDown() override; + void SAL_CALL MoveUp() override; + void SAL_CALL Select() override; + + // XHelperInterface + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacontentcontrols.cxx b/sw/source/ui/vba/vbacontentcontrols.cxx new file mode 100644 index 0000000000..37199e2cec --- /dev/null +++ b/sw/source/ui/vba/vbacontentcontrols.cxx @@ -0,0 +1,268 @@ +/* -*- 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/. + */ + +#include <comphelper/sequence.hxx> +#include <sal/log.hxx> + +#include <doc.hxx> +#include <docsh.hxx> +#include <textcontentcontrol.hxx> + +#include "vbacontentcontrol.hxx" +#include "vbacontentcontrols.hxx" +#include "wordvbahelper.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +// Helper function to access the content controls +// @param rIndex +// [in] negative indexes indicate the need to search by name, otherwise get by index, +// using SAL_MAX_INT32 to indicate the need to just get the total count. +// [out] rIndex indicates the found index, or the total number of content controls +static std::shared_ptr<SwContentControl> +lcl_getContentControl(std::u16string_view sName, std::u16string_view sTag, + std::u16string_view sTitle, sal_Int32& rIndex, + const uno::Reference<text::XTextDocument>& xTextDocument, + uno::Sequence<OUString>* pElementNames = nullptr) +{ + SwDoc* pDoc = word::getDocShell(xTextDocument)->GetDoc(); + if (!pDoc) + return nullptr; + + assert(sTag.empty() || sTitle.empty()); // only one grouping at a time is allowed + + std::shared_ptr<SwContentControl> pControl; + std::vector<OUString> vElementNames; + SwContentControlManager& rManager = pDoc->GetContentControlManager(); + const size_t nLen = rManager.GetCount(); + if (!pElementNames && rIndex > 0 && sName.empty() && sTag.empty() && sTitle.empty()) + { + size_t i = static_cast<size_t>(rIndex); + // This is the normal get-by-index/getCount mode - no need for fancy filtering. + if (i < nLen) + pControl = rManager.Get(i)->GetContentControl().GetContentControl(); + else + rIndex = nLen; + } + else + { + // loop through everything collecting names, filtering by Tag/Title + sal_Int32 nCounter = 0; + for (size_t i = 0; i < nLen; ++i) + { + pControl = rManager.Get(i)->GetContentControl().GetContentControl(); + if (!sTag.empty() && sTag != pControl->GetTag()) + { + pControl = nullptr; + continue; + } + if (!sTitle.empty() && sTitle != pControl->GetAlias()) + { + pControl = nullptr; + continue; + } + + // When treated as a name, consider the integer ID to be unsigned + const OUString sID = OUString::number(static_cast<sal_uInt32>(pControl->GetId())); + if (!sName.empty() && sName != sID) + { + pControl = nullptr; + continue; + } + + if (pElementNames) + vElementNames.push_back(sID); + + if (rIndex == nCounter || !sName.empty()) + break; + + pControl = nullptr; + ++nCounter; + } + rIndex = nCounter; + } + if (pElementNames) + *pElementNames = comphelper::containerToSequence(vElementNames); + return pControl; +} + +namespace +{ +class ContentControlsEnumWrapper : public EnumerationHelper_BASE +{ + uno::Reference<container::XIndexAccess> mxIndexAccess; + sal_Int32 mnIndex; + +public: + explicit ContentControlsEnumWrapper(uno::Reference<container::XIndexAccess> xIndexAccess) + : mxIndexAccess(std::move(xIndexAccess)) + , mnIndex(0) + { + } + + sal_Bool SAL_CALL hasMoreElements() override { return (mnIndex < mxIndexAccess->getCount()); } + + uno::Any SAL_CALL nextElement() override + { + if (mnIndex < mxIndexAccess->getCount()) + { + return mxIndexAccess->getByIndex(mnIndex++); + } + throw container::NoSuchElementException(); + } +}; + +class ContentControlCollectionHelper + : public ::cppu::WeakImplHelper<container::XNameAccess, container::XIndexAccess, + container::XEnumerationAccess> +{ +private: + uno::Reference<XHelperInterface> mxParent; + uno::Reference<uno::XComponentContext> mxContext; + uno::Reference<text::XTextDocument> mxTextDocument; + const OUString m_sTag; + const OUString m_sTitle; + std::shared_ptr<SwContentControl> m_pCache; + +public: + /// @throws css::uno::RuntimeException + ContentControlCollectionHelper(uno::Reference<ov::XHelperInterface> xParent, + uno::Reference<uno::XComponentContext> xContext, + uno::Reference<text::XTextDocument> xTextDocument, + const OUString& rTag, const OUString& rTitle) + + : mxParent(std::move(xParent)) + , mxContext(std::move(xContext)) + , mxTextDocument(std::move(xTextDocument)) + , m_sTag(rTag) + , m_sTitle(rTitle) + { + } + + // XIndexAccess + sal_Int32 SAL_CALL getCount() override + { + sal_Int32 nCount = SAL_MAX_INT32; + lcl_getContentControl(u"", m_sTag, m_sTitle, nCount, mxTextDocument); + return nCount == SAL_MAX_INT32 || nCount < 0 ? 0 : nCount; + } + + uno::Any SAL_CALL getByIndex(sal_Int32 Index) override + { + m_pCache = lcl_getContentControl(u"", m_sTag, m_sTitle, Index, mxTextDocument); + if (!m_pCache) + throw lang::IndexOutOfBoundsException(); + + return uno::Any(uno::Reference<word::XContentControl>( + new SwVbaContentControl(mxParent, mxContext, mxTextDocument, m_pCache))); + } + + // XNameAccess + uno::Sequence<OUString> SAL_CALL getElementNames() override + { + sal_Int32 nCount = SAL_MAX_INT32; + uno::Sequence<OUString> aSeq; + lcl_getContentControl(u"", m_sTag, m_sTitle, nCount, mxTextDocument, &aSeq); + return aSeq; + } + + uno::Any SAL_CALL getByName(const OUString& aName) override + { + if (!hasByName(aName)) + throw container::NoSuchElementException(); + + return uno::Any(uno::Reference<word::XContentControl>( + new SwVbaContentControl(mxParent, mxContext, mxTextDocument, m_pCache))); + } + + sal_Bool SAL_CALL hasByName(const OUString& aName) override + { + sal_Int32 nCount = -1; + m_pCache = lcl_getContentControl(aName, m_sTag, m_sTitle, nCount, mxTextDocument); + return m_pCache != nullptr; + } + + // XElementAccess + uno::Type SAL_CALL getElementType() override + { + return cppu::UnoType<word::XContentControl>::get(); + } + + sal_Bool SAL_CALL hasElements() override { return getCount() != 0; } + + // XEnumerationAccess + uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override + { + return new ContentControlsEnumWrapper(this); + } +}; +} + +/** + * Content Controls can be accessed and filtered in many different ways. + * Surprisingly however, there is no clear, descriptive "by name" access. + * Instead, each content control (probably) has a unique _signed-integer_ identifier, + * which can be passed to Item() as a float or _unsigned-integer_ string + * (to differentiate it from getByIndex). + * + * Index access can be filtered by Tag, Title, Range, and XML link. + * TODO: add filtering for Range, SelectLinkedControls, SelectUnlinkedControls + */ +SwVbaContentControls::SwVbaContentControls(const uno::Reference<XHelperInterface>& xParent, + const uno::Reference<uno::XComponentContext>& xContext, + const uno::Reference<text::XTextDocument>& xTextDocument, + const OUString& rTag, const OUString& rTitle) + : SwVbaContentControls_BASE( + xParent, xContext, + uno::Reference<container::XIndexAccess>( + new ContentControlCollectionHelper(xParent, xContext, xTextDocument, rTag, rTitle))) +{ +} + +// uno::Reference<ooo::vba::word::XContentControl> SwVbaContentControls::Add(const uno::Any& Range, +// sal_Int32 Type) +// { +// sw::mark::IFieldmark* pFieldmark = nullptr; +// switch (Type) +// { +// case ooo::vba::word::WdFieldType::wdFieldFormCheckBox: +// break; +// case ooo::vba::word::WdFieldType::wdFieldFormDropDown: +// break; +// case ooo::vba::word::WdFieldType::wdFieldFormTextInput: +// default:; +// } +// +// return uno::Reference<ooo::vba::word::XContentControl>( +// new SwVbaContentControl(mxParent, mxContext, m_xTextDocument, pFieldmark)); +// } + +// XEnumerationAccess +uno::Type SwVbaContentControls::getElementType() +{ + return cppu::UnoType<word::XContentControl>::get(); +} + +uno::Reference<container::XEnumeration> SwVbaContentControls::createEnumeration() +{ + return new ContentControlsEnumWrapper(m_xIndexAccess); +} + +uno::Any SwVbaContentControls::createCollectionObject(const uno::Any& aSource) { return aSource; } + +OUString SwVbaContentControls::getServiceImplName() { return "SwVbaContentControls"; } + +uno::Sequence<OUString> SwVbaContentControls::getServiceNames() +{ + static uno::Sequence<OUString> const sNames{ "ooo.vba.word.ContentControls" }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacontentcontrols.hxx b/sw/source/ui/vba/vbacontentcontrols.hxx new file mode 100644 index 0000000000..20ff65ae89 --- /dev/null +++ b/sw/source/ui/vba/vbacontentcontrols.hxx @@ -0,0 +1,40 @@ +/* -*- 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/. + */ +#pragma once + +#include <com/sun/star/text/XTextDocument.hpp> +#include <ooo/vba/word/XContentControls.hpp> + +#include <vbahelper/vbacollectionimpl.hxx> + +typedef CollTestImplHelper<ooo::vba::word::XContentControls> SwVbaContentControls_BASE; + +class SwVbaContentControls : public SwVbaContentControls_BASE +{ +public: + /// @throws css::uno::RuntimeException + SwVbaContentControls(const css::uno::Reference<ov::XHelperInterface>& xParent, + const css::uno::Reference<css::uno::XComponentContext>& xContext, + const css::uno::Reference<css::text::XTextDocument>& xTextDocument, + const OUString& rTag, const OUString& rTitle); + + // XContentControls + //css::uno::Reference<ooo::vba::word::XContentControl> SAL_CALL Add(const css::uno::Any& Type, const css::uno::Any& Range) override; + + // XEnumerationAccess + css::uno::Type SAL_CALL getElementType() override; + css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override; + + // SwVbaContentControls_BASE + css::uno::Any createCollectionObject(const css::uno::Any& aSource) override; + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbadialog.cxx b/sw/source/ui/vba/vbadialog.cxx new file mode 100644 index 0000000000..f6af8f113e --- /dev/null +++ b/sw/source/ui/vba/vbadialog.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 "vbadialog.hxx" +#include <ooo/vba/word/WdWordDialog.hpp> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +struct WordDialogTable +{ + sal_Int32 wdDialog; + const char* ooDialog; +}; + +} + +const WordDialogTable aWordDialogTable[] = +{ + { word::WdWordDialog::wdDialogFileNew, ".uno:NewDoc" }, + { word::WdWordDialog::wdDialogFileOpen, ".uno:Open" }, + { word::WdWordDialog::wdDialogFilePrint, ".uno:Print" }, + { word::WdWordDialog::wdDialogFileSaveAs, ".uno:SaveAs" }, + { 0, nullptr } +}; + +OUString +SwVbaDialog::mapIndexToName( sal_Int32 nIndex ) +{ + for (const WordDialogTable & rTable : aWordDialogTable) + { + if( nIndex == rTable.wdDialog ) + { + return OUString::createFromAscii( rTable.ooDialog ); + } + } + return OUString(); +} + +OUString +SwVbaDialog::getServiceImplName() +{ + return "SwVbaDialog"; +} + +uno::Sequence< OUString > +SwVbaDialog::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Dialog" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbadialog.hxx b/sw/source/ui/vba/vbadialog.hxx new file mode 100644 index 0000000000..df4443446f --- /dev/null +++ b/sw/source/ui/vba/vbadialog.hxx @@ -0,0 +1,42 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBADIALOG_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBADIALOG_HXX + +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/word/XDialog.hpp> +#include <vbahelper/vbadialogbase.hxx> + +typedef cppu::ImplInheritanceHelper< VbaDialogBase, ov::word::XDialog > SwVbaDialog_BASE; + +class SwVbaDialog : public SwVbaDialog_BASE +{ +public: + SwVbaDialog( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel, sal_Int32 nIndex ):SwVbaDialog_BASE( xParent, xContext, xModel, nIndex ) {} + + // Methods + virtual OUString mapIndexToName( sal_Int32 nIndex ) override; + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBADIALOG_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbadialogs.cxx b/sw/source/ui/vba/vbadialogs.cxx new file mode 100644 index 0000000000..2b26a4cfaa --- /dev/null +++ b/sw/source/ui/vba/vbadialogs.cxx @@ -0,0 +1,51 @@ +/* -*- 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 <ooo/vba/word/XDialog.hpp> +#include "vbadialogs.hxx" +#include "vbadialog.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +uno::Any +SwVbaDialogs::Item( const uno::Any &aItem ) +{ + sal_Int32 nIndex = 0; + aItem >>= nIndex; + uno::Reference< word::XDialog > aDialog( new SwVbaDialog( uno::Reference< XHelperInterface >( Application(),uno::UNO_QUERY_THROW ), mxContext, m_xModel, nIndex ) ); + return uno::Any( aDialog ); +} + +OUString +SwVbaDialogs::getServiceImplName() +{ + return "SwVbaDialogs"; +} + +uno::Sequence< OUString > +SwVbaDialogs::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Dialogs" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbadialogs.hxx b/sw/source/ui/vba/vbadialogs.hxx new file mode 100644 index 0000000000..3703868f1b --- /dev/null +++ b/sw/source/ui/vba/vbadialogs.hxx @@ -0,0 +1,44 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBADIALOGS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBADIALOGS_HXX + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <ooo/vba/word/XDialogs.hpp> +#include <vbahelper/vbadialogsbase.hxx> +#include <cppuhelper/implbase.hxx> + +typedef cppu::ImplInheritanceHelper< VbaDialogsBase, ov::word::XDialogs > SwVbaDialogs_BASE; + +class SwVbaDialogs : public SwVbaDialogs_BASE +{ +public: + SwVbaDialogs( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::frame::XModel >& xModel ): SwVbaDialogs_BASE( xParent, xContext, xModel ) {} + + // XCollection + virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBADIALOGS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbadocument.cxx b/sw/source/ui/vba/vbadocument.cxx new file mode 100644 index 0000000000..c898546450 --- /dev/null +++ b/sw/source/ui/vba/vbadocument.cxx @@ -0,0 +1,795 @@ +/* -*- 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 <sal/log.hxx> + +#include "vbafilterpropsfromformat.hxx" +#include "vbacontentcontrols.hxx" +#include "vbadocument.hxx" +#include "vbaformfields.hxx" +#include "vbarange.hxx" +#include "vbarangehelper.hxx" +#include "vbadocumentproperties.hxx" +#include "vbabookmarks.hxx" +#include "vbamailmerge.hxx" +#include "vbavariables.hxx" +#include "vbawindow.hxx" +#include <comphelper/processfactory.hxx> +#include <comphelper/propertyvalue.hxx> +#include <cppu/unotype.hxx> + +#include <com/sun/star/text/XBookmarksSupplier.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> +#include <com/sun/star/drawing/XControlShape.hpp> +#include <com/sun/star/form/XFormsSupplier.hpp> +#include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/document/XRedlinesSupplier.hpp> +#include <com/sun/star/util/thePathSettings.hpp> +#include <ooo/vba/XControlProvider.hpp> +#include <ooo/vba/word/WdProtectionType.hpp> +#include <ooo/vba/word/WdSaveFormat.hpp> +#include <ooo/vba/word/XDocumentOutgoing.hpp> + +#include "wordvbahelper.hxx" +#include <doc.hxx> +#include <docsh.hxx> +#include "vbatemplate.hxx" +#include "vbaparagraph.hxx" +#include "vbastyles.hxx" +#include "vbatables.hxx" +#include "vbafield.hxx" +#include "vbapagesetup.hxx" +#include "vbasections.hxx" +#include "vbatablesofcontents.hxx" +#include <vbahelper/vbashapes.hxx> +#include <vbahelper/vbahelper.hxx> +#include "vbarevisions.hxx" +#include "vbaframes.hxx" +#include <basic/sberrors.hxx> +#include <osl/file.hxx> +#include <tools/urlobj.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class SwVbaDocumentOutgoingConnectionPoint : public cppu::WeakImplHelper<XConnectionPoint> +{ +private: + SwVbaDocument* mpDoc; + +public: + SwVbaDocumentOutgoingConnectionPoint( SwVbaDocument* pDoc ); + + // XConnectionPoint + sal_uInt32 SAL_CALL Advise(const uno::Reference< XSink >& Sink ) override; + void SAL_CALL Unadvise( sal_uInt32 Cookie ) override; +}; + +} + +SwVbaDocument::SwVbaDocument( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, uno::Reference< frame::XModel > const & xModel ): SwVbaDocument_BASE( xParent, xContext, xModel ) +{ + Initialize(); +} +SwVbaDocument::SwVbaDocument( uno::Sequence< uno::Any > const& aArgs, uno::Reference< uno::XComponentContext >const& xContext ) : SwVbaDocument_BASE( aArgs, xContext ) +{ + Initialize(); +} + +SwVbaDocument::~SwVbaDocument() +{ +} + +void SwVbaDocument::Initialize() +{ + mxTextDocument.set( getModel(), uno::UNO_QUERY_THROW ); + SwDocShell& rDocSh = *word::getDocShell(mxModel); + rDocSh.RegisterAutomationDocumentObject(this); + rDocSh.GetDoc()->SetVbaEventProcessor(); +} + +sal_uInt32 +SwVbaDocument::AddSink( const uno::Reference< XSink >& xSink ) +{ + word::getDocShell( mxModel )->RegisterAutomationDocumentEventsCaller( uno::Reference< XSinkCaller >(this) ); + mvSinks.push_back(xSink); + return mvSinks.size(); +} + +void +SwVbaDocument::RemoveSink( sal_uInt32 nNumber ) +{ + if (nNumber < 1 || nNumber > mvSinks.size()) + return; + + mvSinks[nNumber-1] = uno::Reference< XSink >(); +} + +uno::Reference< word::XRange > SAL_CALL +SwVbaDocument::getContent() +{ + uno::Reference< text::XTextRange > xStart = mxTextDocument->getText()->getStart(); + uno::Reference< text::XTextRange > xEnd; + return uno::Reference< word::XRange >( new SwVbaRange( this, mxContext, mxTextDocument, xStart, xEnd ) ); +} + +uno::Reference< word::XRange > SAL_CALL +SwVbaDocument::Range( const uno::Any& rStart, const uno::Any& rEnd ) +{ + if( !rStart.hasValue() && !rEnd.hasValue() ) + return getContent(); + + sal_Int32 nStart = 0; + sal_Int32 nEnd = 0; + rStart >>= nStart; + rEnd >>= nEnd; + + uno::Reference< text::XTextRange > xStart; + uno::Reference< text::XTextRange > xEnd; + + if( nStart > nEnd) + throw uno::RuntimeException(); + + if( nEnd != 0) + { + if( nEnd == nStart ) + { + xStart = mxTextDocument->getText()->getEnd(); + xEnd = mxTextDocument->getText()->getEnd(); + } + else + { + xEnd = SwVbaRangeHelper::getRangeByPosition( mxTextDocument->getText(), nEnd ); + + if( nStart != 0 ) + xStart = SwVbaRangeHelper::getRangeByPosition( mxTextDocument->getText(), nStart ); + else + xStart = mxTextDocument->getText()->getStart(); + } + } + else + { + xStart = mxTextDocument->getText()->getEnd(); + xEnd = mxTextDocument->getText()->getEnd(); + } + + if( !xStart.is() && !xEnd.is() ) + { + try + { + // FIXME + xStart = mxTextDocument->getText()->getStart(); + xEnd = mxTextDocument->getText()->getEnd(); + } + catch(const uno::Exception&) + { + DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {}); + } + } + return uno::Reference< word::XRange >( new SwVbaRange( this, mxContext, mxTextDocument, xStart, xEnd ) ); +} + +uno::Any SAL_CALL +SwVbaDocument::BuiltInDocumentProperties( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaBuiltinDocumentProperties( mxParent, mxContext, getModel() ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaDocument::CustomDocumentProperties( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaCustomDocumentProperties( mxParent, mxContext, getModel() ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaDocument::Bookmarks( const uno::Any& rIndex ) +{ + uno::Reference< text::XBookmarksSupplier > xBookmarksSupplier( getModel(),uno::UNO_QUERY_THROW ); + uno::Reference<container::XIndexAccess > xBookmarks( xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY_THROW ); + uno::Reference< XCollection > xBookmarksVba( new SwVbaBookmarks( this, mxContext, xBookmarks, getModel() ) ); + if ( rIndex.getValueTypeClass() == uno::TypeClass_VOID ) + return uno::Any( xBookmarksVba ); + + return xBookmarksVba->Item( rIndex, uno::Any() ); +} + +uno::Any SwVbaDocument::ContentControls(const uno::Any& index) +{ + uno::Reference<XCollection> xContentControls( + new SwVbaContentControls(this, mxContext, mxTextDocument, "", "")); + if (index.hasValue()) + { + try + { + return xContentControls->Item(index, uno::Any()); + } + catch (lang::IndexOutOfBoundsException&) + { + // Hack: Instead of an index, it might be a float that was mistakenly treated as a long, + // which can happen with any valid positive integer when specified as a double like + // ActiveDocument.ContentControls(1841581653#). + if (index.getValueTypeClass() == css::uno::TypeClass_LONG) + { + sal_Int32 nLong(0); + index >>= nLong; + return xContentControls->Item(uno::Any(static_cast<double>(nLong)), uno::Any()); + } + } + } + + return uno::Any(xContentControls); +} + +uno::Any SwVbaDocument::SelectContentControlsByTag(const uno::Any& index) +{ + OUString sTag; + index >>= sTag; + return uno::Any(uno::Reference<XCollection>( + new SwVbaContentControls(this, mxContext, mxTextDocument, sTag, ""))); +} + +uno::Any SwVbaDocument::SelectContentControlsByTitle(const uno::Any& index) +{ + OUString sTitle; + index >>= sTitle; + return uno::Any(uno::Reference<XCollection>( + new SwVbaContentControls(this, mxContext, mxTextDocument, "", sTitle))); +} + +uno::Reference<word::XWindow> SwVbaDocument::getActiveWindow() +{ + // copied from vbaapplication which has a #FIXME so far can't determine Parent + return new SwVbaWindow(uno::Reference< XHelperInterface >(), mxContext, mxModel, + mxModel->getCurrentController()); +} + +uno::Any SAL_CALL +SwVbaDocument::Variables( const uno::Any& rIndex ) +{ + uno::Reference< css::document::XDocumentPropertiesSupplier > xDocumentPropertiesSupplier( getModel(),uno::UNO_QUERY_THROW ); + uno::Reference< css::document::XDocumentProperties > xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties(); + uno::Reference< beans::XPropertyAccess > xUserDefined( xDocumentProperties->getUserDefinedProperties(), uno::UNO_QUERY_THROW ); + + uno::Reference< XCollection > xVariables( new SwVbaVariables( this, mxContext, xUserDefined ) ); + if ( rIndex.getValueTypeClass() == uno::TypeClass_VOID ) + return uno::Any( xVariables ); + + return xVariables->Item( rIndex, uno::Any() ); +} + +uno::Any SAL_CALL +SwVbaDocument::Paragraphs( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaParagraphs( mxParent, mxContext, mxTextDocument ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaDocument::Styles( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaStyles( mxParent, mxContext, getModel() ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaDocument::Fields( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaFields( mxParent, mxContext, getModel() ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaDocument::Shapes( const uno::Any& index ) +{ + uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( getModel(), uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW ); + uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< XCollection > xCol( new ScVbaShapes( this, mxContext, xIndexAccess, xModel ) ); + + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +void SAL_CALL +SwVbaDocument::Select() +{ + auto xRange = getContent(); + if ( xRange ) + xRange->Select(); +} + +uno::Any SAL_CALL +SwVbaDocument::Sections( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaSections( mxParent, mxContext, getModel() ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaDocument::TablesOfContents( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaTablesOfContents( this, mxContext, mxTextDocument ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL SwVbaDocument::FormFields(const uno::Any& index) +{ + uno::Reference<XCollection> xCol(new SwVbaFormFields(this, mxContext, mxTextDocument)); + if (index.hasValue()) + return xCol->Item(index, uno::Any()); + return uno::Any(xCol); +} + +uno::Any SAL_CALL +SwVbaDocument::PageSetup( ) +{ + uno::Reference< beans::XPropertySet > xPageProps( word::getCurrentPageStyle( mxModel ), uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< word::XPageSetup >( new SwVbaPageSetup( this, mxContext, mxModel, xPageProps ) ) ); +} + +OUString +SwVbaDocument::getServiceImplName() +{ + return "SwVbaDocument"; +} + +uno::Any SAL_CALL +SwVbaDocument::getAttachedTemplate() +{ + uno::Reference< word::XTemplate > xTemplate; + uno::Reference<css::document::XDocumentPropertiesSupplier> const xDocPropSupp( + getModel(), uno::UNO_QUERY_THROW); + uno::Reference< css::document::XDocumentProperties > xDocProps( xDocPropSupp->getDocumentProperties(), uno::UNO_SET_THROW ); + OUString sTemplateUrl = xDocProps->getTemplateURL(); + + xTemplate = new SwVbaTemplate( this, mxContext, sTemplateUrl ); + return uno::Any( xTemplate ); +} + +void SAL_CALL +SwVbaDocument::setAttachedTemplate( const css::uno::Any& _attachedtemplate ) +{ + OUString sTemplate; + if( !( _attachedtemplate >>= sTemplate ) ) + { + throw uno::RuntimeException(); + } + OUString aURL; + INetURLObject aObj; + aObj.SetURL( sTemplate ); + bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid; + if ( bIsURL ) + aURL = sTemplate; + else + osl::FileBase::getFileURLFromSystemPath( sTemplate, aURL ); + + uno::Reference<css::document::XDocumentPropertiesSupplier> const xDocPropSupp( + getModel(), uno::UNO_QUERY_THROW ); + uno::Reference< css::document::XDocumentProperties > xDocProps( xDocPropSupp->getDocumentProperties(), uno::UNO_SET_THROW ); + xDocProps->setTemplateURL( aURL ); +} + +uno::Any SAL_CALL +SwVbaDocument::Tables( const css::uno::Any& aIndex ) +{ + uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< XCollection > xColl( new SwVbaTables( mxParent, mxContext, xModel ) ); + + if ( aIndex.hasValue() ) + return xColl->Item( aIndex, uno::Any() ); + return uno::Any( xColl ); +} + +void SAL_CALL SwVbaDocument::Activate() +{ + VbaDocumentBase::Activate(); +} + +::sal_Int32 SAL_CALL SwVbaDocument::getProtectionType() +{ + //TODO + return word::WdProtectionType::wdNoProtection; +} + +void SAL_CALL SwVbaDocument::setProtectionType( ::sal_Int32 /*_protectiontype*/ ) +{ + //TODO +} + +sal_Bool SAL_CALL SwVbaDocument::getUpdateStylesOnOpen() +{ + //TODO + return false; +} + +void SAL_CALL SwVbaDocument::setUpdateStylesOnOpen( sal_Bool /*_updatestylesonopen*/ ) +{ + //TODO +} + +sal_Bool SAL_CALL SwVbaDocument::getAutoHyphenation() +{ + // check this property only in default paragraph style + bool IsAutoHyphenation = false; + uno::Reference< beans::XPropertySet > xParaProps( word::getDefaultParagraphStyle( getModel() ), uno::UNO_QUERY_THROW ); + xParaProps->getPropertyValue("ParaIsHyphenation") >>= IsAutoHyphenation; + return IsAutoHyphenation; +} + +void SAL_CALL SwVbaDocument::setAutoHyphenation( sal_Bool _autohyphenation ) +{ + //TODO + uno::Reference< beans::XPropertySet > xParaProps( word::getDefaultParagraphStyle( getModel() ), uno::UNO_QUERY_THROW ); + xParaProps->setPropertyValue("ParaIsHyphenation", uno::Any( _autohyphenation ) ); +} + +::sal_Int32 SAL_CALL SwVbaDocument::getHyphenationZone() +{ + //TODO + return 0; +} + +void SAL_CALL SwVbaDocument::setHyphenationZone( ::sal_Int32 /*_hyphenationzone*/ ) +{ + //TODO +} + +::sal_Int32 SAL_CALL SwVbaDocument::getConsecutiveHyphensLimit() +{ + //TODO + sal_Int16 nHyphensLimit = 0; + uno::Reference< beans::XPropertySet > xParaProps( word::getDefaultParagraphStyle( getModel() ), uno::UNO_QUERY_THROW ); + xParaProps->getPropertyValue("ParaHyphenationMaxHyphens") >>= nHyphensLimit; + return nHyphensLimit; +} + +void SAL_CALL SwVbaDocument::setConsecutiveHyphensLimit( ::sal_Int32 _consecutivehyphenslimit ) +{ + sal_Int16 nHyphensLimit = static_cast< sal_Int16 >( _consecutivehyphenslimit ); + uno::Reference< beans::XPropertySet > xParaProps( word::getDefaultParagraphStyle( getModel() ), uno::UNO_QUERY_THROW ); + xParaProps->setPropertyValue("ParaHyphenationMaxHyphens", uno::Any( nHyphensLimit ) ); +} + +uno::Reference< ooo::vba::word::XMailMerge > SAL_CALL SwVbaDocument::getMailMerge() +{ + return SwVbaMailMerge::get(mxParent, mxContext); +} + +void SAL_CALL SwVbaDocument::Protect( ::sal_Int32 /*Type*/, const uno::Any& /*NOReset*/, const uno::Any& /*Password*/, const uno::Any& /*UseIRM*/, const uno::Any& /*EnforceStyleLock*/ ) +{ + // Seems not support in Writer + // VbaDocumentBase::Protect( Password ); +} + +void SAL_CALL SwVbaDocument::PrintOut( const uno::Any& /*Background*/, const uno::Any& /*Append*/, const uno::Any& /*Range*/, const uno::Any& /*OutputFileName*/, const uno::Any& /*From*/, const uno::Any& /*To*/, const uno::Any& /*Item*/, const uno::Any& /*Copies*/, const uno::Any& /*Pages*/, const uno::Any& /*PageType*/, const uno::Any& /*PrintToFile*/, const uno::Any& /*Collate*/, const uno::Any& /*FileName*/, const uno::Any& /*ActivePrinterMacGX*/, const uno::Any& /*ManualDuplexPrint*/, const uno::Any& /*PrintZoomColumn*/, const uno::Any& /*PrintZoomRow*/, const uno::Any& /*PrintZoomPaperWidth*/, const uno::Any& /*PrintZoomPaperHeight*/ ) +{ + //TODO +} + +void SAL_CALL SwVbaDocument::PrintPreview( ) +{ + dispatchRequests( mxModel,".uno:PrintPreview" ); +} + +void SAL_CALL SwVbaDocument::ClosePrintPreview( ) +{ + dispatchRequests( mxModel,".uno:ClosePreview" ); +} + +uno::Any SAL_CALL +SwVbaDocument::Revisions( const uno::Any& index ) +{ + uno::Reference< css::document::XRedlinesSupplier > xRedlinesSupp( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xRedlines( xRedlinesSupp->getRedlines(), uno::UNO_QUERY_THROW ); + uno::Reference< XCollection > xCol( new SwVbaRevisions( this, mxContext, getModel(), xRedlines ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaDocument::Frames( const uno::Any& index ) +{ + uno::Reference< text::XTextFramesSupplier > xTextFramesSupp( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xFrames( xTextFramesSupp->getTextFrames(), uno::UNO_QUERY_THROW ); + uno::Reference< XCollection > xCol( new SwVbaFrames( this, mxContext, xFrames, getModel() ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +void SAL_CALL +SwVbaDocument::SaveAs2000( const uno::Any& FileName, const uno::Any& FileFormat, const uno::Any& /*LockComments*/, const uno::Any& /*Password*/, const uno::Any& /*AddToRecentFiles*/, const uno::Any& /*WritePassword*/, const uno::Any& /*ReadOnlyRecommended*/, const uno::Any& /*EmbedTrueTypeFonts*/, const uno::Any& /*SaveNativePictureFormat*/, const uno::Any& /*SaveFormsData*/, const uno::Any& /*SaveAsAOCELetter*/ ) +{ + SAL_INFO("sw.vba", "Document.SaveAs2000(FileName:=" << FileName << ",FileFormat:=" << FileFormat << ")"); + + // Based on ScVbaWorkbook::SaveAs. + OUString sFileName; + FileName >>= sFileName; + OUString sURL; + osl::FileBase::getFileURLFromSystemPath( sFileName, sURL ); + + // Detect if there is no path then we need to use the current folder. + INetURLObject aURL( sURL ); + sURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ); + if( sURL.isEmpty() ) + { + // Need to add cur dir ( of this document ) or else the 'Work' dir + sURL = getModel()->getURL(); + + if ( sURL.isEmpty() ) + { + // Not path available from 'this' document. Need to add the 'document'/work directory then. + // Based on SwVbaOptions::getValueEvent() + uno::Reference< util::XPathSettings > xPathSettings = util::thePathSettings::get( comphelper::getProcessComponentContext() ); + OUString sPathUrl; + xPathSettings->getPropertyValue( "Work" ) >>= sPathUrl; + // Path could be a multipath, Microsoft doesn't support this feature in Word currently. + // Only the last path is from interest. + sal_Int32 nIndex = sPathUrl.lastIndexOf( ';' ); + if( nIndex != -1 ) + { + sPathUrl = sPathUrl.copy( nIndex + 1 ); + } + + aURL.SetURL( sPathUrl ); + } + else + { + aURL.SetURL( sURL ); + aURL.Append( sFileName ); + } + sURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ); + + } + + sal_Int32 nFileFormat = word::WdSaveFormat::wdFormatDocument; + FileFormat >>= nFileFormat; + + uno::Sequence storeProps{ comphelper::makePropertyValue("FilterName", uno::Any()) }; + + setFilterPropsFromFormat( nFileFormat, storeProps ); + + uno::Reference< frame::XStorable > xStor( getModel(), uno::UNO_QUERY_THROW ); + xStor->storeAsURL( sURL, storeProps ); +} + +void SAL_CALL +SwVbaDocument::SaveAs( const uno::Any& FileName, const uno::Any& FileFormat, const uno::Any& LockComments, const uno::Any& Password, const uno::Any& AddToRecentFiles, const uno::Any& WritePassword, const uno::Any& ReadOnlyRecommended, const uno::Any& EmbedTrueTypeFonts, const uno::Any& SaveNativePictureFormat, const uno::Any& SaveFormsData, const uno::Any& SaveAsAOCELetter, const uno::Any& /*Encoding*/, const uno::Any& /*InsertLineBreaks*/, const uno::Any& /*AllowSubstitutions*/, const uno::Any& /*LineEnding*/, const uno::Any& /*AddBiDiMarks*/ ) +{ + return SaveAs2000( FileName, FileFormat, LockComments, Password, AddToRecentFiles, WritePassword, ReadOnlyRecommended, EmbedTrueTypeFonts, SaveNativePictureFormat, SaveFormsData, SaveAsAOCELetter ); +} + +void SAL_CALL +SwVbaDocument::Close( const uno::Any& SaveChanges, const uno::Any& /*OriginalFormat*/, const uno::Any& /*RouteDocument*/ ) +{ + VbaDocumentBase::Close( SaveChanges, uno::Any(), uno::Any() ); +} + +void SAL_CALL +SwVbaDocument::SavePreviewPngAs( const uno::Any& FileName ) +{ + OUString sFileName; + FileName >>= sFileName; + OUString sURL; + osl::FileBase::getFileURLFromSystemPath( sFileName, sURL ); + + uno::Sequence storeProps{ comphelper::makePropertyValue("FilterName", + OUString("writer_png_Export")) }; + + uno::Reference< frame::XStorable > xStor( getModel(), uno::UNO_QUERY_THROW ); + xStor->storeToURL( sURL, storeProps ); +} + +uno::Any +SwVbaDocument::getControlShape( std::u16string_view sName ) +{ + uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW ); + + sal_Int32 nCount = xIndexAccess->getCount(); + for( int index = 0; index < nCount; index++ ) + { + uno::Any aUnoObj = xIndexAccess->getByIndex( index ); + // It seems there are some drawing objects that can not query into Control shapes? + uno::Reference< drawing::XControlShape > xControlShape( aUnoObj, uno::UNO_QUERY ); + if( xControlShape.is() ) + { + uno::Reference< container::XNamed > xNamed( xControlShape->getControl(), uno::UNO_QUERY_THROW ); + if( sName == xNamed->getName() ) + { + return aUnoObj; + } + } + } + return uno::Any(); +} + +uno::Reference< beans::XIntrospectionAccess > SAL_CALL +SwVbaDocument::getIntrospection( ) +{ + return uno::Reference< beans::XIntrospectionAccess >(); +} + +uno::Any SAL_CALL +SwVbaDocument::invoke( const OUString& aFunctionName, const uno::Sequence< uno::Any >& /*aParams*/, uno::Sequence< ::sal_Int16 >& /*aOutParamIndex*/, uno::Sequence< uno::Any >& /*aOutParam*/ ) +{ + SAL_INFO("sw.vba", "** will barf " << aFunctionName ); + throw uno::RuntimeException(); // unsupported operation +} + +void SAL_CALL +SwVbaDocument::setValue( const OUString& /*aPropertyName*/, const uno::Any& /*aValue*/ ) +{ + throw uno::RuntimeException(); // unsupported operation +} +uno::Any SAL_CALL +SwVbaDocument::getValue( const OUString& aPropertyName ) +{ + uno::Reference< drawing::XControlShape > xControlShape( getControlShape( aPropertyName ), uno::UNO_QUERY_THROW ); + + uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< XControlProvider > xControlProvider( xServiceManager->createInstanceWithContext("ooo.vba.ControlProvider", mxContext ), uno::UNO_QUERY_THROW ); + uno::Reference< msforms::XControl > xControl( xControlProvider->createControl( xControlShape, getModel() ) ); + return uno::Any( xControl ); +} + +sal_Bool SAL_CALL +SwVbaDocument::hasMethod( const OUString& /*aName*/ ) +{ + return false; +} + +sal_Bool SAL_CALL +SwVbaDocument::hasProperty( const OUString& aName ) +{ + uno::Reference< container::XNameAccess > xFormControls( getFormControls() ); + if ( xFormControls.is() ) + return xFormControls->hasByName( aName ); + return false; +} + +uno::Reference< container::XNameAccess > +SwVbaDocument::getFormControls() const +{ + uno::Reference< container::XNameAccess > xFormControls; + try + { + uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< form::XFormsSupplier > xFormSupplier( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xIndexAccess( xFormSupplier->getForms(), uno::UNO_QUERY_THROW ); + // get the www-standard container ( maybe we should access the + // 'www-standard' by name rather than index, this seems an + // implementation detail + xFormControls.set( xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW ); + } + catch(const uno::Exception&) + { + } + return xFormControls; +} + +// XInterfaceWithIID + +OUString SAL_CALL +SwVbaDocument::getIID() +{ + return "{82154424-0FBF-11d4-8313-005004526AB4}"; +} + +// XConnectable + +OUString SAL_CALL +SwVbaDocument::GetIIDForClassItselfNotCoclass() +{ + return "{82154428-0FBF-11D4-8313-005004526AB4}"; +} + +TypeAndIID SAL_CALL +SwVbaDocument::GetConnectionPoint() +{ + TypeAndIID aResult = + { cppu::UnoType<word::XDocumentOutgoing>::get(), + "{82154429-0FBF-11D4-8313-005004526AB4}" + }; + + return aResult; +} + +// XSinkCaller + +void SAL_CALL +SwVbaDocument::CallSinks( const OUString& Method, uno::Sequence< uno::Any >& Arguments ) +{ + for (auto& i : mvSinks) + { + if (i.is()) + i->Call(Method, Arguments); + } +} + +uno::Reference<XConnectionPoint> SAL_CALL +SwVbaDocument::FindConnectionPoint() +{ + uno::Reference<XConnectionPoint> xCP(new SwVbaDocumentOutgoingConnectionPoint(this)); + return xCP; +} + +// SwVbaApplicationOutgoingConnectionPoint + +SwVbaDocumentOutgoingConnectionPoint::SwVbaDocumentOutgoingConnectionPoint( SwVbaDocument* pDoc ) : + mpDoc(pDoc) +{ +} + +// XConnectionPoint + +sal_uInt32 SAL_CALL +SwVbaDocumentOutgoingConnectionPoint::Advise( const uno::Reference< XSink >& Sink ) +{ + return mpDoc->AddSink(Sink); +} + +void SAL_CALL +SwVbaDocumentOutgoingConnectionPoint::Unadvise( sal_uInt32 Cookie ) +{ + mpDoc->RemoveSink( Cookie ); +} + +uno::Sequence< OUString > +SwVbaDocument::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Document" + }; + return aServiceNames; +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +Writer_SwVbaDocument_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args) +{ + return cppu::acquire(new SwVbaDocument(args, context)); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbadocument.hxx b/sw/source/ui/vba/vbadocument.hxx new file mode 100644 index 0000000000..069215513c --- /dev/null +++ b/sw/source/ui/vba/vbadocument.hxx @@ -0,0 +1,125 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENT_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENT_HXX + +#include <ooo/vba/XSink.hpp> +#include <ooo/vba/XSinkCaller.hpp> +#include <ooo/vba/word/XDocument.hpp> +#include <vbahelper/vbadocumentbase.hxx> +#include <com/sun/star/text/XTextDocument.hpp> +#include <cppuhelper/implbase.hxx> + +#include <vector> + +typedef cppu::ImplInheritanceHelper< VbaDocumentBase, ooo::vba::word::XDocument, ooo::vba::XSinkCaller > SwVbaDocument_BASE; + +class SwVbaDocument : public SwVbaDocument_BASE +{ +private: + css::uno::Reference< css::text::XTextDocument > mxTextDocument; + + std::vector<css::uno::Reference< ooo::vba::XSink >> mvSinks; + + void Initialize(); + css::uno::Any getControlShape( std::u16string_view sName ); + css::uno::Reference< css::container::XNameAccess > getFormControls() const; + +public: + SwVbaDocument( const css::uno::Reference< ooo::vba::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& m_xContext, css::uno::Reference< css::frame::XModel > const & xModel ); + SwVbaDocument( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext ); + virtual ~SwVbaDocument() override; + + sal_uInt32 AddSink( const css::uno::Reference< ooo::vba::XSink >& xSink ); + void RemoveSink( sal_uInt32 nNumber ); + + // XDocument + virtual css::uno::Reference< ooo::vba::word::XRange > SAL_CALL getContent() override; + virtual css::uno::Reference< ooo::vba::word::XRange > SAL_CALL Range( const css::uno::Any& rStart, const css::uno::Any& rEnd ) override; + virtual css::uno::Any SAL_CALL BuiltInDocumentProperties( const css::uno::Any& index ) override; + virtual css::uno::Any SAL_CALL CustomDocumentProperties( const css::uno::Any& index ) override; + virtual css::uno::Any SAL_CALL Bookmarks( const css::uno::Any& rIndex ) override; + css::uno::Any SAL_CALL ContentControls(const css::uno::Any& index) override; + css::uno::Any SAL_CALL SelectContentControlsByTag(const css::uno::Any& index) override; + css::uno::Any SAL_CALL SelectContentControlsByTitle(const css::uno::Any& index) override; + css::uno::Reference<ov::word::XWindow> SAL_CALL getActiveWindow() override; + virtual css::uno::Any SAL_CALL Variables( const css::uno::Any& rIndex ) override; + virtual css::uno::Any SAL_CALL getAttachedTemplate() override; + virtual void SAL_CALL setAttachedTemplate( const css::uno::Any& _attachedtemplate ) override; + virtual css::uno::Any SAL_CALL Paragraphs( const css::uno::Any& rIndex ) override; + virtual css::uno::Any SAL_CALL Styles( const css::uno::Any& rIndex ) override; + virtual css::uno::Any SAL_CALL Tables( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL Fields( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL Shapes( const css::uno::Any& aIndex ) override; + virtual void SAL_CALL Select() override; + virtual css::uno::Any SAL_CALL Sections( const css::uno::Any& aIndex ) override; + virtual void SAL_CALL Activate() override; + virtual css::uno::Any SAL_CALL PageSetup() override; + virtual css::uno::Any SAL_CALL TablesOfContents( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL FormFields( const css::uno::Any& aIndex ) override; + virtual ::sal_Int32 SAL_CALL getProtectionType() override; + virtual void SAL_CALL setProtectionType( ::sal_Int32 _protectiontype ) override; + virtual sal_Bool SAL_CALL getUpdateStylesOnOpen() override; + virtual void SAL_CALL setUpdateStylesOnOpen( sal_Bool _updatestylesonopen ) override; + virtual sal_Bool SAL_CALL getAutoHyphenation() override; + virtual void SAL_CALL setAutoHyphenation( sal_Bool _autohyphenation ) override; + virtual ::sal_Int32 SAL_CALL getHyphenationZone() override; + virtual void SAL_CALL setHyphenationZone( ::sal_Int32 _hyphenationzone ) override; + virtual ::sal_Int32 SAL_CALL getConsecutiveHyphensLimit() override; + virtual void SAL_CALL setConsecutiveHyphensLimit( ::sal_Int32 _consecutivehyphenslimit ) override; + virtual css::uno::Reference< ooo::vba::word::XMailMerge > SAL_CALL getMailMerge() override; + + using VbaDocumentBase::Protect; + virtual void SAL_CALL Protect( ::sal_Int32 Type, const css::uno::Any& NOReset, const css::uno::Any& Password, const css::uno::Any& UseIRM, const css::uno::Any& EnforceStyleLock ) override; + virtual void SAL_CALL PrintOut( const css::uno::Any& Background, const css::uno::Any& Append, const css::uno::Any& Range, const css::uno::Any& OutputFileName, const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Item, const css::uno::Any& Copies, const css::uno::Any& Pages, const css::uno::Any& PageType, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& FileName, const css::uno::Any& ActivePrinterMacGX, const css::uno::Any& ManualDuplexPrint, const css::uno::Any& PrintZoomColumn, const css::uno::Any& PrintZoomRow, const css::uno::Any& PrintZoomPaperWidth, const css::uno::Any& PrintZoomPaperHeight ) override; + virtual void SAL_CALL PrintPreview( ) override; + virtual void SAL_CALL ClosePrintPreview( ) override; + virtual css::uno::Any SAL_CALL Revisions( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL Frames( const css::uno::Any& aIndex ) override; + virtual void SAL_CALL SaveAs2000( const css::uno::Any& FileName, const css::uno::Any& FileFormat, const css::uno::Any& LockComments, const css::uno::Any& Password, const css::uno::Any& AddToRecentFiles, const css::uno::Any& WritePassword, const css::uno::Any& ReadOnlyRecommended, const css::uno::Any& EmbedTrueTypeFonts, const css::uno::Any& SaveNativePictureFormat, const css::uno::Any& SaveFormsData, const css::uno::Any& SaveAsAOCELetter ) override; + virtual void SAL_CALL SaveAs( const css::uno::Any& FileName, const css::uno::Any& FileFormat, const css::uno::Any& LockComments, const css::uno::Any& Password, const css::uno::Any& AddToRecentFiles, const css::uno::Any& WritePassword, const css::uno::Any& ReadOnlyRecommended, const css::uno::Any& EmbedTrueTypeFonts, const css::uno::Any& SaveNativePictureFormat, const css::uno::Any& SaveFormsData, const css::uno::Any& SaveAsAOCELetter, const css::uno::Any& Encoding, const css::uno::Any& InsertLineBreaks, const css::uno::Any& AllowSubstitutions, const css::uno::Any& LineEnding, const css::uno::Any& AddBiDiMarks ) override; + virtual void SAL_CALL Close( const css::uno::Any& SaveChanges, const css::uno::Any& OriginalFormat, const css::uno::Any& RouteDocument ) override; + virtual void SAL_CALL SavePreviewPngAs( const css::uno::Any& FileName ) override; + + // XInvocation + virtual css::uno::Reference< css::beans::XIntrospectionAccess > SAL_CALL getIntrospection( ) override; + virtual css::uno::Any SAL_CALL invoke( const OUString& aFunctionName, const css::uno::Sequence< css::uno::Any >& aParams, css::uno::Sequence< ::sal_Int16 >& aOutParamIndex, css::uno::Sequence< css::uno::Any >& aOutParam ) override; + virtual void SAL_CALL setValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getValue( const OUString& aPropertyName ) override; + virtual sal_Bool SAL_CALL hasMethod( const OUString& aName ) override; + virtual sal_Bool SAL_CALL hasProperty( const OUString& aName ) override; + + // XInterfaceWithIID + virtual OUString SAL_CALL getIID() override; + + // XConnectable + virtual OUString SAL_CALL GetIIDForClassItselfNotCoclass() override; + virtual ov::TypeAndIID SAL_CALL GetConnectionPoint() override; + virtual css::uno::Reference<ov::XConnectionPoint> SAL_CALL FindConnectionPoint() override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + + // XSinkCaller + virtual void SAL_CALL CallSinks( const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments ) override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbadocumentproperties.cxx b/sw/source/ui/vba/vbadocumentproperties.cxx new file mode 100644 index 0000000000..6d5f06830f --- /dev/null +++ b/sw/source/ui/vba/vbadocumentproperties.cxx @@ -0,0 +1,921 @@ +/* -*- 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 "vbadocumentproperties.hxx" +#include <cppuhelper/implbase.hxx> +#include <sal/log.hxx> +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/beans/XPropertyContainer.hpp> +#include <ooo/vba/word/WdBuiltInProperty.hpp> +#include <ooo/vba/office/MsoDocProperties.hpp> +#include <comphelper/diagnose_ex.hxx> +#include <memory> +#include "wordvbahelper.hxx" +#include <fesh.hxx> +#include <docsh.hxx> +#include <utility> +using namespace ::ooo::vba; +using namespace css; + +/// @throws lang::IllegalArgumentException +static sal_Int8 lcl_toMSOPropType( const uno::Type& aType ) +{ + sal_Int16 msoType = office::MsoDocProperties::msoPropertyTypeString; + + switch ( aType.getTypeClass() ) + { + case uno::TypeClass_BOOLEAN: + msoType = office::MsoDocProperties::msoPropertyTypeBoolean; + break; + case uno::TypeClass_FLOAT: + msoType = office::MsoDocProperties::msoPropertyTypeFloat; + break; + case uno::TypeClass_STRUCT: // Assume date + msoType = office::MsoDocProperties::msoPropertyTypeDate; + break; + case uno::TypeClass_BYTE: + case uno::TypeClass_SHORT: + case uno::TypeClass_LONG: + case uno::TypeClass_HYPER: + msoType = office::MsoDocProperties::msoPropertyTypeNumber; + break; + default: + throw lang::IllegalArgumentException(); + } + return msoType; +} + +namespace { + +class PropertGetSetHelper +{ +protected: + uno::Reference< frame::XModel > m_xModel; + uno::Reference<document::XDocumentProperties> m_xDocProps; +public: + explicit PropertGetSetHelper( uno::Reference< frame::XModel > xModel ):m_xModel(std::move( xModel )) + { + uno::Reference<document::XDocumentPropertiesSupplier> const + xDocPropSupp(m_xModel, uno::UNO_QUERY_THROW); + m_xDocProps.set(xDocPropSupp->getDocumentProperties(), + uno::UNO_SET_THROW); + } + virtual ~PropertGetSetHelper() {} + virtual uno::Any getPropertyValue( const OUString& rPropName ) = 0; + virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) = 0; + uno::Reference< beans::XPropertySet > getUserDefinedProperties() { + return uno::Reference<beans::XPropertySet>( + m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW); + } + +}; + +class BuiltinPropertyGetSetHelper : public PropertGetSetHelper +{ +public: + explicit BuiltinPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :PropertGetSetHelper( xModel ) + { + } + virtual uno::Any getPropertyValue( const OUString& rPropName ) override + { + if ( rPropName == "EditingDuration" ) + { + sal_Int32 const nSecs = m_xDocProps->getEditingDuration(); + return uno::Any( nSecs/60 ); // minutes + } + else if ("Title" == rPropName) + { + return uno::Any(m_xDocProps->getTitle()); + } + else if ("Subject" == rPropName) + { + return uno::Any(m_xDocProps->getSubject()); + } + else if ("Author" == rPropName) + { + return uno::Any(m_xDocProps->getAuthor()); + } + else if ("Keywords" == rPropName) + { + return uno::Any(m_xDocProps->getKeywords()); + } + else if ("Description" == rPropName) + { + return uno::Any(m_xDocProps->getDescription()); + } + else if ("Template" == rPropName) + { + return uno::Any(m_xDocProps->getTemplateName()); + } + else if ("ModifiedBy" == rPropName) + { + return uno::Any(m_xDocProps->getModifiedBy()); + } + else if ("Generator" == rPropName) + { + return uno::Any(m_xDocProps->getGenerator()); + } + else if ("PrintDate" == rPropName) + { + return uno::Any(m_xDocProps->getPrintDate()); + } + else if ("CreationDate" == rPropName) + { + return uno::Any(m_xDocProps->getCreationDate()); + } + else if ("ModifyDate" == rPropName) + { + return uno::Any(m_xDocProps->getModificationDate()); + } + else if ("AutoloadURL" == rPropName) + { + return uno::Any(m_xDocProps->getAutoloadURL()); + } + else + { + // fall back to user-defined properties + return getUserDefinedProperties()->getPropertyValue(rPropName); + } + } + virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) override + { + if ("EditingDuration" == rPropName) + { + sal_Int32 nMins = 0; + if (aValue >>= nMins) + { + m_xDocProps->setEditingDuration(nMins * 60); // convert minutes + } + } + else if ("Title" == rPropName) + { + OUString str; + if (aValue >>= str) + { + m_xDocProps->setTitle(str); + } + } + else if ("Subject" == rPropName) + { + OUString str; + if (aValue >>= str) + { + m_xDocProps->setSubject(str); + } + } + else if ("Author" == rPropName) + { + OUString str; + if (aValue >>= str) + { + m_xDocProps->setAuthor(str); + } + } + else if ("Keywords" == rPropName) + { + uno::Sequence<OUString> keywords; + if (aValue >>= keywords) + { + m_xDocProps->setKeywords(keywords); + } + } + else if ("Description" == rPropName) + { + OUString str; + if (aValue >>= str) + { + m_xDocProps->setDescription(str); + } + } + else if ("Template" == rPropName) + { + OUString str; + if (aValue >>= str) + { + m_xDocProps->setTemplateName(str); + } + } + else if ("ModifiedBy" == rPropName) + { + OUString str; + if (aValue >>= str) + { + m_xDocProps->setModifiedBy(str); + } + } + else if ("Generator" == rPropName) + { + OUString str; + if (aValue >>= str) + { + return m_xDocProps->setGenerator(str); + } + } + else if ("PrintDate" == rPropName) + { + util::DateTime dt; + if (aValue >>= dt) + { + m_xDocProps->setPrintDate(dt); + } + } + else if ("CreationDate" == rPropName) + { + util::DateTime dt; + if (aValue >>= dt) + { + m_xDocProps->setCreationDate(dt); + } + } + else if ("ModifyDate" == rPropName) + { + util::DateTime dt; + if (aValue >>= dt) + { + m_xDocProps->setModificationDate(dt); + } + } + else if ("AutoloadURL" == rPropName) + { + OUString str; + if (aValue >>= str) + { + m_xDocProps->setAutoloadURL(str); + } + } + else + { + // fall back to user-defined properties + getUserDefinedProperties()->setPropertyValue(rPropName, aValue); + } + } +}; + +class CustomPropertyGetSetHelper : public BuiltinPropertyGetSetHelper +{ +public: + explicit CustomPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :BuiltinPropertyGetSetHelper( xModel ) + { + } + virtual uno::Any getPropertyValue( const OUString& rPropName ) override + { + return getUserDefinedProperties()->getPropertyValue(rPropName); + } + virtual void setPropertyValue( + const OUString& rPropName, const uno::Any& rValue) override + { + return getUserDefinedProperties()->setPropertyValue(rPropName, rValue); + } +}; + +class StatisticPropertyGetSetHelper : public PropertGetSetHelper +{ + SwDocShell* mpDocShell; + uno::Reference< beans::XPropertySet > mxModelProps; +public: + explicit StatisticPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :PropertGetSetHelper( xModel ) , mpDocShell( nullptr ) + { + mxModelProps.set( m_xModel, uno::UNO_QUERY_THROW ); + mpDocShell = word::getDocShell( xModel ); + } + virtual uno::Any getPropertyValue( const OUString& rPropName ) override + { + try + { + // Characters, ParagraphCount & WordCount are available from + // the model ( and additionally these also update the statics object ) + return mxModelProps->getPropertyValue( rPropName ); + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("sw.vba", ""); + } + uno::Any aReturn; + if ( rPropName == "LineCount" ) // special processing needed + { + if ( mpDocShell ) + { + if (SwFEShell* pFEShell = mpDocShell->GetFEShell()) + aReturn <<= pFEShell->GetLineCount(); + } + } + else + { + uno::Sequence< beans::NamedValue > const stats( + m_xDocProps->getDocumentStatistics()); + + auto pStat = std::find_if(stats.begin(), stats.end(), + [&rPropName](const beans::NamedValue& rStat) { return rPropName == rStat.Name; }); + if (pStat == stats.end()) + throw uno::RuntimeException(); // bad Property + + aReturn = pStat->Value; + } + return aReturn; + } + + virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) override + { + uno::Sequence< beans::NamedValue > stats( + m_xDocProps->getDocumentStatistics()); + + auto [begin, end] = asNonConstRange(stats); + auto pStat = std::find_if(begin, end, + [&rPropName](const beans::NamedValue& rStat) { return rPropName == rStat.Name; }); + if (pStat != end) + { + pStat->Value = aValue; + m_xDocProps->setDocumentStatistics(stats); + } + } +}; + +class DocPropInfo +{ +public: + OUString msMSODesc; + OUString msOOOPropName; + std::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper; + + static DocPropInfo createDocPropInfo( const OUString& sDesc, const OUString& sPropName, std::shared_ptr< PropertGetSetHelper > const & rHelper ) + { + DocPropInfo aItem; + aItem.msMSODesc = sDesc; + aItem.msOOOPropName = sPropName; + aItem.mpPropGetSetHelper = rHelper; + return aItem; + } + + static DocPropInfo createDocPropInfo( const char* sDesc, const char* sPropName, std::shared_ptr< PropertGetSetHelper > const & rHelper ) + { + return createDocPropInfo( OUString::createFromAscii( sDesc ), OUString::createFromAscii( sPropName ), rHelper ); + } + uno::Any getValue() + { + if ( mpPropGetSetHelper ) + return mpPropGetSetHelper->getPropertyValue( msOOOPropName ); + return uno::Any(); + } + void setValue( const uno::Any& rValue ) + { + if ( mpPropGetSetHelper ) + mpPropGetSetHelper->setPropertyValue( msOOOPropName, rValue ); + } + uno::Reference< beans::XPropertySet > getUserDefinedProperties() + { + uno::Reference< beans::XPropertySet > xProps; + if ( mpPropGetSetHelper ) + return mpPropGetSetHelper->getUserDefinedProperties(); + return xProps; + } +}; + +} + +typedef std::unordered_map< sal_Int32, DocPropInfo > MSOIndexToOODocPropInfo; + +namespace { + +class BuiltInIndexHelper +{ + MSOIndexToOODocPropInfo m_docPropInfoMap; + +public: + explicit BuiltInIndexHelper( const uno::Reference< frame::XModel >& xModel ) + { + auto aStandardHelper = std::make_shared<BuiltinPropertyGetSetHelper>( xModel ); + auto aUsingStatsHelper = std::make_shared<StatisticPropertyGetSetHelper>( xModel ); + + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTitle ] = DocPropInfo::createDocPropInfo( "Title", "Title", aStandardHelper ); + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySubject ] = DocPropInfo::createDocPropInfo( "Subject", "Subject", aStandardHelper ); + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAuthor ] = DocPropInfo::createDocPropInfo( "Author", "Author", aStandardHelper ); + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyKeywords ] = DocPropInfo::createDocPropInfo( "Keywords", "Keywords", aStandardHelper ); + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyComments ] = DocPropInfo::createDocPropInfo( "Comments", "Description", aStandardHelper ); + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTemplate ] = DocPropInfo::createDocPropInfo( "Template", "Template", aStandardHelper ); + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLastAuthor ] = DocPropInfo::createDocPropInfo( "Last author", "ModifiedBy", aStandardHelper ); // doesn't seem to exist - throw or return nothing ? + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyRevision ] = DocPropInfo::createDocPropInfo( "Revision number", "EditingCycles", aStandardHelper ); // doesn't seem to exist - throw or return nothing ? + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAppName ] = DocPropInfo::createDocPropInfo( "Application name", "Generator", aStandardHelper ); // doesn't seem to exist - throw or return nothing ? + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastPrinted ] = DocPropInfo::createDocPropInfo( "Last print date", "PrintDate", aStandardHelper ); // doesn't seem to exist - throw or return nothing ? + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeCreated ] = DocPropInfo::createDocPropInfo( "Creation date", "CreationDate", aStandardHelper ); + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastSaved ] = DocPropInfo::createDocPropInfo( "Last save time", "ModifyDate", aStandardHelper ); + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyVBATotalEdit ] = DocPropInfo::createDocPropInfo( "Total editing time", "EditingDuration", aStandardHelper ); // Not sure if this is correct + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyPages ] = DocPropInfo::createDocPropInfo( "Number of pages", "PageCount", aUsingStatsHelper ); // special handling required ? + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyWords ] = DocPropInfo::createDocPropInfo( "Number of words", "WordCount", aUsingStatsHelper ); // special handling require ? + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharacters ] = DocPropInfo::createDocPropInfo( "Number of characters", "CharacterCount", aUsingStatsHelper ); // special handling required ? + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySecurity ] = DocPropInfo::createDocPropInfo( "Security", "", aStandardHelper ); // doesn't seem to exist + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCategory ] = DocPropInfo::createDocPropInfo( "Category", "Category", aStandardHelper ); // hacked in + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyFormat ] = DocPropInfo::createDocPropInfo( "Format", "", aStandardHelper ); // doesn't seem to exist + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyManager ] = DocPropInfo::createDocPropInfo( "Manager", "Manager", aStandardHelper ); // hacked in + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCompany ] = DocPropInfo::createDocPropInfo( "Company", "Company", aStandardHelper ); // hacked in + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyBytes ] = DocPropInfo::createDocPropInfo( "Number of bytes", "", aStandardHelper ); // doesn't seem to exist - size on disk exists ( for an already saved document ) perhaps it will do ( or we need something else ) + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLines ] = DocPropInfo::createDocPropInfo( "Number of lines", "LineCount", aUsingStatsHelper ); // special handling + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyParas ] = DocPropInfo::createDocPropInfo( "Number of paragraphs", "ParagraphCount", aUsingStatsHelper ); // special handling + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySlides ] = DocPropInfo::createDocPropInfo( "Number of slides", "" , aStandardHelper ); // doesn't seem to exist + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyNotes ] = DocPropInfo::createDocPropInfo( "Number of notes", "", aStandardHelper ); // doesn't seem to exist + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHiddenSlides ] = DocPropInfo::createDocPropInfo("Number of hidden Slides", "", aStandardHelper ); // doesn't seem to exist + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyMMClips ] = DocPropInfo::createDocPropInfo( "Number of multimedia clips", "", aStandardHelper ); // doesn't seem to exist + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHyperlinkBase ] = DocPropInfo::createDocPropInfo( "Hyperlink base", "AutoloadURL", aStandardHelper ); + m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharsWSpaces ] = DocPropInfo::createDocPropInfo( "Number of characters (with spaces)", "", aStandardHelper ); // doesn't seem to be supported + } + + MSOIndexToOODocPropInfo& getDocPropInfoMap() { return m_docPropInfoMap; } +}; + +} + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::XDocumentProperty > SwVbaDocumentProperty_BASE; + +namespace { + +class SwVbaBuiltInDocumentProperty : public SwVbaDocumentProperty_BASE +{ +protected: + DocPropInfo mPropInfo; +public: + SwVbaBuiltInDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, DocPropInfo rInfo ); + // XDocumentProperty + virtual void SAL_CALL Delete( ) override; + virtual OUString SAL_CALL getName( ) override; + virtual void SAL_CALL setName( const OUString& Name ) override; + virtual ::sal_Int8 SAL_CALL getType( ) override; + virtual void SAL_CALL setType( ::sal_Int8 Type ) override; + virtual sal_Bool SAL_CALL getLinkToContent( ) override; + virtual void SAL_CALL setLinkToContent( sal_Bool LinkToContent ) override; + virtual uno::Any SAL_CALL getValue( ) override; + virtual void SAL_CALL setValue( const uno::Any& Value ) override; + virtual OUString SAL_CALL getLinkSource( ) override; + virtual void SAL_CALL setLinkSource( const OUString& LinkSource ) override; + //XDefaultProperty + virtual OUString SAL_CALL getDefaultPropertyName( ) override { return "Value"; } + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual uno::Sequence<OUString> getServiceNames() override; +}; + +class SwVbaCustomDocumentProperty : public SwVbaBuiltInDocumentProperty +{ +public: + + SwVbaCustomDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo ); + + virtual sal_Bool SAL_CALL getLinkToContent( ) override; + virtual void SAL_CALL setLinkToContent( sal_Bool LinkToContent ) override; + + virtual OUString SAL_CALL getLinkSource( ) override; + virtual void SAL_CALL setLinkSource( const OUString& LinkSource ) override; + virtual void SAL_CALL Delete( ) override; + virtual void SAL_CALL setName( const OUString& Name ) override; + virtual void SAL_CALL setType( ::sal_Int8 Type ) override; + +}; + +} + +SwVbaCustomDocumentProperty::SwVbaCustomDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo ) : SwVbaBuiltInDocumentProperty( xParent, xContext, rInfo ) +{ +} + +sal_Bool +SwVbaCustomDocumentProperty::getLinkToContent( ) +{ + // #FIXME we need to store the link content somewhere + return false; +} + +void +SwVbaCustomDocumentProperty::setLinkToContent( sal_Bool /*bLinkContent*/ ) +{ +} + +OUString +SwVbaCustomDocumentProperty::getLinkSource( ) +{ + // #FIXME we need to store the link content somewhere + return OUString(); +} + +void +SwVbaCustomDocumentProperty::setLinkSource( const OUString& /*rsLinkContent*/ ) +{ + // #FIXME we need to store the link source somewhere +} + +void SAL_CALL +SwVbaCustomDocumentProperty::setName( const OUString& /*Name*/ ) +{ + // setName on existing property ? + // #FIXME + // do we need to delete existing property and create a new one? +} + +void SAL_CALL +SwVbaCustomDocumentProperty::setType( ::sal_Int8 /*Type*/ ) +{ + // setType, do we need to do a conversion? + // #FIXME the underlying value needs to be changed to the new type +} + +void SAL_CALL +SwVbaCustomDocumentProperty::Delete( ) +{ + uno::Reference< beans::XPropertyContainer > xContainer( + mPropInfo.getUserDefinedProperties(), uno::UNO_QUERY_THROW); + xContainer->removeProperty( getName() ); +} + +SwVbaBuiltInDocumentProperty::SwVbaBuiltInDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, DocPropInfo rInfo ) : SwVbaDocumentProperty_BASE( xParent, xContext ), mPropInfo(std::move( rInfo )) +{ +} + +void SAL_CALL +SwVbaBuiltInDocumentProperty::Delete( ) +{ + // not valid for Builtin + throw uno::RuntimeException(); +} + +OUString SAL_CALL +SwVbaBuiltInDocumentProperty::getName( ) +{ + return mPropInfo.msMSODesc; +} + +void SAL_CALL +SwVbaBuiltInDocumentProperty::setName( const OUString& ) +{ + // not valid for Builtin + throw uno::RuntimeException(); +} + +::sal_Int8 SAL_CALL +SwVbaBuiltInDocumentProperty::getType( ) +{ + return lcl_toMSOPropType( getValue().getValueType() ); +} + +void SAL_CALL +SwVbaBuiltInDocumentProperty::setType( ::sal_Int8 /*Type*/ ) +{ + // not valid for Builtin + throw uno::RuntimeException(); +} + +sal_Bool SAL_CALL +SwVbaBuiltInDocumentProperty::getLinkToContent( ) +{ + return false; // built-in always false +} + +void SAL_CALL +SwVbaBuiltInDocumentProperty::setLinkToContent( sal_Bool /*LinkToContent*/ ) +{ + // not valid for Builtin + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +SwVbaBuiltInDocumentProperty::getValue( ) +{ + uno::Any aRet = mPropInfo.getValue(); + if ( !aRet.hasValue() ) + throw uno::RuntimeException(); + return aRet; +} + +void SAL_CALL +SwVbaBuiltInDocumentProperty::setValue( const uno::Any& Value ) +{ + mPropInfo.setValue( Value ); +} + +OUString SAL_CALL +SwVbaBuiltInDocumentProperty::getLinkSource( ) +{ + // not valid for Builtin + throw uno::RuntimeException(); +} + +void SAL_CALL +SwVbaBuiltInDocumentProperty::setLinkSource( const OUString& /*LinkSource*/ ) +{ + // not valid for Builtin + throw uno::RuntimeException(); +} + +OUString +SwVbaBuiltInDocumentProperty::getServiceImplName() +{ + return "SwVbaBuiltinDocumentProperty"; +} + +uno::Sequence<OUString> +SwVbaBuiltInDocumentProperty::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.DocumentProperty" + }; + return aServiceNames; +} +typedef ::cppu::WeakImplHelper< css::container::XIndexAccess + ,css::container::XNameAccess + ,css::container::XEnumerationAccess + > PropertiesImpl_BASE; + +typedef std::unordered_map< sal_Int32, uno::Reference< XDocumentProperty > > DocProps; + +namespace { + +class DocPropEnumeration : public ::cppu::WeakImplHelper< css::container::XEnumeration > +{ + DocProps mDocProps; + DocProps::iterator mIt; +public: + + explicit DocPropEnumeration( DocProps&& rProps ) : mDocProps( std::move(rProps) ), mIt( mDocProps.begin() ) {} + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return mIt != mDocProps.end(); + } + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( !hasMoreElements() ) + throw container::NoSuchElementException(); + return uno::Any( mIt++->second ); + } +}; + +} + +typedef std::unordered_map< OUString, uno::Reference< XDocumentProperty > > DocPropsByName; + +namespace { + +class BuiltInPropertiesImpl : public PropertiesImpl_BASE +{ +protected: + + uno::Reference< frame::XModel > m_xModel; + + DocProps mDocProps; + DocPropsByName mNamedDocProps; + + public: + BuiltInPropertiesImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, uno::Reference< frame::XModel > xModel ) : m_xModel(std::move( xModel )) + { + BuiltInIndexHelper builtIns( m_xModel ); + for ( sal_Int32 index = word::WdBuiltInProperty::wdPropertyTitle; index <= word::WdBuiltInProperty::wdPropertyCharsWSpaces; ++index ) + { + mDocProps[ index ] = new SwVbaBuiltInDocumentProperty( xParent, xContext, builtIns.getDocPropInfoMap()[ index ] ); + mNamedDocProps[ mDocProps[ index ]->getName() ] = mDocProps[ index ]; + } + } +// XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override + { + return mDocProps.size(); + } + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override + { + // correct the correct by the base class for 1 based indices + DocProps::iterator it = mDocProps.find( ++Index ); + if ( it == mDocProps.end() ) + throw lang::IndexOutOfBoundsException(); + return uno::Any( it->second ); + } + virtual uno::Any SAL_CALL getByName( const OUString& aName ) override + { + if ( !hasByName( aName ) ) + throw container::NoSuchElementException(); + DocPropsByName::iterator it = mNamedDocProps.find( aName ); + return uno::Any( it->second ); + + } + virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override + { + uno::Sequence< OUString > aNames( getCount() ); + OUString* pName = aNames.getArray(); + for (const auto& rEntry : mNamedDocProps) + { + *pName = rEntry.first; + ++pName; + } + return aNames; + } + + virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override + { + DocPropsByName::iterator it = mNamedDocProps.find( aName ); + if ( it == mNamedDocProps.end() ) + return false; + return true; + } +// XElementAccess + virtual uno::Type SAL_CALL getElementType( ) override + { + return cppu::UnoType<XDocumentProperty>::get(); + } + virtual sal_Bool SAL_CALL hasElements( ) override + { + return !mDocProps.empty(); + } + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override + { + return new DocPropEnumeration( std::unordered_map(mDocProps) ); + } +}; + +} + +SwVbaBuiltinDocumentProperties::SwVbaBuiltinDocumentProperties( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : SwVbaDocumentproperties_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new BuiltInPropertiesImpl( xParent, xContext, xModel ) ) ) +{ +} + +uno::Reference< XDocumentProperty > SAL_CALL +SwVbaBuiltinDocumentProperties::Add( const OUString& /*Name*/, sal_Bool /*LinkToContent*/, ::sal_Int8 /*Type*/, const uno::Any& /*value*/, const uno::Any& /*LinkSource*/ ) +{ + throw uno::RuntimeException( "not supported for Builtin properties" ); +} + +// XEnumerationAccess +uno::Type SAL_CALL +SwVbaBuiltinDocumentProperties::getElementType() +{ + return cppu::UnoType<XDocumentProperty>::get(); +} + +uno::Reference< container::XEnumeration > SAL_CALL +SwVbaBuiltinDocumentProperties::createEnumeration() +{ + uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); + return xEnumAccess->createEnumeration(); +} + +// ScVbaCollectionBaseImpl +uno::Any +SwVbaBuiltinDocumentProperties::createCollectionObject( const uno::Any& aSource ) +{ + // pass through + return aSource; +} + +// XHelperInterface +OUString +SwVbaBuiltinDocumentProperties::getServiceImplName() +{ + return "SwVbaBuiltinDocumentProperties"; +} + +uno::Sequence<OUString> +SwVbaBuiltinDocumentProperties::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.DocumentProperties" + }; + return aServiceNames; +} + +namespace { + +class CustomPropertiesImpl : public PropertiesImpl_BASE +{ + uno::Reference< XHelperInterface > m_xParent; + uno::Reference< uno::XComponentContext > m_xContext; + uno::Reference< frame::XModel > m_xModel; + uno::Reference< beans::XPropertySet > mxUserDefinedProp; + std::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper; +public: + CustomPropertiesImpl( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel ) : m_xParent(std::move( xParent )), m_xContext(std::move( xContext )), m_xModel(std::move( xModel )) + { + // suck in the document( custom ) properties + mpPropGetSetHelper = std::make_shared<CustomPropertyGetSetHelper>( m_xModel ); + mxUserDefinedProp.set(mpPropGetSetHelper->getUserDefinedProperties(), + uno::UNO_SET_THROW); + }; + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override + { + return mxUserDefinedProp->getPropertySetInfo()->getProperties().getLength(); + } + + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override + { + uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties(); + if ( Index >= aProps.getLength() ) + throw lang::IndexOutOfBoundsException(); + // How to determine type e.g Date? ( com.sun.star.util.DateTime ) + DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aProps[ Index ].Name, aProps[ Index ].Name, mpPropGetSetHelper ); + return uno::Any( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) ); + } + + virtual uno::Any SAL_CALL getByName( const OUString& aName ) override + { + if ( !hasByName( aName ) ) + throw container::NoSuchElementException(); + + DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aName, aName, mpPropGetSetHelper ); + return uno::Any( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) ); + } + + virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override + { + const uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties(); + uno::Sequence< OUString > aNames( aProps.getLength() ); + std::transform(aProps.begin(), aProps.end(), aNames.getArray(), + [](const beans::Property& rProp) -> OUString { return rProp.Name; }); + return aNames; + } + + virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override + { + SAL_INFO("sw.vba", "hasByName(" << aName << ") returns " << mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName ) ); + return mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName ); + } + + // XElementAccess + virtual uno::Type SAL_CALL getElementType( ) override + { + return cppu::UnoType<XDocumentProperty>::get(); + } + + virtual sal_Bool SAL_CALL hasElements( ) override + { + return getCount() > 0; + } + + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override + { + // create a map of properties ( the key doesn't matter ) + SAL_INFO("sw.vba", "Creating an enumeration"); + sal_Int32 key = 0; + sal_Int32 nElem = getCount(); + DocProps simpleDocPropSnapShot; + for ( ; key < nElem; ++key ) + simpleDocPropSnapShot[ key ].set( getByIndex( key ), uno::UNO_QUERY_THROW ); + SAL_INFO("sw.vba", "After creating the enumeration"); + return new DocPropEnumeration( std::move(simpleDocPropSnapShot) ); + } + + void addProp( const OUString& Name, const uno::Any& Value ) + { + uno::Reference< beans::XPropertyContainer > xContainer( mxUserDefinedProp, uno::UNO_QUERY_THROW ); + // TODO fixme, perform the necessary Type Value conversions + xContainer->addProperty( Name, sal_Int16(128), Value ); + } + +}; + +} + +SwVbaCustomDocumentProperties::SwVbaCustomDocumentProperties( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : SwVbaBuiltinDocumentProperties( xParent, xContext, xModel ) +{ + // replace the m_xIndexAccess implementation ( we need a virtual init ) + m_xIndexAccess.set( new CustomPropertiesImpl( xParent, xContext, xModel ) ); + m_xNameAccess.set( m_xIndexAccess, uno::UNO_QUERY_THROW ); +} + +uno::Reference< XDocumentProperty > SAL_CALL +SwVbaCustomDocumentProperties::Add( const OUString& Name, sal_Bool LinkToContent, ::sal_Int8 /*Type*/, const uno::Any& Value, const uno::Any& LinkSource ) +{ + CustomPropertiesImpl* pCustomProps = dynamic_cast< CustomPropertiesImpl* > ( m_xIndexAccess.get() ); + uno::Reference< XDocumentProperty > xDocProp; + if ( pCustomProps ) + { + OUString sLinkSource; + pCustomProps->addProp( Name, Value ); + + xDocProp.set( m_xNameAccess->getByName( Name ), uno::UNO_QUERY_THROW ); + xDocProp->setLinkToContent( LinkToContent ); + + if ( LinkSource >>= sLinkSource ) + xDocProp->setLinkSource( sLinkSource ); + } + return xDocProp; +} + +// XHelperInterface +OUString +SwVbaCustomDocumentProperties::getServiceImplName() +{ + return "SwVbaCustomDocumentProperties"; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbadocumentproperties.hxx b/sw/source/ui/vba/vbadocumentproperties.hxx new file mode 100644 index 0000000000..740353e829 --- /dev/null +++ b/sw/source/ui/vba/vbadocumentproperties.hxx @@ -0,0 +1,58 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENTPROPERTIES_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENTPROPERTIES_HXX + +#include <ooo/vba/XDocumentProperties.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <vbahelper/vbacollectionimpl.hxx> + +typedef CollTestImplHelper< ov::XDocumentProperties > SwVbaDocumentproperties_BASE; + +class SwVbaBuiltinDocumentProperties : public SwVbaDocumentproperties_BASE +{ +public: + SwVbaBuiltinDocumentProperties( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xDocument ); + + // XDocumentProperties + virtual css::uno::Reference< ::ooo::vba::XDocumentProperty > SAL_CALL Add( const OUString& Name, sal_Bool LinkToContent, ::sal_Int8 Type, const css::uno::Any& Value, const css::uno::Any& LinkSource ) override; + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + // ScVbaCollectionBaseImpl + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +class SwVbaCustomDocumentProperties : public SwVbaBuiltinDocumentProperties +{ +public: + SwVbaCustomDocumentProperties( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xDocument ); +// XDocumentProperties + virtual css::uno::Reference< ::ooo::vba::XDocumentProperty > SAL_CALL Add( const OUString& Name, sal_Bool LinkToContent, ::sal_Int8 Type, const css::uno::Any& Value, const css::uno::Any& LinkSource ) override; + // XHelperInterface + virtual OUString getServiceImplName() override; +}; + +#endif /* SW_VBA_DOCUMENTPROPERTY_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbadocuments.cxx b/sw/source/ui/vba/vbadocuments.cxx new file mode 100644 index 0000000000..ca5f298555 --- /dev/null +++ b/sw/source/ui/vba/vbadocuments.cxx @@ -0,0 +1,161 @@ +/* -*- 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/text/XTextDocument.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> + +#include <tools/urlobj.hxx> +#include <rtl/ref.hxx> + +#include "vbadocument.hxx" +#include "vbadocuments.hxx" + +#include <osl/file.hxx> +#include <utility> +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +static uno::Any +getDocument( uno::Reference< uno::XComponentContext > const & xContext, const uno::Reference< text::XTextDocument > &xDoc, const uno::Any& aApplication ) +{ + // FIXME: fine as long as SwVbaDocument is stateless ... + if( !xDoc.is() ) + return uno::Any(); + + rtl::Reference<SwVbaDocument> pWb = new SwVbaDocument( uno::Reference< XHelperInterface >( aApplication, uno::UNO_QUERY_THROW ), xContext, xDoc ); + return uno::Any( uno::Reference< word::XDocument > (pWb) ); +} + +namespace { + +class DocumentEnumImpl : public EnumerationHelperImpl +{ + uno::Any m_aApplication; +public: + /// @throws uno::RuntimeException + DocumentEnumImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, uno::Any aApplication ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_aApplication(std::move( aApplication )) {} + + virtual uno::Any SAL_CALL nextElement( ) override + { + uno::Reference< text::XTextDocument > xDoc( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); + return getDocument( m_xContext, xDoc, m_aApplication ); + } +}; + +} + +SwVbaDocuments::SwVbaDocuments( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : SwVbaDocuments_BASE( xParent, xContext, VbaDocumentsBase::WORD_DOCUMENT ) +{ +} +// XEnumerationAccess +uno::Type +SwVbaDocuments::getElementType() +{ + return cppu::UnoType<word::XDocument>::get(); +} +uno::Reference< container::XEnumeration > +SwVbaDocuments::createEnumeration() +{ + // #FIXME it's possible the DocumentEnumImpl here doesn't reflect + // the state of this object (although it should) would be + // safer to create an enumeration based on this objects state + // rather than one effectively based of the desktop component + uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); + return new DocumentEnumImpl( mxParent, mxContext, xEnumerationAccess->createEnumeration(), Application() ); +} + +uno::Any +SwVbaDocuments::createCollectionObject( const uno::Any& aSource ) +{ + uno::Reference< text::XTextDocument > xDoc( aSource, uno::UNO_QUERY_THROW ); + return getDocument( mxContext, xDoc, Application() ); +} + +uno::Any SAL_CALL +SwVbaDocuments::Add( const uno::Any& Template, const uno::Any& /*NewTemplate*/, const uno::Any& /*DocumentType*/, const uno::Any& /*Visible*/ ) +{ + OUString sFileName; + if( Template.hasValue() && ( Template >>= sFileName ) ) + { + return Open( sFileName, uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any()); + } + uno::Reference <text::XTextDocument> xTextDoc( createDocument() , uno::UNO_QUERY_THROW ); + return getDocument( mxContext, xTextDoc, Application() ); +} + +// #TODO# #FIXME# can any of the unused params below be used? +// #TODO# #FIXME# surely we should actually close the document here +void SAL_CALL +SwVbaDocuments::Close( const uno::Any& /*SaveChanges*/, const uno::Any& /*OriginalFormat*/, const uno::Any& /*RouteDocument*/ ) +{ +} + +// #TODO# #FIXME# can any of the unused params below be used? +uno::Any SAL_CALL +SwVbaDocuments::Open( const OUString& Filename, const uno::Any& /*ConfirmConversions*/, const uno::Any& ReadOnly, const uno::Any& /*AddToRecentFiles*/, const uno::Any& /*PasswordDocument*/, const uno::Any& /*PasswordTemplate*/, const uno::Any& /*Revert*/, const uno::Any& /*WritePasswordDocument*/, const uno::Any& /*WritePasswordTemplate*/, const uno::Any& /*Format*/, const uno::Any& /*Encoding*/, const uno::Any& /*Visible*/, const uno::Any& /*OpenAndRepair*/, const uno::Any& /*DocumentDirection*/, const uno::Any& /*NoEncodingDialog*/, const uno::Any& /*XMLTransform*/ ) +{ + SAL_INFO("sw.vba", "Documents.Open(Filename:=" << Filename << ",ReadOnly:=" << ReadOnly << ")"); + + // we need to detect if this is a URL, if not then assume it's a file path + OUString aURL; + INetURLObject aObj; + aObj.SetURL( Filename ); + bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid; + if ( bIsURL ) + aURL = Filename; + else + osl::FileBase::getFileURLFromSystemPath( Filename, aURL ); + + uno::Reference <text::XTextDocument> xSpreadDoc( openDocument( Filename, ReadOnly, {}), uno::UNO_QUERY_THROW ); + uno::Any aRet = getDocument( mxContext, xSpreadDoc, Application() ); + uno::Reference< word::XDocument > xDocument( aRet, uno::UNO_QUERY ); + if ( xDocument.is() ) + xDocument->Activate(); + return aRet; +} + +uno::Any SAL_CALL +SwVbaDocuments::OpenNoRepairDialog( const OUString& Filename, const uno::Any& ConfirmConversions, const uno::Any& ReadOnly, const uno::Any& AddToRecentFiles, const uno::Any& PasswordDocument, const uno::Any& PasswordTemplate, const uno::Any& Revert, const uno::Any& WritePasswordDocument, const uno::Any& WritePasswordTemplate, const uno::Any& Format, const uno::Any& Encoding, const uno::Any& Visible, const uno::Any& OpenAndRepair, const uno::Any& DocumentDirection, const uno::Any& NoEncodingDialog, const uno::Any& XMLTransform ) +{ + return Open( Filename, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, Encoding, Visible, OpenAndRepair, DocumentDirection, NoEncodingDialog, XMLTransform ); +} + +uno::Any SAL_CALL +SwVbaDocuments::OpenOld( const OUString& FileName, const uno::Any& ConfirmConversions, const uno::Any& ReadOnly, const uno::Any& AddToRecentFiles, const uno::Any& PasswordDocument, const uno::Any& PasswordTemplate, const uno::Any& Revert, const uno::Any& WritePasswordDocument, const uno::Any& WritePasswordTemplate, const uno::Any& Format ) +{ + return Open( FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any() ); +} + +OUString +SwVbaDocuments::getServiceImplName() +{ + return "SwVbaDocuments"; +} + +uno::Sequence<OUString> +SwVbaDocuments::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.Documents" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbadocuments.hxx b/sw/source/ui/vba/vbadocuments.hxx new file mode 100644 index 0000000000..2b6261adba --- /dev/null +++ b/sw/source/ui/vba/vbadocuments.hxx @@ -0,0 +1,52 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENTS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENTS_HXX + +#include <ooo/vba/word/XDocuments.hpp> +#include <vbahelper/vbadocumentsbase.hxx> +#include <cppuhelper/implbase.hxx> + +typedef cppu::ImplInheritanceHelper< VbaDocumentsBase, ov::word::XDocuments > SwVbaDocuments_BASE; + +class SwVbaDocuments : public SwVbaDocuments_BASE +{ +public: + SwVbaDocuments( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ); + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaDocuments_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + + // Methods + virtual css::uno::Any SAL_CALL Add( const css::uno::Any& Template, const css::uno::Any& NewTemplate, const css::uno::Any& DocumentType, const css::uno::Any& Visible ) override; + virtual css::uno::Any SAL_CALL Open( const OUString& Filename, const css::uno::Any& ConfirmConversions, const css::uno::Any& ReadOnly, const css::uno::Any& AddToRecentFiles, const css::uno::Any& PasswordDocument, const css::uno::Any& PasswordTemplate, const css::uno::Any& Revert, const css::uno::Any& WritePasswordDocument, const css::uno::Any& WritePasswordTemplate, const css::uno::Any& Format, const css::uno::Any& Encoding, const css::uno::Any& Visible, const css::uno::Any& OpenAndRepair, const css::uno::Any& DocumentDirection, const css::uno::Any& NoEncodingDialog, const css::uno::Any& XMLTransform ) override; + virtual css::uno::Any SAL_CALL OpenNoRepairDialog( const OUString& Filename, const css::uno::Any& ConfirmConversions, const css::uno::Any& ReadOnly, const css::uno::Any& AddToRecentFiles, const css::uno::Any& PasswordDocument, const css::uno::Any& PasswordTemplate, const css::uno::Any& Revert, const css::uno::Any& WritePasswordDocument, const css::uno::Any& WritePasswordTemplate, const css::uno::Any& Format, const css::uno::Any& Encoding, const css::uno::Any& Visible, const css::uno::Any& OpenAndRepair, const css::uno::Any& DocumentDirection, const css::uno::Any& NoEncodingDialog, const css::uno::Any& XMLTransform ) override; + virtual css::uno::Any SAL_CALL OpenOld( const OUString& FileName, const css::uno::Any& ConfirmConversions, const css::uno::Any& ReadOnly, const css::uno::Any& AddToRecentFiles, const css::uno::Any& PasswordDocument, const css::uno::Any& PasswordTemplate, const css::uno::Any& Revert, const css::uno::Any& WritePasswordDocument, const css::uno::Any& WritePasswordTemplate, const css::uno::Any& Format ) override; + virtual void SAL_CALL Close( const css::uno::Any& SaveChanges, const css::uno::Any& OriginalFormat, const css::uno::Any& RouteDocument ) override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENTS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaeventshelper.cxx b/sw/source/ui/vba/vbaeventshelper.cxx new file mode 100644 index 0000000000..d928eaba16 --- /dev/null +++ b/sw/source/ui/vba/vbaeventshelper.cxx @@ -0,0 +1,94 @@ +/* -*- 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 "vbaeventshelper.hxx" +#include <com/sun/star/script/ModuleType.hpp> +#include <com/sun/star/script/vba/VBAEventId.hpp> +#include <cppuhelper/supportsservice.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::script::vba::VBAEventId; + +SwVbaEventsHelper::SwVbaEventsHelper( uno::Sequence< css::uno::Any > const& aArgs, uno::Reference< uno::XComponentContext > const& /*xContext*/ ) : + VbaEventsHelperBase( aArgs ) +{ + using namespace ::com::sun::star::script::ModuleType; + registerEventHandler( DOCUMENT_NEW, DOCUMENT, "Document_New" ); + registerEventHandler( AUTO_NEW, NORMAL, "AutoNew" ); + registerEventHandler( DOCUMENT_OPEN, DOCUMENT, "Document_Open" ); + registerEventHandler( AUTO_OPEN, NORMAL, "AutoOpen" ); + registerEventHandler( DOCUMENT_CLOSE, DOCUMENT, "Document_Close" ); + registerEventHandler( AUTO_CLOSE, NORMAL, "AutoClose" ); +} + +SwVbaEventsHelper::~SwVbaEventsHelper() +{ +} + +bool SwVbaEventsHelper::implPrepareEvent(EventQueue& /*rEventQueue*/, + const EventHandlerInfo& /*rInfo*/, const uno::Sequence<uno::Any>& /*rArgs*/) +{ + return true; +} + +uno::Sequence< uno::Any > SwVbaEventsHelper::implBuildArgumentList( const EventHandlerInfo& /*rInfo*/, + const uno::Sequence< uno::Any >& /*rArgs*/ ) +{ + // no event handler expects any arguments + return uno::Sequence< uno::Any >(); +} + +void SwVbaEventsHelper::implPostProcessEvent( EventQueue& /*rEventQueue*/, + const EventHandlerInfo& /*rInfo*/, bool /*bCancel*/ ) +{ + // nothing to do after any event +} + +OUString SwVbaEventsHelper::implGetDocumentModuleName( const EventHandlerInfo& /*rInfo*/, + const uno::Sequence< uno::Any >& /*rArgs*/ ) const +{ + // TODO: get actual codename from document + return "ThisDocument"; +} + + // XServiceInfo +OUString SwVbaEventsHelper::getImplementationName() +{ + return "SwVbaEventsHelper"; +} +sal_Bool SwVbaEventsHelper::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} +css::uno::Sequence< OUString > SwVbaEventsHelper::getSupportedServiceNames() +{ + return { "com.sun.star.script.vba.VBATextEventProcessor" }; +} + + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +Writer_SwVbaEventsHelper_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args) +{ + return cppu::acquire(new SwVbaEventsHelper(args, context)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaeventshelper.hxx b/sw/source/ui/vba/vbaeventshelper.hxx new file mode 100644 index 0000000000..31a6b2808e --- /dev/null +++ b/sw/source/ui/vba/vbaeventshelper.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 . + */ + +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAEVENTSHELPER_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAEVENTSHELPER_HXX + +#include <vbahelper/vbaeventshelperbase.hxx> + +class SwVbaEventsHelper : public VbaEventsHelperBase +{ +public: + SwVbaEventsHelper( + const css::uno::Sequence< css::uno::Any >& rArgs, + const css::uno::Reference< css::uno::XComponentContext >& rxContext ); + virtual ~SwVbaEventsHelper() 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; + +protected: + virtual bool implPrepareEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) override; + virtual css::uno::Sequence< css::uno::Any > implBuildArgumentList( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) override; + virtual void implPostProcessEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, bool bCancel ) override; + virtual OUString implGetDocumentModuleName( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) const override; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbafield.cxx b/sw/source/ui/vba/vbafield.cxx new file mode 100644 index 0000000000..ded84a6d8b --- /dev/null +++ b/sw/source/ui/vba/vbafield.cxx @@ -0,0 +1,538 @@ +/* -*- 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 "vbafield.hxx" +#include "vbarange.hxx" +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/text/XTextFieldsSupplier.hpp> +#include <com/sun/star/text/FilenameDisplayFormat.hpp> +#include <com/sun/star/util/XRefreshable.hpp> +#include <com/sun/star/util/XUpdatable.hpp> +#include <ooo/vba/word/WdFieldType.hpp> +#include <basic/sberrors.hxx> +#include <cppuhelper/implbase.hxx> +#include <sal/log.hxx> +#include <tools/long.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaField::SwVbaField( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, const uno::Reference< css::text::XTextField >& xTextField) : SwVbaField_BASE( rParent, rContext ) +{ + mxTextField.set( xTextField, uno::UNO_SET_THROW ); +} + +sal_Bool SAL_CALL SwVbaField::Update() +{ + uno::Reference< util::XUpdatable > xUpdatable( mxTextField, uno::UNO_QUERY ); + if( xUpdatable.is() ) + { + xUpdatable->update(); + return true; + } + return false; +} + +// XHelperInterface +OUString +SwVbaField::getServiceImplName() +{ + return "SwVbaField"; +} + +uno::Sequence<OUString> +SwVbaField::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Field" + }; + return aServiceNames; +} + +namespace { + +// FIXME? copy and paste code +// the codes are copied from ww8par5.cxx +class SwVbaReadFieldParams +{ +private: + OUString m_aData; + sal_Int32 m_nLen, m_nFnd, m_nNext, m_nSavPtr; + OUString m_aFieldName; +public: + explicit SwVbaReadFieldParams( const OUString& rData ); + + tools::Long SkipToNextToken(); + + sal_Int32 FindNextStringPiece( sal_Int32 _nStart ); + + OUString GetResult() const; + const OUString& GetFieldName()const { return m_aFieldName; } +}; + +} + +SwVbaReadFieldParams::SwVbaReadFieldParams( const OUString& _rData ) + : m_aData( _rData ), m_nLen( _rData.getLength() ), m_nNext( 0 ) +{ + // First search for an opening parenthesis or a space or a quotation mark + // or a backslash, so that the field command + // (thus INCLUDEPICTURE or ...) is ignored. + while( (m_nLen > m_nNext) && (m_aData[ m_nNext ] == ' ') ) + ++m_nNext; + + sal_Unicode c; + while( m_nLen > m_nNext + && (c = m_aData[ m_nNext ]) != ' ' + && c != '"' + && c != '\\' + && c != 132 + && c != 0x201c ) + ++m_nNext; + + m_nFnd = m_nNext; + m_nSavPtr = m_nNext; + m_aFieldName = m_aData.copy( 0, m_nFnd ); +} + +OUString SwVbaReadFieldParams::GetResult() const +{ + return (-1 == m_nFnd) + ? OUString() + : m_aData.copy( m_nFnd, (m_nSavPtr - m_nFnd) ); +} + +// ret: -2: NOT a '\' parameter but normal Text +tools::Long SwVbaReadFieldParams::SkipToNextToken() +{ + tools::Long nRet = -1; // end + if ( + (-1 != m_nNext) && (m_nLen > m_nNext) && + -1 != (m_nFnd = FindNextStringPiece(m_nNext)) + ) + { + m_nSavPtr = m_nNext; + + if ('\\' == m_aData[m_nFnd] && '\\' != m_aData[m_nFnd + 1]) + { + nRet = m_aData[++m_nFnd]; + m_nNext = ++m_nFnd; // and set behind + } + else + { + nRet = -2; + if ( + (-1 != m_nSavPtr ) && + ( + ('"' == m_aData[m_nSavPtr - 1]) || + (0x201d == m_aData[m_nSavPtr - 1]) + ) + ) + { + --m_nSavPtr; + } + } + } + return nRet; +} + +// FindNextPara is searching for the next Backslash-Parameter or the next string +// until blank or the next "\" or until the closing quotation mark +// or until the string end of pStr. + +// Output ppNext (if ppNext != 0) beginning of the search for the next parameter or 0 + +// Return value: 0 if String-End reached, otherwise begin of the parameter or the string + +sal_Int32 SwVbaReadFieldParams::FindNextStringPiece(const sal_Int32 nStart) +{ + sal_Int32 n = ( -1 == nStart ) ? m_nFnd : nStart; // Start + sal_Int32 n2; // End + + m_nNext = -1; // Default for not found + + while( (m_nLen > n) && (m_aData[ n ] == ' ') ) + ++n; + + if( m_nLen == n ) + return -1; // String End reached! + + if( (m_aData[ n ] == '"') // quotation marks are in front of parenthesis? + || (m_aData[ n ] == 0x201c) + || (m_aData[ n ] == 132) ) + { + n++; // ignore quotation marks + n2 = n; // From here search for the end + while( (m_nLen > n2) + && (m_aData[ n2 ] != '"') + && (m_aData[ n2 ] != 0x201d) + && (m_aData[ n2 ] != 147) ) + n2++; // Search for the end of the parenthesis + } + else // no quotation marks + { + n2 = n; // from here search for the end + while( (m_nLen > n2) && (m_aData[ n2 ] != ' ') ) // Search for the end of the parenthesis + { + if( m_aData[ n2 ] == '\\' ) + { + if( m_aData[ n2+1 ] == '\\' ) + n2 += 2; // double-backslash -> OK + else + { + if( n2 > n ) + n2--; + break; // single-backslash -> End + } + } + else + n2++; // no backslash -> OK + } + } + if( m_nLen > n2 ) + { + if(m_aData[ n2 ] != ' ') n2++; + m_nNext = n2; + } + return n; +} + +// SwVbaFields + +static uno::Any lcl_createField( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel, const uno::Any& aSource ) +{ + uno::Reference< text::XTextField > xTextField( aSource, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextDocument > xTextDocument( xModel, uno::UNO_QUERY_THROW ); + uno::Reference< word::XField > xField( new SwVbaField( xParent, xContext, xTextField ) ); + return uno::Any( xField ); +} + +namespace { + +class FieldEnumeration : public ::cppu::WeakImplHelper< css::container::XEnumeration > +{ + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< frame::XModel > mxModel; + uno::Reference< container::XEnumeration > mxEnumeration; +public: + FieldEnumeration( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel, uno::Reference< container::XEnumeration > xEnumeration ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxModel(std::move( xModel )), mxEnumeration(std::move( xEnumeration )) + { + } + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return mxEnumeration->hasMoreElements(); + } + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( !hasMoreElements() ) + throw container::NoSuchElementException(); + return lcl_createField( mxParent, mxContext, mxModel, mxEnumeration->nextElement() ); + } +}; + +class FieldCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess, + container::XEnumerationAccess > +{ + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< frame::XModel > mxModel; + uno::Reference< container::XEnumerationAccess > mxEnumerationAccess; +public: + /// @throws css::uno::RuntimeException + FieldCollectionHelper( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, const uno::Reference< frame::XModel >& xModel ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxModel( xModel ) + { + uno::Reference< text::XTextFieldsSupplier > xSupp( xModel, uno::UNO_QUERY_THROW ); + mxEnumerationAccess.set( xSupp->getTextFields(), uno::UNO_SET_THROW ); + } + // XElementAccess + virtual uno::Type SAL_CALL getElementType( ) override { return mxEnumerationAccess->getElementType(); } + virtual sal_Bool SAL_CALL hasElements( ) override { return mxEnumerationAccess->hasElements(); } + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override + { + uno::Reference< container::XEnumeration > xEnumeration = mxEnumerationAccess->createEnumeration(); + sal_Int32 nCount = 0; + while( xEnumeration->hasMoreElements() ) + { + ++nCount; + xEnumeration->nextElement(); + } + return nCount; + } + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override + { + if( Index < 0 || Index >= getCount() ) + throw lang::IndexOutOfBoundsException(); + + uno::Reference< container::XEnumeration > xEnumeration = mxEnumerationAccess->createEnumeration(); + sal_Int32 nCount = 0; + while( xEnumeration->hasMoreElements() ) + { + if( nCount == Index ) + { + return xEnumeration->nextElement(); + } + ++nCount; + } + throw lang::IndexOutOfBoundsException(); + } + // XEnumerationAccess + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override + { + uno::Reference< container::XEnumeration > xEnumeration = mxEnumerationAccess->createEnumeration(); + return uno::Reference< container::XEnumeration >( new FieldEnumeration( mxParent, mxContext, mxModel, xEnumeration ) ); + } +}; + +} + +SwVbaFields::SwVbaFields( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel ) : SwVbaFields_BASE( xParent, xContext , uno::Reference< container::XIndexAccess >( new FieldCollectionHelper( xParent, xContext, xModel ) ) ), mxModel( xModel ) +{ + mxMSF.set( mxModel, uno::UNO_QUERY_THROW ); +} + +uno::Reference< word::XField > SAL_CALL +SwVbaFields::Add( const css::uno::Reference< ::ooo::vba::word::XRange >& Range, const css::uno::Any& Type, const css::uno::Any& Text, const css::uno::Any& /*PreserveFormatting*/ ) +{ + sal_Int32 nType = word::WdFieldType::wdFieldEmpty; + Type >>= nType; + OUString sText; + Text >>= sText; + + OUString sFieldName; + if( ( nType == word::WdFieldType::wdFieldEmpty ) && !sText.isEmpty() ) + { + SwVbaReadFieldParams aReadParam(sText); + sFieldName = aReadParam.GetFieldName(); + SAL_INFO("sw.vba", "the field name is " << sFieldName ); + } + + uno::Reference< text::XTextContent > xTextField; + if( nType == word::WdFieldType::wdFieldFileName || sFieldName.equalsIgnoreAsciiCase("FILENAME") ) + { + xTextField.set( Create_Field_FileName( sText ), uno::UNO_QUERY_THROW ); + } + else if( nType == word::WdFieldType::wdFieldDocProperty || sFieldName.equalsIgnoreAsciiCase("DOCPROPERTY") ) + { + xTextField.set( Create_Field_DocProperty( sText ), uno::UNO_QUERY_THROW ); + } + else + { + throw uno::RuntimeException("Not implemented" ); + } + + SwVbaRange& rVbaRange = dynamic_cast<SwVbaRange&>(*Range); + uno::Reference< text::XTextRange > xTextRange = rVbaRange.getXTextRange(); + uno::Reference< text::XText > xText = xTextRange->getText(); + xText->insertTextContent( xTextRange, xTextField, true ); + return uno::Reference< word::XField >( new SwVbaField( mxParent, mxContext, uno::Reference< text::XTextField >( xTextField, uno::UNO_QUERY_THROW ) ) ); +} + +uno::Reference< text::XTextField > SwVbaFields::Create_Field_FileName( const OUString& _text ) +{ + uno::Reference< text::XTextField > xTextField( mxMSF->createInstance("com.sun.star.text.TextField.FileName"), uno::UNO_QUERY_THROW ); + sal_Int16 nFileFormat = text::FilenameDisplayFormat::NAME_AND_EXT; + if( !_text.isEmpty() ) + { + tools::Long nRet; + SwVbaReadFieldParams aReadParam( _text ); + while (-1 != (nRet = aReadParam.SkipToNextToken())) + { + switch (nRet) + { + case 'p': + nFileFormat = text::FilenameDisplayFormat::FULL; + break; + case '*': + //Skip over MERGEFORMAT + aReadParam.SkipToNextToken(); + break; + default: + DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {}); + break; + } + } + } + + uno::Reference< beans::XPropertySet > xProps( xTextField, uno::UNO_QUERY_THROW ); + xProps->setPropertyValue("FileFormat", uno::Any( nFileFormat ) ); + + return xTextField; +} + +namespace { + +struct DocPropertyTable +{ + const char* sDocPropertyName; + const char* sFieldService; +}; + +} + +const DocPropertyTable aDocPropertyTables[] = +{ + { "Author", "com.sun.star.text.textfield.docinfo.CreateAuthor" }, + { "Bytes", nullptr }, + { "Category", nullptr }, + { "Characters",nullptr }, + { "CharactersWithSpaces", nullptr }, + { "Comments", "com.sun.star.text.textfield.docinfo.Description" }, + { "Company", nullptr }, + { "CreateTime", "com.sun.star.text.textfield.docinfo.CreateDateTime" }, + { "HyperlinkBase", nullptr }, + { "Keywords", "com.sun.star.text.textfield.docinfo.Keywords" }, + { "LastPrinted", "com.sun.star.text.textfield.docinfo.PrintDateTime" }, + { "LastSavedBy", "com.sun.star.text.textfield.docinfo.ChangeAuthor" }, + { "LastSavedTime", "com.sun.star.text.textfield.docinfo.ChangeDateTime" }, + { "Lines", nullptr }, + { "Manager", nullptr }, + { "NameofApplication", nullptr }, + { "ODMADocID", nullptr }, + { "Pages", "com.sun.star.text.textfield.PageCount" }, + { "Paragraphs", "com.sun.star.text.textfield.ParagraphCount" }, + { "RevisionNumber", "com.sun.star.text.textfield.docinfo.Revision" }, + { "Security", nullptr }, + { "Subject", "com.sun.star.text.textfield.docinfo.Subject" }, + { "Template", "com.sun.star.text.textfield.TemplateName" }, + { "Title", "com.sun.star.text.textfield.docinfo.Title" }, + { "TotalEditingTime", "com.sun.star.text.textfield.docinfo.EditTime" }, + { "Words", "com.sun.star.text.textfield.WordCount" }, + { nullptr, nullptr } +}; + +uno::Reference< text::XTextField > SwVbaFields::Create_Field_DocProperty( const OUString& _text ) +{ + OUString aDocProperty; + SwVbaReadFieldParams aReadParam( _text ); + tools::Long nRet; + while( -1 != ( nRet = aReadParam.SkipToNextToken() )) + { + switch( nRet ) + { + case -2: + if( aDocProperty.isEmpty() ) + aDocProperty = aReadParam.GetResult(); + break; + case '*': + //Skip over MERGEFORMAT + aReadParam.SkipToNextToken(); + break; + } + } + aDocProperty = aDocProperty.replaceAll("\"", ""); + SAL_INFO("sw.vba", "SwVbaFields::Create_Field_DocProperty, the document property name is " << aDocProperty ); + if( aDocProperty.isEmpty() ) + { + throw uno::RuntimeException(); + } + + bool bCustom = true; + OUString sFieldService; + // find the build in document properties + for( const DocPropertyTable* pTable = aDocPropertyTables; pTable->sDocPropertyName != nullptr; pTable++ ) + { + if( aDocProperty.equalsIgnoreAsciiCaseAscii( pTable->sDocPropertyName ) ) + { + if( pTable->sFieldService != nullptr ) + sFieldService = OUString::createFromAscii(pTable->sFieldService); + bCustom = false; + break; + } + } + + if( bCustom ) + { + sFieldService = "com.sun.star.text.textfield.docinfo.Custom"; + } + else if( sFieldService.isEmpty() ) + { + throw uno::RuntimeException("Not implemented" ); + } + + uno::Reference< text::XTextField > xTextField( mxMSF->createInstance( sFieldService ), uno::UNO_QUERY_THROW ); + + if( bCustom ) + { + uno::Reference< beans::XPropertySet > xProps( xTextField, uno::UNO_QUERY_THROW ); + xProps->setPropertyValue("Name", uno::Any( aDocProperty ) ); + } + + return xTextField; +} + +uno::Reference< container::XEnumeration > SAL_CALL +SwVbaFields::createEnumeration() +{ + uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); + return xEnumerationAccess->createEnumeration(); +} + +// ScVbaCollectionBaseImpl +uno::Any +SwVbaFields::createCollectionObject( const uno::Any& aSource ) +{ + return lcl_createField( mxParent, mxContext, mxModel, aSource ); +} + +sal_Int32 SAL_CALL SwVbaFields::Update() +{ + sal_Int32 nUpdate = 1; + try + { + uno::Reference< text::XTextFieldsSupplier > xSupp( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< util::XRefreshable > xRef( xSupp->getTextFields(), uno::UNO_QUERY_THROW ); + xRef->refresh(); + nUpdate = 0; + } + catch(const uno::Exception&) + { + nUpdate = 1; + } + return nUpdate; +} + +// XHelperInterface +OUString +SwVbaFields::getServiceImplName() +{ + return "SwVbaFields"; +} + +// XEnumerationAccess +uno::Type SAL_CALL +SwVbaFields::getElementType() +{ + return cppu::UnoType<word::XField>::get(); +} + +uno::Sequence<OUString> +SwVbaFields::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Fields" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbafield.hxx b/sw/source/ui/vba/vbafield.hxx new file mode 100644 index 0000000000..292be2edb7 --- /dev/null +++ b/sw/source/ui/vba/vbafield.hxx @@ -0,0 +1,74 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAFIELD_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAFIELD_HXX +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/text/XTextField.hpp> +#include <ooo/vba/word/XField.hpp> +#include <ooo/vba/word/XFields.hpp> +#include <vbahelper/vbacollectionimpl.hxx> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XField > SwVbaField_BASE; + +class SwVbaField : public SwVbaField_BASE +{ + css::uno::Reference< css::text::XTextField > mxTextField; +public: + /// @throws css::uno::RuntimeException + SwVbaField( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, const css::uno::Reference< css::text::XTextField >& xTextField); + + virtual sal_Bool SAL_CALL Update() override; + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +typedef CollTestImplHelper< ov::word::XFields > SwVbaFields_BASE; + +class SwVbaFields : public SwVbaFields_BASE +{ + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::lang::XMultiServiceFactory > mxMSF; +private: + /// @throws css::uno::RuntimeException + /// @throws css::script::BasicErrorException + css::uno::Reference< css::text::XTextField > Create_Field_FileName(const OUString& rText); + /// @throws css::uno::RuntimeException + css::uno::Reference< css::text::XTextField > Create_Field_DocProperty( const OUString& _text ); + +public: + SwVbaFields( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel ); + // XFields + virtual css::uno::Reference< ::ooo::vba::word::XField > SAL_CALL Add( const css::uno::Reference< ::ooo::vba::word::XRange >& Range, const css::uno::Any& Type, const css::uno::Any& Text, const css::uno::Any& PreserveFormatting ) override; + virtual sal_Int32 SAL_CALL Update() override; + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + // ScVbaCollectionBaseImpl + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbafilterpropsfromformat.hxx b/sw/source/ui/vba/vbafilterpropsfromformat.hxx new file mode 100644 index 0000000000..cde1da0b4d --- /dev/null +++ b/sw/source/ui/vba/vbafilterpropsfromformat.hxx @@ -0,0 +1,75 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAFILTERPROPSFROMFORMAT_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAFILTERPROPSFROMFORMAT_HXX + +#include <sal/config.h> + +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/uno/Sequence.hxx> +#include <rtl/ustring.hxx> +#include <ooo/vba/word/WdSaveFormat.hpp> + +namespace +{ +inline bool setFilterPropsFromFormat(sal_Int32 nFormat, + css::uno::Sequence<css::beans::PropertyValue>& rProps) +{ + auto[begin, end] = asNonConstRange(rProps); + auto pProp = std::find_if(begin, end, [](const css::beans::PropertyValue& rProp) { + return rProp.Name == "FilterName"; + }); + if (pProp != end) + { + switch (nFormat) + { + case ooo::vba::word::WdSaveFormat::wdFormatDocument: + pProp->Value <<= OUString("MS Word 97"); + break; + // Just save all the text formats as "Text" + case ooo::vba::word::WdSaveFormat::wdFormatDOSText: + case ooo::vba::word::WdSaveFormat::wdFormatDOSTextLineBreaks: + case ooo::vba::word::WdSaveFormat::wdFormatEncodedText: + case ooo::vba::word::WdSaveFormat::wdFormatText: + case ooo::vba::word::WdSaveFormat::wdFormatTextLineBreaks: + pProp->Value <<= OUString("Text"); + break; + case ooo::vba::word::WdSaveFormat::wdFormatFilteredHTML: + case ooo::vba::word::WdSaveFormat::wdFormatHTML: + pProp->Value <<= OUString("HTML"); + break; + case ooo::vba::word::WdSaveFormat::wdFormatRTF: + pProp->Value <<= OUString("Rich Text Format"); + break; + case ooo::vba::word::WdSaveFormat::wdFormatTemplate: + pProp->Value <<= OUString("MS Word 97 Vorlage"); + break; + + // Default to "MS Word 97" + default: + pProp->Value <<= OUString("MS Word 97"); + break; + } + return true; + } + return false; +} +} + +#endif diff --git a/sw/source/ui/vba/vbafind.cxx b/sw/source/ui/vba/vbafind.cxx new file mode 100644 index 0000000000..892e062f3c --- /dev/null +++ b/sw/source/ui/vba/vbafind.cxx @@ -0,0 +1,431 @@ +/* -*- 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 "vbafind.hxx" +#include "vbareplacement.hxx" +#include <ooo/vba/word/WdFindWrap.hpp> +#include <ooo/vba/word/WdReplace.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/text/XTextRangeCompare.hpp> +#include <doc.hxx> +#include <docsh.hxx> +#include "wordvbahelper.hxx" +#include <rtl/ref.hxx> +#include <sal/log.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaFind::SwVbaFind( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< frame::XModel > xModel ) : + SwVbaFind_BASE( rParent, rContext ), mxModel( std::move(xModel) ), mbReplace( false ), mnReplaceType( word::WdReplace::wdReplaceOne ), mnWrap( word::WdFindWrap::wdFindStop ) +{ + mxReplaceable.set( mxModel, uno::UNO_QUERY_THROW ); + mxPropertyReplace.set( mxReplaceable->createReplaceDescriptor(), uno::UNO_QUERY_THROW ); + mxTVC = word::getXTextViewCursor( mxModel ); + mxSelSupp.set( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); +} + +SwVbaFind::~SwVbaFind() +{ +} + +uno::Reference< word::XFind > SwVbaFind::GetOrCreateFind(const uno::Reference< ooo::vba::XHelperInterface >& rParent, + const uno::Reference< uno::XComponentContext >& rContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< text::XTextRange >& xTextRange) +{ + rtl::Reference< SwVbaFind > xFind; + SwDoc* pDoc = word::getDocShell( xModel )->GetDoc(); + if( pDoc ) + xFind = dynamic_cast<SwVbaFind *>( pDoc->getVbaFind().get() ); + if ( !xFind ) + { + xFind = new SwVbaFind( rParent, rContext, xModel ); + if ( pDoc ) + pDoc->setVbaFind( xFind ); + } + xFind->mxTextRange = xTextRange; + + return xFind; +} + + +bool SwVbaFind::InRange( const uno::Reference< text::XTextRange >& xCurrentRange ) +{ + uno::Reference< text::XTextRangeCompare > xTRC( mxTextRange->getText(), uno::UNO_QUERY_THROW ); + return xTRC->compareRegionStarts( mxTextRange, xCurrentRange ) >= 0 && xTRC->compareRegionEnds( mxTextRange, xCurrentRange ) <= 0; +} + +bool SwVbaFind::InEqualRange( const uno::Reference< text::XTextRange >& xCurrentRange ) +{ + uno::Reference< text::XTextRangeCompare > xTRC( mxTextRange->getText(), uno::UNO_QUERY_THROW ); + return xTRC->compareRegionStarts( mxTextRange, xCurrentRange ) == 0 && xTRC->compareRegionEnds( mxTextRange, xCurrentRange ) == 0; +} + +void SwVbaFind::SetReplaceWith( const OUString& rText ) +{ + mxPropertyReplace->setReplaceString( rText ); + mbReplace = true; +} + +OUString SwVbaFind::GetReplaceWith() +{ + return mxPropertyReplace->getReplaceString(); +} +void SwVbaFind::SetReplace( sal_Int32 type ) +{ + mnReplaceType = type; + mbReplace = true; +} +uno::Reference< text::XTextRange > SwVbaFind::FindOneElement() +{ + uno::Reference< text::XTextRange > xFoundOne; + if( !mxTVC->getString().isEmpty() ) + { + if( getForward() ) + { + xFoundOne.set( mxReplaceable->findNext( mxTextRange->getStart(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY ); + } + else + { + xFoundOne.set( mxReplaceable->findNext( mxTextRange->getEnd(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY ); + } + + if( xFoundOne.is() && InEqualRange( xFoundOne ) ) + { + xFoundOne.set( mxReplaceable->findNext( xFoundOne, uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY ); + } + else if( xFoundOne.is() && !InRange( xFoundOne ) ) + { + xFoundOne.clear(); + } + } + else + { + xFoundOne.set( mxReplaceable->findNext( mxTextRange, uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY ); + } + + if( !xFoundOne.is() && ( getWrap() == word::WdFindWrap::wdFindContinue || getWrap() == word::WdFindWrap::wdFindAsk ) ) + { + if( getForward() ) + { + mxTVC->gotoStart(false); + xFoundOne.set( mxReplaceable->findNext( mxTextRange->getStart(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY ); + } + else + { + mxTVC->gotoEnd( false ); + xFoundOne.set( mxReplaceable->findNext( mxTextRange->getEnd(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY ); + + } + } + return xFoundOne; +} + +bool SwVbaFind::SearchReplace() +{ + bool result = false; + + // TODO: map wildcards in area to OOo wildcards + + if( mbReplace ) + { + switch( mnReplaceType ) + { + case word::WdReplace::wdReplaceNone: + { + result = true; + break; + } + case word::WdReplace::wdReplaceOne: + { + uno::Reference< text::XTextRange > xFindOne = FindOneElement(); + if( xFindOne.is() ) + { + xFindOne->setString( GetReplaceWith() ); + result = mxSelSupp->select( uno::Any( xFindOne ) ); + } + break; + } + case word::WdReplace::wdReplaceAll: + { + uno::Reference< container::XIndexAccess > xIndexAccess = mxReplaceable->findAll( uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ); + if( xIndexAccess->getCount() > 0 ) + { + for( sal_Int32 i = 0; i < xIndexAccess->getCount(); i++ ) + { + uno::Reference< text::XTextRange > xTextRange( xIndexAccess->getByIndex( i ), uno::UNO_QUERY_THROW ); + if( mnWrap == word::WdFindWrap::wdFindContinue || mnWrap == word::WdFindWrap::wdFindAsk || InRange( xTextRange ) ) + { + xTextRange->setString( GetReplaceWith() ); + result = true; + } + } + } + break; + } + default: + { + result = false; + } + } + } + else + { + uno::Reference< text::XTextRange > xFindOne = FindOneElement(); + if( xFindOne.is() ) + result = mxSelSupp->select( uno::Any( xFindOne ) ); + } + + return result; +} + +OUString SAL_CALL SwVbaFind::getText() +{ + return mxPropertyReplace->getSearchString(); +} + +void SAL_CALL SwVbaFind::setText( const OUString& _text ) +{ + mxPropertyReplace->setSearchString( _text ); +} + +uno::Any SAL_CALL SwVbaFind::getReplacement() +{ + return uno::Any( uno::Reference< word::XReplacement >( new SwVbaReplacement( this, mxContext, mxPropertyReplace ) ) ); +} + +void SAL_CALL SwVbaFind::setReplacement( const uno::Any& /*_replacement */ ) +{ + throw uno::RuntimeException("Not implemented" ); +} + +sal_Bool SAL_CALL SwVbaFind::getForward() +{ + bool bBackward = false; + mxPropertyReplace->getPropertyValue("SearchBackwards") >>= bBackward; + return !bBackward; +} + +void SAL_CALL SwVbaFind::setForward( sal_Bool _forward ) +{ + bool bBackward = !_forward; + mxPropertyReplace->setPropertyValue("SearchBackwards", uno::Any( bBackward ) ); +} + +::sal_Int32 SAL_CALL SwVbaFind::getWrap() +{ + // seems not supported in Writer + return mnWrap; +} + +void SAL_CALL SwVbaFind::setWrap( ::sal_Int32 _wrap ) +{ + // seems not supported in Writer + mnWrap = _wrap; +} + +sal_Bool SAL_CALL SwVbaFind::getFormat() +{ + return mxPropertyReplace->getValueSearch(); +} + +void SAL_CALL SwVbaFind::setFormat( sal_Bool _format ) +{ + mxPropertyReplace->setValueSearch( _format ); +} + +sal_Bool SAL_CALL SwVbaFind::getMatchCase() +{ + bool value = false; + mxPropertyReplace->getPropertyValue("SearchCaseSensitive") >>= value; + return value; +} + +void SAL_CALL SwVbaFind::setMatchCase( sal_Bool _matchcase ) +{ + mxPropertyReplace->setPropertyValue("SearchCaseSensitive", uno::Any( _matchcase ) ); +} + +sal_Bool SAL_CALL SwVbaFind::getMatchWholeWord() +{ + bool value = false; + mxPropertyReplace->getPropertyValue("SearchWords") >>= value; + return value; +} + +void SAL_CALL SwVbaFind::setMatchWholeWord( sal_Bool _matchwholeword ) +{ + mxPropertyReplace->setPropertyValue("SearchWords", uno::Any( _matchwholeword ) ); +} + +sal_Bool SAL_CALL SwVbaFind::getMatchWildcards() +{ + bool value = false; + mxPropertyReplace->getPropertyValue("SearchRegularExpression") >>= value; + return value; +} + +void SAL_CALL SwVbaFind::setMatchWildcards( sal_Bool _matchwildcards ) +{ + mxPropertyReplace->setPropertyValue("SearchRegularExpression", uno::Any( _matchwildcards ) ); +} + +sal_Bool SAL_CALL SwVbaFind::getMatchSoundsLike() +{ + bool value = false; + mxPropertyReplace->getPropertyValue("SearchSimilarity") >>= value; + return value; +} + +void SAL_CALL SwVbaFind::setMatchSoundsLike( sal_Bool _matchsoundslike ) +{ + // seems not accurate + mxPropertyReplace->setPropertyValue("SearchSimilarity", uno::Any( _matchsoundslike ) ); +} + +sal_Bool SAL_CALL SwVbaFind::getMatchAllWordForms() +{ + bool value = false; + mxPropertyReplace->getPropertyValue("SearchSimilarity") >>= value; + if( value ) + mxPropertyReplace->getPropertyValue("SearchSimilarityRelax") >>= value; + return value; +} + +void SAL_CALL SwVbaFind::setMatchAllWordForms( sal_Bool _matchallwordforms ) +{ + // seems not accurate + mxPropertyReplace->setPropertyValue("SearchSimilarity", uno::Any( _matchallwordforms ) ); + mxPropertyReplace->setPropertyValue("SearchSimilarityRelax", uno::Any( _matchallwordforms ) ); +} + +uno::Any SAL_CALL SwVbaFind::getStyle() +{ + throw uno::RuntimeException("Not implemented" ); +} + +void SAL_CALL SwVbaFind::setStyle( const uno::Any& /*_style */ ) +{ + throw uno::RuntimeException("Not implemented" ); +} + +sal_Bool SAL_CALL +SwVbaFind::Execute( const uno::Any& FindText, const uno::Any& MatchCase, const uno::Any& MatchWholeWord, const uno::Any& MatchWildcards, const uno::Any& MatchSoundsLike, const uno::Any& MatchAllWordForms, const uno::Any& Forward, const uno::Any& Wrap, const uno::Any& Format, const uno::Any& ReplaceWith, const uno::Any& Replace, const uno::Any& /*MatchKashida*/, const uno::Any& /*MatchDiacritics*/, const uno::Any& /*MatchAlefHamza*/, const uno::Any& /*MatchControl*/, const uno::Any& /*MatchPrefix*/, const uno::Any& /*MatchSuffix*/, const uno::Any& /*MatchPhrase*/, const uno::Any& /*IgnoreSpace*/, const uno::Any& /*IgnorePunct*/ ) +{ + bool result = false; + if( FindText.hasValue() ) + { + OUString sText; + FindText >>= sText; + setText( sText ); + } + + bool bValue = false; + if( MatchCase.hasValue() ) + { + MatchCase >>= bValue; + setMatchCase( bValue ); + } + + if( MatchWholeWord.hasValue() ) + { + MatchWholeWord >>= bValue; + setMatchWholeWord( bValue ); + } + + if( MatchWildcards.hasValue() ) + { + MatchWildcards >>= bValue; + setMatchWildcards( bValue ); + } + + if( MatchSoundsLike.hasValue() ) + { + MatchSoundsLike >>= bValue; + setMatchSoundsLike( bValue ); + } + + if( MatchAllWordForms.hasValue() ) + { + MatchAllWordForms >>= bValue; + setMatchAllWordForms( bValue ); + } + + if( Forward.hasValue() ) + { + Forward >>= bValue; + setForward( bValue ); + } + + if( Wrap.hasValue() ) + { + sal_Int32 nWrapType = 0; + Wrap >>= nWrapType; + setWrap( nWrapType ); + } + + if( Format.hasValue() ) + { + Format >>= bValue; + setFormat( bValue ); + } + + if( ReplaceWith.hasValue() ) + { + OUString sValue; + ReplaceWith >>= sValue; + SetReplaceWith( sValue ); + } + + if( Replace.hasValue() ) + { + sal_Int32 nValue(0); + Replace >>= nValue; + SetReplace( nValue ); + } + + result = SearchReplace(); + + return result; +} + +void SAL_CALL +SwVbaFind::ClearFormatting( ) +{ + uno::Sequence< beans::PropertyValue > aSearchAttribs; + mxPropertyReplace->setSearchAttributes( aSearchAttribs ); +} + +OUString +SwVbaFind::getServiceImplName() +{ + return "SwVbaFind"; +} + +uno::Sequence< OUString > +SwVbaFind::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Find" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbafind.hxx b/sw/source/ui/vba/vbafind.hxx new file mode 100644 index 0000000000..110a084bd2 --- /dev/null +++ b/sw/source/ui/vba/vbafind.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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAFIND_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAFIND_HXX + +#include <ooo/vba/word/XFind.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/util/XReplaceable.hpp> +#include <com/sun/star/util/XPropertyReplace.hpp> +#include <com/sun/star/text/XTextViewCursor.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XFind > SwVbaFind_BASE; + +class SwVbaFind : public SwVbaFind_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::text::XTextRange > mxTextRange; + css::uno::Reference< css::util::XReplaceable > mxReplaceable; + css::uno::Reference< css::util::XPropertyReplace> mxPropertyReplace; + css::uno::Reference< css::text::XTextViewCursor> mxTVC; + css::uno::Reference< css::view::XSelectionSupplier> mxSelSupp; + bool mbReplace; + sal_Int32 mnReplaceType; + sal_Int32 mnWrap; + +private: + /// @throws css::uno::RuntimeException + bool InRange( const css::uno::Reference< css::text::XTextRange >& xCurrentRange ); + /// @throws css::uno::RuntimeException + bool InEqualRange( const css::uno::Reference< css::text::XTextRange >& xCurrentRange ); + void SetReplace( sal_Int32 type ); + /// @throws css::uno::RuntimeException + void SetReplaceWith( const OUString& rText ); + /// @throws css::uno::RuntimeException + OUString GetReplaceWith(); + /// @throws css::uno::RuntimeException + css::uno::Reference< css::text::XTextRange > FindOneElement(); + /// @throws css::uno::RuntimeException + bool SearchReplace(); + + /// @throws css::uno::RuntimeException + SwVbaFind( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::frame::XModel > xModel ); +public: + static css::uno::Reference< ooo::vba::word::XFind > GetOrCreateFind(const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< com::sun::star::uno::XComponentContext >& rContext, const css::uno::Reference< com::sun::star::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextRange >& xTextRange); + virtual ~SwVbaFind() override; + + // Attributes + virtual OUString SAL_CALL getText() override; + virtual void SAL_CALL setText( const OUString& _text ) override; + virtual css::uno::Any SAL_CALL getReplacement() override; + virtual void SAL_CALL setReplacement( const css::uno::Any& _replacement ) override; + virtual sal_Bool SAL_CALL getForward() override; + virtual void SAL_CALL setForward( sal_Bool _forward ) override; + virtual ::sal_Int32 SAL_CALL getWrap() override; + virtual void SAL_CALL setWrap( ::sal_Int32 _wrap ) override; + virtual sal_Bool SAL_CALL getFormat() override; + virtual void SAL_CALL setFormat( sal_Bool _format ) override; + virtual sal_Bool SAL_CALL getMatchCase() override; + virtual void SAL_CALL setMatchCase( sal_Bool _matchcase ) override; + virtual sal_Bool SAL_CALL getMatchWholeWord() override; + virtual void SAL_CALL setMatchWholeWord( sal_Bool _matchwholeword ) override; + virtual sal_Bool SAL_CALL getMatchWildcards() override; + virtual void SAL_CALL setMatchWildcards( sal_Bool _matchwildcards ) override; + virtual sal_Bool SAL_CALL getMatchSoundsLike() override; + virtual void SAL_CALL setMatchSoundsLike( sal_Bool _matchsoundslike ) override; + virtual sal_Bool SAL_CALL getMatchAllWordForms() override; + virtual void SAL_CALL setMatchAllWordForms( sal_Bool _matchallwordforms ) override; + virtual css::uno::Any SAL_CALL getStyle() override; + virtual void SAL_CALL setStyle( const css::uno::Any& _style ) override; + + // Methods + virtual sal_Bool SAL_CALL Execute( const css::uno::Any& FindText, const css::uno::Any& MatchCase, const css::uno::Any& MatchWholeWord, const css::uno::Any& MatchWildcards, const css::uno::Any& MatchSoundsLike, const css::uno::Any& MatchAllWordForms, const css::uno::Any& Forward, const css::uno::Any& Wrap, const css::uno::Any& Format, const css::uno::Any& ReplaceWith, const css::uno::Any& Replace, const css::uno::Any& MatchKashida, const css::uno::Any& MatchDiacritics, const css::uno::Any& MatchAlefHamza, const css::uno::Any& MatchControl, const css::uno::Any& MatchPrefix, const css::uno::Any& MatchSuffix, const css::uno::Any& MatchPhrase, const css::uno::Any& IgnoreSpace, const css::uno::Any& IgnorePunct ) override; + virtual void SAL_CALL ClearFormatting( ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAFIND_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbafont.cxx b/sw/source/ui/vba/vbafont.cxx new file mode 100644 index 0000000000..91a31ec664 --- /dev/null +++ b/sw/source/ui/vba/vbafont.cxx @@ -0,0 +1,235 @@ +/* -*- 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 "vbafont.hxx" +#include <com/sun/star/awt/FontUnderline.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <ooo/vba/word/WdUnderline.hpp> +#include <sal/macros.h> +#include <unordered_map> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +const uno::Any aLongAnyTrue( sal_Int16(-1) ); +const uno::Any aLongAnyFalse( sal_Int16( 0 ) ); + +namespace { + +struct MapPair +{ + sal_Int32 nMSOConst; + sal_Int32 nOOOConst; +}; + +} + +MapPair const UnderLineTable[] = { + { word::WdUnderline::wdUnderlineNone, css::awt::FontUnderline::NONE }, + { word::WdUnderline::wdUnderlineSingle, css::awt::FontUnderline::SINGLE }, + { word::WdUnderline::wdUnderlineWords, css::awt::FontUnderline::SINGLE }, + { word::WdUnderline::wdUnderlineDouble, css::awt::FontUnderline::DOUBLE }, + { word::WdUnderline::wdUnderlineDotted, css::awt::FontUnderline::DOTTED }, + { word::WdUnderline::wdUnderlineThick, css::awt::FontUnderline::BOLDDASH }, + { word::WdUnderline::wdUnderlineDash, css::awt::FontUnderline::DASH }, + { word::WdUnderline::wdUnderlineDotDash, css::awt::FontUnderline::DASHDOT }, + { word::WdUnderline::wdUnderlineDotDotDash, css::awt::FontUnderline::DASHDOTDOT }, + { word::WdUnderline::wdUnderlineWavy, css::awt::FontUnderline::WAVE }, + { word::WdUnderline::wdUnderlineDottedHeavy, css::awt::FontUnderline::BOLDDOTTED }, + { word::WdUnderline::wdUnderlineDashHeavy, css::awt::FontUnderline::BOLDDASH }, + { word::WdUnderline::wdUnderlineDotDashHeavy, css::awt::FontUnderline::BOLDDASHDOT }, + { word::WdUnderline::wdUnderlineDotDotDashHeavy, css::awt::FontUnderline::BOLDDASHDOTDOT }, + { word::WdUnderline::wdUnderlineWavyHeavy, css::awt::FontUnderline::BOLDWAVE }, + { word::WdUnderline::wdUnderlineDashLong, css::awt::FontUnderline::LONGDASH }, + { word::WdUnderline::wdUnderlineWavyDouble, css::awt::FontUnderline::DOUBLEWAVE }, + { word::WdUnderline::wdUnderlineDashLongHeavy, css::awt::FontUnderline::BOLDLONGDASH }, +}; + +typedef std::unordered_map< sal_Int32, sal_Int32 > ConstToConst; + +namespace { + +class UnderLineMapper +{ + ConstToConst m_MSO2OOO; + ConstToConst m_OOO2MSO; +private: + UnderLineMapper() + { + for ( auto const & index: UnderLineTable ) + { + m_MSO2OOO[ index.nMSOConst ] = index.nOOOConst; + m_OOO2MSO[ index.nOOOConst ] = index.nMSOConst; + } + } +public: + static OUString propName() + { + return "CharUnderline"; + } + + static UnderLineMapper& instance() + { + static UnderLineMapper theMapper; + return theMapper; + } + + /// @throws lang::IllegalArgumentException + sal_Int32 getOOOFromMSO( sal_Int32 nMSOConst ) + { + ConstToConst::iterator it = m_MSO2OOO.find( nMSOConst ); + if ( it == m_MSO2OOO.end() ) + throw lang::IllegalArgumentException(); + return it->second; + } + /// @throws lang::IllegalArgumentException + sal_Int32 getMSOFromOOO( sal_Int32 nOOOConst ) + { + ConstToConst::iterator it = m_OOO2MSO.find( nOOOConst ); + if ( it == m_OOO2MSO.end() ) + throw lang::IllegalArgumentException(); + return it->second; + } +}; + +} + +SwVbaFont::SwVbaFont( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xPalette, uno::Reference< css::beans::XPropertySet > const & xPropertySet ) + : SwVbaFont_BASE( xParent, xContext, xPalette, xPropertySet, Component::WORD ) +{ +} + +uno::Any SAL_CALL +SwVbaFont::getUnderline() +{ + sal_Int32 nOOVal = 0; + mxFont->getPropertyValue( UnderLineMapper::propName() ) >>= nOOVal; + return uno::Any( UnderLineMapper::instance().getMSOFromOOO( nOOVal ) ); +} + +void SAL_CALL +SwVbaFont::setUnderline( const uno::Any& _underline ) +{ + sal_Int32 nMSOVal = 0; + + if ( _underline >>= nMSOVal ) + { + sal_Int32 nOOVal = UnderLineMapper::instance().getOOOFromMSO( nMSOVal ); + mxFont->setPropertyValue( UnderLineMapper::propName(), uno::Any( nOOVal ) ); + } +} + +OUString +SwVbaFont::getServiceImplName() +{ + return "SwVbaFont"; +} + +uno::Any SAL_CALL +SwVbaFont::getColorIndex() +{ + sal_Int32 nColor = 0; + + getColor() >>= nColor; + sal_Int32 nElems = mxPalette->getCount(); + sal_Int32 nIndex = 0; + for ( sal_Int32 count=0; count<nElems; ++count ) + { + sal_Int32 nPaletteColor = 0; + mxPalette->getByIndex( count ) >>= nPaletteColor; + if ( nPaletteColor == nColor ) + { + nIndex = count; + break; + } + } + return uno::Any( nIndex ); +} +uno::Any SAL_CALL +SwVbaFont::getSubscript() +{ + bool bRes = false; + SwVbaFont_BASE::getSubscript() >>= bRes; + if ( bRes ) + return aLongAnyTrue; + return aLongAnyFalse; +} + +uno::Any SAL_CALL +SwVbaFont::getSuperscript() +{ + bool bRes = false; + SwVbaFont_BASE::getSuperscript() >>= bRes; + if ( bRes ) + return aLongAnyTrue; + return aLongAnyFalse; +} + +uno::Any SAL_CALL +SwVbaFont::getBold() +{ + bool bRes = false; + SwVbaFont_BASE::getBold() >>= bRes; + if ( bRes ) + return aLongAnyTrue; + return aLongAnyFalse; +} + +uno::Any SAL_CALL +SwVbaFont::getItalic() +{ + bool bRes = false; + SwVbaFont_BASE::getItalic() >>= bRes; + if ( bRes ) + return aLongAnyTrue; + return aLongAnyFalse; +} + +uno::Any SAL_CALL +SwVbaFont::getStrikethrough() +{ + bool bRes = false; + SwVbaFont_BASE::getStrikethrough() >>= bRes; + if ( bRes ) + return aLongAnyTrue; + return aLongAnyFalse; +} + +uno::Any SAL_CALL +SwVbaFont::getShadow() +{ + bool bRes = false; + SwVbaFont_BASE::getShadow() >>= bRes; + if ( bRes ) + return aLongAnyTrue; + return aLongAnyFalse; +} + +uno::Sequence< OUString > +SwVbaFont::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Font" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbafont.hxx b/sw/source/ui/vba/vbafont.hxx new file mode 100644 index 0000000000..61bfc0f526 --- /dev/null +++ b/sw/source/ui/vba/vbafont.hxx @@ -0,0 +1,49 @@ +/* -*- 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 <vbahelper/vbafontbase.hxx> +#include <ooo/vba/word/XFont.hpp> +#include <cppuhelper/implbase.hxx> + +typedef cppu::ImplInheritanceHelper< VbaFontBase, ov::word::XFont > SwVbaFont_BASE; + +class SwVbaFont : public SwVbaFont_BASE +{ +public: + /// @throws css::uno::RuntimeException + SwVbaFont( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xPalette, css::uno::Reference< css::beans::XPropertySet > const & xPropertySet ); + + // Attributes + virtual css::uno::Any SAL_CALL getColorIndex() override; + virtual css::uno::Any SAL_CALL getUnderline() override; + virtual void SAL_CALL setUnderline( const css::uno::Any& _underline ) override; + virtual css::uno::Any SAL_CALL getSubscript() override; + virtual css::uno::Any SAL_CALL getSuperscript() override; + + virtual css::uno::Any SAL_CALL getBold() override; + virtual css::uno::Any SAL_CALL getItalic() override; + virtual css::uno::Any SAL_CALL getStrikethrough() override; + virtual css::uno::Any SAL_CALL getShadow() override; + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfield.cxx b/sw/source/ui/vba/vbaformfield.cxx new file mode 100644 index 0000000000..cb1351fa74 --- /dev/null +++ b/sw/source/ui/vba/vbaformfield.cxx @@ -0,0 +1,255 @@ +/* -*- 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/. + */ + +#include <ooo/vba/word/WdFieldType.hpp> + +#include <sal/log.hxx> + +#include <doc.hxx> +#include <docsh.hxx> +#include <unotextrange.hxx> + +#include "vbaformfield.hxx" +#include "vbaformfieldcheckbox.hxx" +#include "vbaformfielddropdown.hxx" +#include "vbaformfieldtextinput.hxx" +#include "vbarange.hxx" +#include "wordvbahelper.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +/** + * FormFields are inline text objects that are only found in MS Word. + * They cannot be created in Excel or in Calc. + * + * There are three specific kinds of FormFields: CheckBox, DropDown, and TextInput. + */ +SwVbaFormField::SwVbaFormField(const uno::Reference<ooo::vba::XHelperInterface>& rParent, + const uno::Reference<uno::XComponentContext>& rContext, + const uno::Reference<text::XTextDocument>& xTextDocument, + sw::mark::IFieldmark& rFormField) + : SwVbaFormField_BASE(rParent, rContext) + , m_xTextDocument(xTextDocument) + , m_rFormField(rFormField) +{ +} + +SwVbaFormField::~SwVbaFormField() {} + +uno::Any SwVbaFormField::CheckBox() +{ + return uno::Any(uno::Reference<word::XCheckBox>( + new SwVbaFormFieldCheckBox(mxParent, mxContext, m_rFormField))); +} + +uno::Any SwVbaFormField::DropDown() +{ + return uno::Any(uno::Reference<word::XDropDown>( + new SwVbaFormFieldDropDown(mxParent, mxContext, m_rFormField))); +} + +uno::Any SwVbaFormField::TextInput() +{ + return uno::Any(uno::Reference<word::XTextInput>( + new SwVbaFormFieldTextInput(mxParent, mxContext, m_rFormField))); +} + +uno::Any SwVbaFormField::Previous() +{ + SwDoc* pDoc = word::getDocShell(m_xTextDocument)->GetDoc(); + if (!pDoc) + return uno::Any(); + + const IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + if (!pMarkAccess) + return uno::Any(); + + sw::mark::IFieldmark* pFieldMark = pMarkAccess->getFieldmarkBefore(m_rFormField.GetMarkPos(), + /*bLoop=*/false); + + // DateFields are a LO specialty, and do not exist natively in MS documents. Ignore if added... + auto pDateField = dynamic_cast<sw::mark::IDateFieldmark*>(pFieldMark); + while (pDateField) + { + pFieldMark = pMarkAccess->getFieldmarkBefore(pDateField->GetMarkPos(), /*bLoop=*/false); + pDateField = dynamic_cast<sw::mark::IDateFieldmark*>(pFieldMark); + } + + if (!pFieldMark) + return uno::Any(); + + return uno::Any(uno::Reference<word::XFormField>( + new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldMark))); +} + +uno::Any SwVbaFormField::Next() +{ + SwDoc* pDoc = word::getDocShell(m_xTextDocument)->GetDoc(); + if (!pDoc) + return uno::Any(); + + const IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + if (!pMarkAccess) + return uno::Any(); + + sw::mark::IFieldmark* pFieldMark = pMarkAccess->getFieldmarkAfter(m_rFormField.GetMarkPos(), + /*bLoop=*/false); + + // DateFields are a LO specialty, and do not exist natively in MS documents. Ignore if added... + auto pDateField = dynamic_cast<sw::mark::IDateFieldmark*>(pFieldMark); + while (pDateField) + { + pFieldMark = pMarkAccess->getFieldmarkAfter(pDateField->GetMarkPos(), /*bLoop=*/false); + pDateField = dynamic_cast<sw::mark::IDateFieldmark*>(pFieldMark); + } + + if (!pFieldMark) + return uno::Any(); + + return uno::Any(uno::Reference<word::XFormField>( + new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldMark))); +} + +uno::Reference<word::XRange> SwVbaFormField::Range() +{ + uno::Reference<word::XRange> xRet; + SwDoc* pDoc = word::getDocShell(m_xTextDocument)->GetDoc(); + if (pDoc) + { + rtl::Reference<SwXTextRange> xText(SwXTextRange::CreateXTextRange( + *pDoc, m_rFormField.GetMarkStart(), &m_rFormField.GetMarkEnd())); + if (xText.is()) + xRet = new SwVbaRange(mxParent, mxContext, m_xTextDocument, xText->getStart(), + xText->getEnd()); + } + return xRet; +} + +OUString SwVbaFormField::getDefaultPropertyName() { return "Type"; } + +sal_Int32 SwVbaFormField::getType() +{ + IDocumentMarkAccess::MarkType aType = IDocumentMarkAccess::GetType(m_rFormField); + if (aType == IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK) + return ooo::vba::word::WdFieldType::wdFieldFormCheckBox; + else if (aType == IDocumentMarkAccess::MarkType::TEXT_FIELDMARK) + return ooo::vba::word::WdFieldType::wdFieldFormTextInput; + return ooo::vba::word::WdFieldType::wdFieldFormDropDown; +} + +sal_Bool SwVbaFormField::getCalculateOnExit() +{ + SAL_INFO("sw.vba", "SwVbaFormField::getCalculateOnExit stub"); + return false; +} + +void SwVbaFormField::setCalculateOnExit(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaFormField::setCalculateOnExit stub"); +} + +sal_Bool SwVbaFormField::getEnabled() +{ + SAL_INFO("sw.vba", "SwVbaFormField::getEnabled stub"); + return true; +} + +void SwVbaFormField::setEnabled(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaFormField::setEnabled stub"); +} + +OUString SwVbaFormField::getEntryMacro() +{ + OUString sMacro; + (*m_rFormField.GetParameters())["EntryMacro"] >>= sMacro; + return sMacro; +} + +void SwVbaFormField::setEntryMacro(const OUString& rSet) +{ + (*m_rFormField.GetParameters())["EntryMacro"] <<= rSet; +} + +OUString SwVbaFormField::getExitMacro() +{ + OUString sMacro; + (*m_rFormField.GetParameters())["ExitMacro"] >>= sMacro; + return sMacro; +} + +void SwVbaFormField::setExitMacro(const OUString& rSet) +{ + (*m_rFormField.GetParameters())["ExitMacro"] <<= rSet; +} + +OUString SwVbaFormField::getHelpText() { return m_rFormField.GetFieldHelptext(); } + +void SwVbaFormField::setHelpText(const OUString& rSet) { m_rFormField.SetFieldHelptext(rSet); } + +sal_Bool SwVbaFormField::getOwnHelp() +{ + SAL_INFO("sw.vba", "SwVbaFormField::getOwnHelp stub"); + return true; +} + +void SwVbaFormField::setOwnHelp(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaFormField::setOwnHelp stub"); +} + +OUString SwVbaFormField::getName() { return m_rFormField.GetName(); } + +void SwVbaFormField::setName(const OUString& rSet) +{ + SAL_INFO("sw.vba", "SwVbaFormField::setName[" << rSet << "] stub"); +} + +OUString SwVbaFormField::getResult() { return m_rFormField.GetContent(); } + +void SwVbaFormField::setResult(const OUString& rSet) +{ + if (dynamic_cast<sw::mark::ICheckboxFieldmark*>(&m_rFormField)) + m_rFormField.ReplaceContent("false"); + else + m_rFormField.ReplaceContent(rSet); +} + +OUString SwVbaFormField::getStatusText() +{ + SAL_INFO("sw.vba", "SwVbaFormField::getStatusText stub"); + return OUString(); +} + +void SwVbaFormField::setStatusText(const OUString& rSet) +{ + SAL_INFO("sw.vba", "SwVbaFormField::setStatusText[" << rSet << "] stub"); +} + +sal_Bool SwVbaFormField::getOwnStatus() +{ + SAL_INFO("sw.vba", "SwVbaFormField::getOwnStatus stub"); + return true; +} + +void SwVbaFormField::setOwnStatus(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaFormField::setOwnStatus stub"); +} + +OUString SwVbaFormField::getServiceImplName() { return "SwVbaFormField"; } + +uno::Sequence<OUString> SwVbaFormField::getServiceNames() +{ + static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.FormField" }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfield.hxx b/sw/source/ui/vba/vbaformfield.hxx new file mode 100644 index 0000000000..260e790935 --- /dev/null +++ b/sw/source/ui/vba/vbaformfield.hxx @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include <com/sun/star/text/XTextDocument.hpp> +#include <ooo/vba/word/XFormField.hpp> + +#include <vbahelper/vbahelperinterface.hxx> + +#include <IDocumentMarkAccess.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XFormField> SwVbaFormField_BASE; + +class SwVbaFormField : public SwVbaFormField_BASE +{ +private: + css::uno::Reference<css::text::XTextDocument> m_xTextDocument; + sw::mark::IFieldmark& m_rFormField; + +public: + /// @throws css::uno::RuntimeException + SwVbaFormField(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, + const uno::Reference<text::XTextDocument>& xTextDocument, + sw::mark::IFieldmark& rFormField); + ~SwVbaFormField() override; + + // XFormField Methods + OUString SAL_CALL getDefaultPropertyName() override; + + css::uno::Any SAL_CALL CheckBox() override; + css::uno::Any SAL_CALL DropDown() override; + css::uno::Any SAL_CALL TextInput() override; + css::uno::Any SAL_CALL Previous() override; + css::uno::Any SAL_CALL Next() override; + css::uno::Reference<ooo::vba::word::XRange> SAL_CALL Range() override; + + // Indicates which of the three form fields this is: oovbaapi/ooo/vba/word/WdFieldType.idl + sal_Int32 SAL_CALL getType() override; + // True if references to the specified form field + // are automatically updated whenever the field is exited + sal_Bool SAL_CALL getCalculateOnExit() override; + void SAL_CALL setCalculateOnExit(sal_Bool bSet) override; + sal_Bool SAL_CALL getEnabled() override; + void SAL_CALL setEnabled(sal_Bool bSet) override; + OUString SAL_CALL getEntryMacro() override; + void SAL_CALL setEntryMacro(const OUString& rSet) override; + OUString SAL_CALL getExitMacro() override; + void SAL_CALL setExitMacro(const OUString& rSet) override; + /* + * If the OwnHelp property is set to True, + * HelpText specifies the text string value. + * If OwnHelp is set to False, HelpText specifies the name of an AutoText entry + * that contains help text for the form field. + */ + OUString SAL_CALL getHelpText() override; + void SAL_CALL setHelpText(const OUString& rSet) override; + sal_Bool SAL_CALL getOwnHelp() override; + void SAL_CALL setOwnHelp(sal_Bool bSet) override; + + OUString SAL_CALL getName() override; + void SAL_CALL setName(const OUString& rSet) override; + OUString SAL_CALL getResult() override; + void SAL_CALL setResult(const OUString& rSet) override; + /* + * If the OwnStatus property is set to True, + * StatusText specifies the status bar value. + * If OwnStatus is set to False, StatusText specifies the name of an AutoText entry + * that contains status bar text for the form field. + */ + OUString SAL_CALL getStatusText() override; + void SAL_CALL setStatusText(const OUString& rSet) override; + sal_Bool SAL_CALL getOwnStatus() override; + void SAL_CALL setOwnStatus(sal_Bool bSet) override; + + // XHelperInterface + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfieldcheckbox.cxx b/sw/source/ui/vba/vbaformfieldcheckbox.cxx new file mode 100644 index 0000000000..5a32e7e426 --- /dev/null +++ b/sw/source/ui/vba/vbaformfieldcheckbox.cxx @@ -0,0 +1,117 @@ +/* -*- 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/. + */ + +#include <sal/log.hxx> + +#include "vbaformfieldcheckbox.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +/** + * CheckBoxes are inline text objects that are only found in MS Word. + * They cannot be created in Excel or in Calc. + * + * Note that VBA might call this a Checkbox, but it might not actually be one, + * so make good use of getValid() + */ +SwVbaFormFieldCheckBox::SwVbaFormFieldCheckBox( + const uno::Reference<ooo::vba::XHelperInterface>& rParent, + const uno::Reference<uno::XComponentContext>& rContext, sw::mark::IFieldmark& rFormField) + : SwVbaFormFieldCheckBox_BASE(rParent, rContext) + , m_pCheckBox(dynamic_cast<sw::mark::ICheckboxFieldmark*>(&rFormField)) +{ +} + +SwVbaFormFieldCheckBox::~SwVbaFormFieldCheckBox() {} + +OUString SwVbaFormFieldCheckBox::getDefaultPropertyName() { return "Valid"; } + +sal_Bool SwVbaFormFieldCheckBox::getValid() +{ + return m_pCheckBox + && IDocumentMarkAccess::GetType(*m_pCheckBox) + == IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK; +} + +sal_Bool SwVbaFormFieldCheckBox::getAutoSize() +{ + if (!getValid()) + return false; + + SAL_INFO("sw.vba", "SwVbaFormFieldCheckBox::getAutoSize stub"); + return true; +} + +void SwVbaFormFieldCheckBox::setAutoSize(sal_Bool /*bSet*/) +{ + if (!getValid()) + return; + + SAL_INFO("sw.vba", "SwVbaFormFieldCheckBox::setAutoSize stub"); +} + +sal_Bool SwVbaFormFieldCheckBox::getDefault() +{ + if (!getValid()) + return false; + + return getValue(); +} + +void SwVbaFormFieldCheckBox::setDefault(sal_Bool bSet) +{ + if (!getValid()) + return; + + // Hard to know what to do here, since LO doesn't have a default property for checkboxes. + // Setting this really only makes sense when macro-adding a checkbox. + // In that case, we want it to affect the actual checkbox. + // However, if the checkbox has already been set by the user, then this shouldn't do anything. + // Assuming this is only ever called when adding a checkbox seems the sanest approach. + setValue(bSet); +} + +// Returns the size of a check box, in points +sal_Int32 SwVbaFormFieldCheckBox::getSize() +{ + if (!getValid()) + return 0; + + SAL_INFO("sw.vba", "SwVbaFormFieldCheckBox::getSize stub"); + return 11; +} + +void SwVbaFormFieldCheckBox::setSize(sal_Int32 nSet) +{ + if (!getValid()) + return; + + SAL_INFO("sw.vba", "SwVbaFormFieldCheckBox::setSize[" << nSet << "] stub"); +} + +sal_Bool SwVbaFormFieldCheckBox::getValue() { return getValid() && m_pCheckBox->IsChecked(); } + +void SwVbaFormFieldCheckBox::setValue(sal_Bool bSet) +{ + if (!getValid() || !getValue() == !bSet) + return; + + m_pCheckBox->SetChecked(bSet); +} + +OUString SwVbaFormFieldCheckBox::getServiceImplName() { return "SwVbaFormFieldCheckBox"; } + +uno::Sequence<OUString> SwVbaFormFieldCheckBox::getServiceNames() +{ + static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.CheckBox" }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfieldcheckbox.hxx b/sw/source/ui/vba/vbaformfieldcheckbox.hxx new file mode 100644 index 0000000000..c62549585b --- /dev/null +++ b/sw/source/ui/vba/vbaformfieldcheckbox.hxx @@ -0,0 +1,54 @@ +/* -*- 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/. + */ +#pragma once + +#include <ooo/vba/word/XCheckBox.hpp> + +#include <vbahelper/vbahelperinterface.hxx> + +#include <IDocumentMarkAccess.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XCheckBox> SwVbaFormFieldCheckBox_BASE; + +class SwVbaFormFieldCheckBox : public SwVbaFormFieldCheckBox_BASE +{ +private: + sw::mark::ICheckboxFieldmark* m_pCheckBox; + +public: + /// @throws css::uno::RuntimeException + SwVbaFormFieldCheckBox(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, + sw::mark::IFieldmark& rFormField); + ~SwVbaFormFieldCheckBox() override; + + // XCheckBox + OUString SAL_CALL getDefaultPropertyName() override; + + // Default member: True if the specified form field object is a valid check box form field + sal_Bool SAL_CALL getValid() override; + + sal_Bool SAL_CALL getAutoSize() override; + void SAL_CALL setAutoSize(sal_Bool bSet) override; + // Returns the default check box value + sal_Bool SAL_CALL getDefault() override; + void SAL_CALL setDefault(sal_Bool bSet) override; + // Returns the size of a check box, in points + sal_Int32 SAL_CALL getSize() override; + void SAL_CALL setSize(sal_Int32 nSet) override; + + sal_Bool SAL_CALL getValue() override; + void SAL_CALL setValue(sal_Bool bSet) override; + + // XHelperInterface + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfielddropdown.cxx b/sw/source/ui/vba/vbaformfielddropdown.cxx new file mode 100644 index 0000000000..f1edc81403 --- /dev/null +++ b/sw/source/ui/vba/vbaformfielddropdown.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/. + */ + +#include <ooo/vba/word/WdTextFormFieldType.hpp> + +#include "vbaformfielddropdown.hxx" +#include "vbaformfielddropdownlistentries.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +/** + * DropDown formfields are inline text objects that are only found in MS Word. + * They cannot be created in Excel or in Calc. + * + * Note that VBA might call this a DropDown, but it might not actually be one, + * so make good use of getValid() + */ +SwVbaFormFieldDropDown::SwVbaFormFieldDropDown( + const uno::Reference<ooo::vba::XHelperInterface>& rParent, + const uno::Reference<uno::XComponentContext>& rContext, ::sw::mark::IFieldmark& rFormField) + : SwVbaFormFieldDropDown_BASE(rParent, rContext) + , m_pDropDown(dynamic_cast<sw::mark::IDropdownFieldmark*>(&rFormField)) +{ +} + +SwVbaFormFieldDropDown::~SwVbaFormFieldDropDown() {} + +OUString SwVbaFormFieldDropDown::getDefaultPropertyName() { return "Valid"; } + +sal_Bool SwVbaFormFieldDropDown::getValid() +{ + return m_pDropDown + && IDocumentMarkAccess::GetType(*m_pDropDown) + == IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK; +} + +sal_Int32 SwVbaFormFieldDropDown::getDefault() { return getValue(); } + +void SwVbaFormFieldDropDown::setDefault(sal_Int32 nSet) +{ + // Hard to know what to do here, since LO doesn't have a default property for DropDowns. + // Setting this really only makes sense when macro-adding a DropDown. + // In that case, we want it to affect the actual text content. + // However, if an item has already been selected by the user, then this shouldn't do anything. + // Assuming this is only ever set when adding a DropDown seems the sanest approach. + setValue(nSet); +} + +sal_Int32 SwVbaFormFieldDropDown::getValue() +{ + sal_Int32 nRet = 0; + if (!getValid()) + return nRet; + + --nRet; // send -1, which requests being changed to the selected DropDown's zero-based index + m_pDropDown->GetContent(&nRet); + return nRet + 1; +} + +void SwVbaFormFieldDropDown::setValue(sal_Int32 nIndex) +{ + if (!getValid() || nIndex == getValue()) + return; + + // switch to zero-based index for implementation + --nIndex; + m_pDropDown->ReplaceContent(/*pText=*/nullptr, &nIndex); +} + +uno::Any SwVbaFormFieldDropDown::ListEntries(const uno::Any& rIndex) +{ + if (!getValid()) + return uno::Any(); + + uno::Reference<XCollection> xCol( + new SwVbaFormFieldDropDownListEntries(this, mxContext, *m_pDropDown)); + + if (rIndex.hasValue()) + return xCol->Item(rIndex, uno::Any()); + + return uno::Any(xCol); +} + +OUString SwVbaFormFieldDropDown::getServiceImplName() { return "SwVbaFormFieldDropDown"; } + +uno::Sequence<OUString> SwVbaFormFieldDropDown::getServiceNames() +{ + static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.DropDown" }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfielddropdown.hxx b/sw/source/ui/vba/vbaformfielddropdown.hxx new file mode 100644 index 0000000000..e92caa2f8e --- /dev/null +++ b/sw/source/ui/vba/vbaformfielddropdown.hxx @@ -0,0 +1,52 @@ +/* -*- 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/. + */ +#pragma once + +#include <ooo/vba/word/XDropDown.hpp> + +#include <vbahelper/vbahelperinterface.hxx> + +#include <IDocumentMarkAccess.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XDropDown> SwVbaFormFieldDropDown_BASE; + +class SwVbaFormFieldDropDown : public SwVbaFormFieldDropDown_BASE +{ +private: + sw::mark::IDropdownFieldmark* m_pDropDown; + +public: + /// @throws css::uno::RuntimeException + SwVbaFormFieldDropDown(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, + sw::mark::IFieldmark& rFormField); + ~SwVbaFormFieldDropDown() override; + + // XDropDown + OUString SAL_CALL getDefaultPropertyName() override; + + // Default member: True if the specified form field object is a valid listbox field + sal_Bool SAL_CALL getValid() override; + + // Returns and sets the index for the default listbox entry + sal_Int32 SAL_CALL getDefault() override; + void SAL_CALL setDefault(sal_Int32 nSet) override; + // Returns and sets the index of the selected listbox entry + sal_Int32 SAL_CALL getValue() override; + void SAL_CALL setValue(sal_Int32 nIndex) override; + + // Returns a ListEntries collection that represents all the available entries + css::uno::Any SAL_CALL ListEntries(const css::uno::Any& rIndex) override; + + // XHelperInterface + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfielddropdownlistentries.cxx b/sw/source/ui/vba/vbaformfielddropdownlistentries.cxx new file mode 100644 index 0000000000..c167e16d78 --- /dev/null +++ b/sw/source/ui/vba/vbaformfielddropdownlistentries.cxx @@ -0,0 +1,162 @@ +/* -*- 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/. + */ + +#include <xmloff/odffields.hxx> + +#include "vbaformfielddropdownlistentries.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +static uno::Sequence<OUString> lcl_getListEntries(sw::mark::IDropdownFieldmark& rDropDown) +{ + uno::Sequence<OUString> aSeq; + (*rDropDown.GetParameters())[ODF_FORMDROPDOWN_LISTENTRY] >>= aSeq; + return aSeq; +} + +namespace +{ +class ListEntriesEnumWrapper : public EnumerationHelper_BASE +{ + uno::Reference<container::XIndexAccess> mxIndexAccess; + sal_Int32 mnIndex; + +public: + explicit ListEntriesEnumWrapper(uno::Reference<container::XIndexAccess> xIndexAccess) + : mxIndexAccess(xIndexAccess) + , mnIndex(0) + { + } + + sal_Bool SAL_CALL hasMoreElements() override { return (mnIndex < mxIndexAccess->getCount()); } + + uno::Any SAL_CALL nextElement() override + { + if (mnIndex < mxIndexAccess->getCount()) + { + return mxIndexAccess->getByIndex(mnIndex++); + } + throw container::NoSuchElementException(); + } +}; + +class ListEntryCollectionHelper + : public ::cppu::WeakImplHelper<container::XIndexAccess, container::XEnumerationAccess> +{ +private: + uno::Reference<XHelperInterface> mxParent; + uno::Reference<uno::XComponentContext> mxContext; + sw::mark::IDropdownFieldmark& m_rDropDown; + +public: + /// @throws css::uno::RuntimeException + ListEntryCollectionHelper(uno::Reference<ov::XHelperInterface> xParent, + uno::Reference<uno::XComponentContext> xContext, + sw::mark::IDropdownFieldmark& rFormField) + : mxParent(xParent) + , mxContext(xContext) + , m_rDropDown(rFormField) + { + } + + sal_Int32 SAL_CALL getCount() override { return lcl_getListEntries(m_rDropDown).getLength(); } + + uno::Any SAL_CALL getByIndex(sal_Int32 Index) override + { + if (Index < 0 || Index >= getCount()) + throw lang::IndexOutOfBoundsException(); + + return uno::Any(uno::Reference<word::XListEntry>( + new SwVbaFormFieldDropDownListEntry(mxParent, mxContext, m_rDropDown, Index))); + } + + uno::Type SAL_CALL getElementType() override { return cppu::UnoType<word::XListEntry>::get(); } + + sal_Bool SAL_CALL hasElements() override { return getCount() != 0; } + + // XEnumerationAccess + uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override + { + return new ListEntriesEnumWrapper(this); + } +}; +} + +SwVbaFormFieldDropDownListEntries::SwVbaFormFieldDropDownListEntries( + const uno::Reference<XHelperInterface>& xParent, + const uno::Reference<uno::XComponentContext>& xContext, + sw::mark::IDropdownFieldmark& rFormField) + : SwVbaFormFieldDropDownListEntries_BASE( + xParent, xContext, + uno::Reference<container::XIndexAccess>( + new ListEntryCollectionHelper(xParent, xContext, rFormField))) + , m_rDropDown(rFormField) +{ +} + +// XListEntries +uno::Reference<word::XListEntry> SwVbaFormFieldDropDownListEntries::Add(const OUString& rName, + const uno::Any& rIndex) +{ + sal_Int32 nZIndex = 0; + rIndex >>= nZIndex; + // rIndex is 1-based, nZIndex is 0-based. If rIndex is not given, then add as the last choice. + + // In testing with Word 2010, this gives a compile error: 'ListEntries.Add("Name", 2)' + // This compiles, but gets an unsupported runtime error: 'ListEntries.Add("Name", 2) = "Choice' + // So the only thing that actually works is to simply append: 'ListEntires.Add("Name")' + // but I'll still keep the expected implementation for the broken case. + if (!nZIndex) + nZIndex = SAL_MAX_INT32; + else + --nZIndex; + m_rDropDown.AddContent(rName + "__allowDuplicates", &nZIndex); + m_rDropDown.ReplaceContent(&rName, &nZIndex); + + return uno::Reference<word::XListEntry>( + new SwVbaFormFieldDropDownListEntry(mxParent, mxContext, m_rDropDown, nZIndex)); +} + +void SwVbaFormFieldDropDownListEntries::Clear() { m_rDropDown.DelContent(); } + +sal_Int32 SwVbaFormFieldDropDownListEntries::getCount() +{ + return lcl_getListEntries(m_rDropDown).getLength(); +} + +// XEnumerationAccess +uno::Type SwVbaFormFieldDropDownListEntries::getElementType() +{ + return cppu::UnoType<word::XListEntry>::get(); +} + +uno::Reference<container::XEnumeration> SwVbaFormFieldDropDownListEntries::createEnumeration() +{ + return new ListEntriesEnumWrapper(m_xIndexAccess); +} + +// SwVbadropDownListEntries_BASE +uno::Any SwVbaFormFieldDropDownListEntries::createCollectionObject(const uno::Any& aSource) +{ + return aSource; +} + +OUString SwVbaFormFieldDropDownListEntries::getServiceImplName() +{ + return "SwVbaFormFieldDropDownListEntries"; +} + +uno::Sequence<OUString> SwVbaFormFieldDropDownListEntries::getServiceNames() +{ + static uno::Sequence<OUString> const sNames{ "ooo.vba.word.ListEntries" }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfielddropdownlistentries.hxx b/sw/source/ui/vba/vbaformfielddropdownlistentries.hxx new file mode 100644 index 0000000000..ef13391270 --- /dev/null +++ b/sw/source/ui/vba/vbaformfielddropdownlistentries.hxx @@ -0,0 +1,49 @@ +/* -*- 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/. + */ +#pragma once + +#include <ooo/vba/word/XListEntries.hpp> +#include <ooo/vba/word/XListEntry.hpp> + +#include <vbahelper/vbacollectionimpl.hxx> + +#include "vbaformfielddropdownlistentries.hxx" +#include "vbaformfielddropdownlistentry.hxx" + +typedef CollTestImplHelper<ooo::vba::word::XListEntries> SwVbaFormFieldDropDownListEntries_BASE; + +class SwVbaFormFieldDropDownListEntries : public SwVbaFormFieldDropDownListEntries_BASE +{ +private: + sw::mark::IDropdownFieldmark& m_rDropDown; + +public: + /// @throws css::uno::RuntimeException + SwVbaFormFieldDropDownListEntries( + const css::uno::Reference<ov::XHelperInterface>& xParent, + const css::uno::Reference<css::uno::XComponentContext>& xContext, + sw::mark::IDropdownFieldmark& m_rDropDown); + + // XListEntries + css::uno::Reference<ooo::vba::word::XListEntry> + SAL_CALL Add(const OUString& rName, const css::uno::Any& rIndex) override; + void SAL_CALL Clear() override; + sal_Int32 SAL_CALL getCount() override; + + // XEnumerationAccess + css::uno::Type SAL_CALL getElementType() override; + css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override; + + // SwVbaFormFieldDropDownListEntries_BASE + css::uno::Any createCollectionObject(const css::uno::Any& aSource) override; + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfielddropdownlistentry.cxx b/sw/source/ui/vba/vbaformfielddropdownlistentry.cxx new file mode 100644 index 0000000000..bc02439ed5 --- /dev/null +++ b/sw/source/ui/vba/vbaformfielddropdownlistentry.cxx @@ -0,0 +1,56 @@ +/* -*- 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/. + */ + +#include "vbaformfielddropdownlistentry.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaFormFieldDropDownListEntry::SwVbaFormFieldDropDownListEntry( + const uno::Reference<ooo::vba::XHelperInterface>& rParent, + const uno::Reference<uno::XComponentContext>& rContext, + sw::mark::IDropdownFieldmark& rFormField, sal_Int32 nZIndex) + : SwVbaFormFieldDropDownListEntry_BASE(rParent, rContext) + , m_rDropDown(rFormField) + , m_nZIndex(nZIndex) +{ +} + +SwVbaFormFieldDropDownListEntry::~SwVbaFormFieldDropDownListEntry() {} + +// XListEntry +sal_Int32 SwVbaFormFieldDropDownListEntry::getIndex() { return m_nZIndex + 1; } + +OUString SwVbaFormFieldDropDownListEntry::getName() +{ + sal_Int32 nZIndex = m_nZIndex; + return m_rDropDown.GetContent(&nZIndex); +} + +void SwVbaFormFieldDropDownListEntry::setName(const OUString& rSet) +{ + sal_Int32 nZIndex = m_nZIndex; + m_rDropDown.ReplaceContent(&rSet, &nZIndex); +} + +void SwVbaFormFieldDropDownListEntry::Delete() { m_rDropDown.DelContent(m_nZIndex); } + +// XHelperInterface +OUString SwVbaFormFieldDropDownListEntry::getServiceImplName() +{ + return "SwVbaFormFieldDropDownListEntry"; +} + +uno::Sequence<OUString> SwVbaFormFieldDropDownListEntry::getServiceNames() +{ + static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.ListEntry" }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfielddropdownlistentry.hxx b/sw/source/ui/vba/vbaformfielddropdownlistentry.hxx new file mode 100644 index 0000000000..4ded080e63 --- /dev/null +++ b/sw/source/ui/vba/vbaformfielddropdownlistentry.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/. + */ +#pragma once + +#include <ooo/vba/word/XListEntry.hpp> + +#include <vbahelper/vbahelperinterface.hxx> + +#include <IDocumentMarkAccess.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XListEntry> + SwVbaFormFieldDropDownListEntry_BASE; + +class SwVbaFormFieldDropDownListEntry : public SwVbaFormFieldDropDownListEntry_BASE +{ +private: + sw::mark::IDropdownFieldmark& m_rDropDown; + // All LO and internal UNO functions are 0-based. Convert to 1-based when sending to VBA + const sal_Int32 m_nZIndex; + +public: + /// @throws css::uno::RuntimeException + SwVbaFormFieldDropDownListEntry( + const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, + sw::mark::IDropdownFieldmark& rFormField, sal_Int32 nZIndex); + ~SwVbaFormFieldDropDownListEntry() override; + + // XListEntry + sal_Int32 SAL_CALL getIndex() override; + + OUString SAL_CALL getName() override; + void SAL_CALL setName(const OUString& sSet) override; + + void SAL_CALL Delete() override; + + // XHelperInterface + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfields.cxx b/sw/source/ui/vba/vbaformfields.cxx new file mode 100644 index 0000000000..9c8af450d3 --- /dev/null +++ b/sw/source/ui/vba/vbaformfields.cxx @@ -0,0 +1,235 @@ +/* -*- 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/. + */ + +#include <comphelper/sequence.hxx> +#include <sal/log.hxx> + +#include <doc.hxx> +#include <docsh.hxx> +#include <IDocumentMarkAccess.hxx> + +#include "vbaformfield.hxx" +#include "vbaformfields.hxx" +#include "wordvbahelper.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +// Helper function to access the fieldmarks +// @param rIndex serves multiple purposes +// [in] -1 to indicate searching using the provided name, SAL_MAX_INT32 for totals +// [out] rIndex indicates the found index, or the total number of fieldmarks +static sw::mark::IFieldmark* lcl_getFieldmark(std::string_view rName, sal_Int32& rIndex, + const uno::Reference<frame::XModel>& xModel, + uno::Sequence<OUString>* pElementNames = nullptr) + +{ + SwDoc* pDoc = word::getDocShell(xModel)->GetDoc(); + if (!pDoc) + return nullptr; + + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + if (!pMarkAccess) + return nullptr; + + sal_Int32 nCounter = 0; + std::vector<OUString> vElementNames; + IDocumentMarkAccess::iterator aIter = pMarkAccess->getFieldmarksBegin(); + while (aIter != pMarkAccess->getFieldmarksEnd()) + { + switch (IDocumentMarkAccess::GetType(**aIter)) + { + case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK: + case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK: + case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK: + { + if (rIndex < 0 + && (*aIter)->GetName().equalsIgnoreAsciiCase(OUString::fromUtf8(rName))) + { + rIndex = nCounter; + return dynamic_cast<sw::mark::IFieldmark*>(*aIter); + } + else if (rIndex == nCounter) + return dynamic_cast<sw::mark::IFieldmark*>(*aIter); + + ++nCounter; + if (pElementNames) + vElementNames.push_back((*aIter)->GetName()); + break; + } + default:; + } + aIter++; + } + rIndex = nCounter; + if (pElementNames) + *pElementNames = comphelper::containerToSequence(vElementNames); + return nullptr; +} + +namespace +{ +class FormFieldsEnumWrapper : public EnumerationHelper_BASE +{ + uno::Reference<container::XIndexAccess> mxIndexAccess; + sal_Int32 mnIndex; + +public: + explicit FormFieldsEnumWrapper(const uno::Reference<container::XIndexAccess>& xIndexAccess) + : mxIndexAccess(xIndexAccess) + , mnIndex(0) + { + } + sal_Bool SAL_CALL hasMoreElements() override { return (mnIndex < mxIndexAccess->getCount()); } + + uno::Any SAL_CALL nextElement() override + { + if (mnIndex < mxIndexAccess->getCount()) + { + return mxIndexAccess->getByIndex(mnIndex++); + } + throw container::NoSuchElementException(); + } +}; + +class FormFieldCollectionHelper + : public ::cppu::WeakImplHelper<container::XNameAccess, container::XIndexAccess, + container::XEnumerationAccess> +{ +private: + uno::Reference<XHelperInterface> mxParent; + uno::Reference<uno::XComponentContext> mxContext; + uno::Reference<text::XTextDocument> mxTextDocument; + sw::mark::IFieldmark* m_pCache; + +public: + /// @throws css::uno::RuntimeException + FormFieldCollectionHelper(uno::Reference<ov::XHelperInterface> xParent, + uno::Reference<uno::XComponentContext> xContext, + uno::Reference<text::XTextDocument> xTextDocument) + : mxParent(std::move(xParent)) + , mxContext(std::move(xContext)) + , mxTextDocument(std::move(xTextDocument)) + , m_pCache(nullptr) + { + } + + // XIndexAccess + sal_Int32 SAL_CALL getCount() override + { + sal_Int32 nCount = SAL_MAX_INT32; + lcl_getFieldmark("", nCount, mxTextDocument); + return nCount == SAL_MAX_INT32 ? 0 : nCount; + } + + uno::Any SAL_CALL getByIndex(sal_Int32 Index) override + { + m_pCache = lcl_getFieldmark("", Index, mxTextDocument); + if (!m_pCache) + throw lang::IndexOutOfBoundsException(); + + return uno::Any(uno::Reference<word::XFormField>( + new SwVbaFormField(mxParent, mxContext, mxTextDocument, *m_pCache))); + } + + // XNameAccess + uno::Sequence<OUString> SAL_CALL getElementNames() override + { + sal_Int32 nCount = SAL_MAX_INT32; + uno::Sequence<OUString> aSeq; + lcl_getFieldmark("", nCount, mxTextDocument, &aSeq); + return aSeq; + } + + uno::Any SAL_CALL getByName(const OUString& aName) override + { + if (!hasByName(aName)) + throw container::NoSuchElementException(); + + return uno::Any(uno::Reference<word::XFormField>( + new SwVbaFormField(mxParent, mxContext, mxTextDocument, *m_pCache))); + } + + sal_Bool SAL_CALL hasByName(const OUString& aName) override + { + sal_Int32 nCount = -1; + m_pCache = lcl_getFieldmark(aName.toUtf8(), nCount, mxTextDocument); + return m_pCache != nullptr; + } + + // XElementAccess + uno::Type SAL_CALL getElementType() override { return cppu::UnoType<word::XFormField>::get(); } + + sal_Bool SAL_CALL hasElements() override { return getCount() != 0; } + + // XEnumerationAccess + uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override + { + return new FormFieldsEnumWrapper(this); + } +}; +} + +SwVbaFormFields::SwVbaFormFields(const uno::Reference<XHelperInterface>& xParent, + const uno::Reference<uno::XComponentContext>& xContext, + const uno::Reference<text::XTextDocument>& xTextDocument) + : SwVbaFormFields_BASE(xParent, xContext, + uno::Reference<container::XIndexAccess>( + new FormFieldCollectionHelper(xParent, xContext, xTextDocument))) +{ +} + +sal_Bool SwVbaFormFields::getShaded() +{ + SAL_INFO("sw.vba", "SwVbaFormFields::getShaded stub"); + return false; +} + +void SwVbaFormFields::setShaded(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaFormFields::setShaded stub"); +} + +// uno::Reference<ooo::vba::word::XFormField> SwVbaFormFields::Add(const uno::Any& Range, +// sal_Int32 Type) +// { +// sw::mark::IFieldmark* pFieldmark = nullptr; +// switch (Type) +// { +// case ooo::vba::word::WdFieldType::wdFieldFormCheckBox: +// break; +// case ooo::vba::word::WdFieldType::wdFieldFormDropDown: +// break; +// case ooo::vba::word::WdFieldType::wdFieldFormTextInput: +// default:; +// } +// +// return uno::Reference<ooo::vba::word::XFormField>( +// new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldmark)); +// } + +// XEnumerationAccess +uno::Type SwVbaFormFields::getElementType() { return cppu::UnoType<word::XFormField>::get(); } + +uno::Reference<container::XEnumeration> SwVbaFormFields::createEnumeration() +{ + return new FormFieldsEnumWrapper(m_xIndexAccess); +} + +uno::Any SwVbaFormFields::createCollectionObject(const uno::Any& aSource) { return aSource; } + +OUString SwVbaFormFields::getServiceImplName() { return "SwVbaFormFields"; } + +uno::Sequence<OUString> SwVbaFormFields::getServiceNames() +{ + static uno::Sequence<OUString> const sNames{ "ooo.vba.word.FormFields" }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfields.hxx b/sw/source/ui/vba/vbaformfields.hxx new file mode 100644 index 0000000000..2dfa9e76b0 --- /dev/null +++ b/sw/source/ui/vba/vbaformfields.hxx @@ -0,0 +1,41 @@ +/* -*- 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/. + */ +#pragma once + +#include <com/sun/star/text/XTextDocument.hpp> +#include <ooo/vba/word/XFormFields.hpp> + +#include <vbahelper/vbacollectionimpl.hxx> + +typedef CollTestImplHelper<ooo::vba::word::XFormFields> SwVbaFormFields_BASE; + +class SwVbaFormFields : public SwVbaFormFields_BASE +{ +public: + /// @throws css::uno::RuntimeException + SwVbaFormFields(const css::uno::Reference<ov::XHelperInterface>& xParent, + const css::uno::Reference<css::uno::XComponentContext>& xContext, + const css::uno::Reference<css::text::XTextDocument>& xTextDocument); + + // XFormFields + sal_Bool SAL_CALL getShaded() override; + void SAL_CALL setShaded(sal_Bool bSet) override; + //css::uno::Reference<ooo::vba::word::XFormField> SAL_CALL Add(const css::uno::Any& Range, sal_Int32 Type) override; + + // XEnumerationAccess + css::uno::Type SAL_CALL getElementType() override; + css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override; + + // SwVbaFormFields_BASE + css::uno::Any createCollectionObject(const css::uno::Any& aSource) override; + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfieldtextinput.cxx b/sw/source/ui/vba/vbaformfieldtextinput.cxx new file mode 100644 index 0000000000..4f78761f4e --- /dev/null +++ b/sw/source/ui/vba/vbaformfieldtextinput.cxx @@ -0,0 +1,130 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <ooo/vba/word/WdTextFormFieldType.hpp> + +#include <sal/log.hxx> + +#include "vbaformfieldtextinput.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +/** + * TextInput formfields are inline text objects that are only found in MS Word. + * They cannot be created in Excel or in Calc. + * + * Note that VBA might call this a TextInput, but it might not actually be one, + * so make good use of getValid() + */ +SwVbaFormFieldTextInput::SwVbaFormFieldTextInput( + const uno::Reference<ooo::vba::XHelperInterface>& rParent, + const uno::Reference<uno::XComponentContext>& rContext, sw::mark::IFieldmark& rFormField) + : SwVbaFormFieldTextInput_BASE(rParent, rContext) + , m_rTextInput(rFormField) +{ +} + +SwVbaFormFieldTextInput::~SwVbaFormFieldTextInput() {} + +OUString SwVbaFormFieldTextInput::getDefaultPropertyName() { return "Valid"; } + +sal_Bool SwVbaFormFieldTextInput::getValid() +{ + return IDocumentMarkAccess::GetType(m_rTextInput) + == IDocumentMarkAccess::MarkType::TEXT_FIELDMARK; +} + +OUString SwVbaFormFieldTextInput::getDefault() +{ + if (!getValid()) + return OUString(); + + return m_rTextInput.GetContent(); +} + +void SwVbaFormFieldTextInput::setDefault(const OUString& sSet) +{ + // Hard to know what to do here, since LO doesn't have a default property for text input. + // This really only makes sense when macro-adding a text input. + // In that case, we want it to affect the actual text content. + // However, if the text has already been set by the user, then this shouldn't do anything. + // Assuming this is only ever set when adding a text input seems the sanest approach. + if (!getValid() || getDefault() == sSet) + return; + + m_rTextInput.ReplaceContent(sSet); +} + +OUString SwVbaFormFieldTextInput::getFormat() +{ + if (!getValid()) + return OUString(); + + SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::getFormat stub"); + return OUString(); +} + +sal_Int32 SwVbaFormFieldTextInput::getType() +{ + if (!getValid()) + return word::WdTextFormFieldType::wdRegularText; + + SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::getType stub"); + return word::WdTextFormFieldType::wdRegularText; +} + +sal_Int32 SwVbaFormFieldTextInput::getWidth() +{ + if (!getValid()) + return 0; + + SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::getWidth stub"); + return 11 * 50; +} + +void SwVbaFormFieldTextInput::setWidth(sal_Int32 nWidth) +{ + if (!getValid()) + return; + + SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::setWidth[" << nWidth << "] stub"); +} + +void SwVbaFormFieldTextInput::Clear() +{ + if (!getValid() || m_rTextInput.GetContent().isEmpty()) + return; + + m_rTextInput.ReplaceContent(""); +} + +void SwVbaFormFieldTextInput::EditType(sal_Int32 nType, const uno::Any& rDefault, + const uno::Any& rFormat, const uno::Any& rEnabled) +{ + OUString sDefault; + OUString sFormat; + bool bEnabled = true; + rDefault >>= sDefault; + rFormat >>= sFormat; + rEnabled >>= bEnabled; + SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::EditType[" + << nType << "] sDefault[" << sDefault << "] sFormat[" << sFormat + << "] bEnabled[" << bEnabled << "] stub"); +} + +OUString SwVbaFormFieldTextInput::getServiceImplName() { return "SwVbaFormFieldTextInput"; } + +uno::Sequence<OUString> SwVbaFormFieldTextInput::getServiceNames() +{ + static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.TextInput" }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfieldtextinput.hxx b/sw/source/ui/vba/vbaformfieldtextinput.hxx new file mode 100644 index 0000000000..513cac64de --- /dev/null +++ b/sw/source/ui/vba/vbaformfieldtextinput.hxx @@ -0,0 +1,68 @@ +/* -*- 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/. + */ +#pragma once + +#include <ooo/vba/word/XTextInput.hpp> + +#include <vbahelper/vbahelperinterface.hxx> + +#include <IDocumentMarkAccess.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XTextInput> SwVbaFormFieldTextInput_BASE; + +class SwVbaFormFieldTextInput : public SwVbaFormFieldTextInput_BASE +{ +private: + sw::mark::IFieldmark& m_rTextInput; + +public: + /// @throws css::uno::RuntimeException + SwVbaFormFieldTextInput(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, + sw::mark::IFieldmark& rFormField); + ~SwVbaFormFieldTextInput() override; + + // XTextInput + OUString SAL_CALL getDefaultPropertyName() override; + + // default member: True if the specified form field object is a valid text form field + sal_Bool SAL_CALL getValid() override; + + // Returns and sets the default text string of the input box + OUString SAL_CALL getDefault() override; + void SAL_CALL setDefault(const OUString& bSet) override; + // Returns the format string for the current text + OUString SAL_CALL getFormat() override; + /* + * Returns the type of text form field. + * Possible return values are: + * wdCalculationText - Calculation text field, + * wdCurrentDateText - Current date text field, + * wdCurrentTimeText - Current time text field, + * wdDateText - Date text field, + * wdNumberText - Number text field, + * wdRegularText - Regular text field. + */ + sal_Int32 SAL_CALL getType() override; + // Returns and sets the width, in points + sal_Int32 SAL_CALL getWidth() override; + void SAL_CALL setWidth(sal_Int32 nSet) override; + + // Deletes the text from the text form field. + void SAL_CALL Clear() override; + // Sets the type, default text string, format string, and enabled status + void SAL_CALL EditType(sal_Int32 nType, const css::uno::Any& rDefault, + const css::uno::Any& rFormat, const css::uno::Any& rEnabled) override; + + // XHelperInterface + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaframe.cxx b/sw/source/ui/vba/vbaframe.cxx new file mode 100644 index 0000000000..b3a0180fb1 --- /dev/null +++ b/sw/source/ui/vba/vbaframe.cxx @@ -0,0 +1,58 @@ +/* -*- 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 "vbaframe.hxx" +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaFrame::SwVbaFrame( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, css::uno::Reference< frame::XModel > xModel, css::uno::Reference< text::XTextFrame > xTextFrame ) : + SwVbaFrame_BASE( rParent, rContext ), mxModel(std::move( xModel )), mxTextFrame(std::move( xTextFrame )) +{ +} + +SwVbaFrame::~SwVbaFrame() +{ +} + +void SAL_CALL SwVbaFrame::Select() +{ + uno::Reference< view::XSelectionSupplier > xSelectSupp( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); + xSelectSupp->select( uno::Any( mxTextFrame ) ); +} + +OUString +SwVbaFrame::getServiceImplName() +{ + return "SwVbaFrame"; +} + +uno::Sequence< OUString > +SwVbaFrame::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Frame" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaframe.hxx b/sw/source/ui/vba/vbaframe.hxx new file mode 100644 index 0000000000..c24ba4617c --- /dev/null +++ b/sw/source/ui/vba/vbaframe.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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAFRAME_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAFRAME_HXX + +#include <ooo/vba/word/XFrame.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextFrame.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XFrame > SwVbaFrame_BASE; + +class SwVbaFrame : public SwVbaFrame_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::text::XTextFrame > mxTextFrame; + +public: + /// @throws css::uno::RuntimeException + SwVbaFrame( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::frame::XModel > xModel, css::uno::Reference< css::text::XTextFrame > xTextFrame ); + virtual ~SwVbaFrame() override; + + // Methods + virtual void SAL_CALL Select() override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAFRAME_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaframes.cxx b/sw/source/ui/vba/vbaframes.cxx new file mode 100644 index 0000000000..376082054b --- /dev/null +++ b/sw/source/ui/vba/vbaframes.cxx @@ -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 . + */ +#include "vbaframes.hxx" +#include "vbaframe.hxx" +#include <com/sun/star/frame/XModel.hpp> +#include <cppuhelper/implbase.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class FramesEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration > +{ +private: + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< container::XIndexAccess> mxIndexAccess; + uno::Reference< frame::XModel > mxModel; + sal_Int32 mnCurrentPos; +public: + /// @throws uno::RuntimeException + FramesEnumeration( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< container::XIndexAccess > xIndexAccess, uno::Reference< frame::XModel > xModel ) : mxParent(std::move( xParent )), mxContext(std::move( xContext)), mxIndexAccess(std::move( xIndexAccess )), mxModel(std::move( xModel )), mnCurrentPos(0) + { + } + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( mnCurrentPos < mxIndexAccess->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( !hasMoreElements() ) + throw container::NoSuchElementException(); + uno::Reference< text::XTextFrame > xTextFrame( mxIndexAccess->getByIndex( mnCurrentPos++ ), uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< word::XFrame > ( new SwVbaFrame( mxParent, mxContext, mxModel, xTextFrame ) ) ); + } + +}; + +} + +SwVbaFrames::SwVbaFrames( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xFrames, uno::Reference< frame::XModel > xModel ): SwVbaFrames_BASE( xParent, xContext, xFrames ), mxModel(std::move( xModel )) +{ + mxFramesSupplier.set( mxModel, uno::UNO_QUERY_THROW ); +} +// XEnumerationAccess +uno::Type +SwVbaFrames::getElementType() +{ + return cppu::UnoType<word::XFrame>::get(); +} + +uno::Reference< container::XEnumeration > +SwVbaFrames::createEnumeration() +{ + return new FramesEnumeration( this, mxContext,m_xIndexAccess, mxModel ); +} + +uno::Any +SwVbaFrames::createCollectionObject( const css::uno::Any& aSource ) +{ + uno::Reference< text::XTextFrame > xTextFrame( aSource, uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< word::XFrame > ( new SwVbaFrame( this, mxContext, mxModel, xTextFrame ) ) ); +} + +OUString +SwVbaFrames::getServiceImplName() +{ + return "SwVbaFrames"; +} + +css::uno::Sequence<OUString> +SwVbaFrames::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.Frames" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaframes.hxx b/sw/source/ui/vba/vbaframes.hxx new file mode 100644 index 0000000000..6a0c20c3db --- /dev/null +++ b/sw/source/ui/vba/vbaframes.hxx @@ -0,0 +1,50 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAFRAMES_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAFRAMES_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XFrames.hpp> +#include <com/sun/star/text/XTextFramesSupplier.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XFrames > SwVbaFrames_BASE; + +class SwVbaFrames : public SwVbaFrames_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::text::XTextFramesSupplier > mxFramesSupplier; + +public: + SwVbaFrames( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xFrames, css::uno::Reference< css::frame::XModel > xModel ); + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaFrames_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAFRAMES_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaglobals.cxx b/sw/source/ui/vba/vbaglobals.cxx new file mode 100644 index 0000000000..3e9f7dbefe --- /dev/null +++ b/sw/source/ui/vba/vbaglobals.cxx @@ -0,0 +1,224 @@ +/* -*- 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 "vbaglobals.hxx" +#include "vbawordbasic.hxx" +#include <sal/log.hxx> + +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <comphelper/sequence.hxx> + +#include "vbaapplication.hxx" +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::ooo::vba; + +SwVbaGlobals::SwVbaGlobals( uno::Sequence< uno::Any > const& aArgs, uno::Reference< uno::XComponentContext >const& rxContext ) : SwVbaGlobals_BASE( uno::Reference< XHelperInterface >(), rxContext, "WordDocumentContext" ) +{ + SAL_INFO("sw.vba", "SwVbaGlobals::SwVbaGlobals()"); + uno::Sequence< beans::PropertyValue > aInitArgs( aArgs.hasElements() ? 2 : 1 ); + auto pInitArgs = aInitArgs.getArray(); + pInitArgs[ 0 ].Name = "Application"; + pInitArgs[ 0 ].Value <<= getApplication(); + if ( aArgs.hasElements() ) + { + pInitArgs[ 1 ].Name = "WordDocumentContext"; + pInitArgs[ 1 ].Value <<= getXSomethingFromArgs< frame::XModel >( aArgs, 0 ); + } + init( aInitArgs ); +} + +SwVbaGlobals::~SwVbaGlobals() +{ + SAL_INFO("sw.vba", "SwVbaGlobals::~SwVbaGlobals"); +} + +// XGlobals + +uno::Reference<word::XApplication > const & +SwVbaGlobals::getApplication() +{ + SAL_INFO("sw.vba", "In SwVbaGlobals::getApplication"); + if ( !mxApplication.is() ) + mxApplication.set( new SwVbaApplication( mxContext) ); + + return mxApplication; +} + +uno::Reference<word::XSystem > SAL_CALL +SwVbaGlobals::getSystem() +{ + return getApplication()->getSystem(); +} + +uno::Reference< word::XDocument > SAL_CALL +SwVbaGlobals::getActiveDocument() +{ + return getApplication()->getActiveDocument(); +} + +uno::Reference< word::XWindow > SAL_CALL +SwVbaGlobals::getActiveWindow() +{ + return getApplication()->getActiveWindow(); +} + +OUString SAL_CALL +SwVbaGlobals::getName() +{ + return getApplication()->getName(); +} + +uno::Reference<word::XOptions > SAL_CALL +SwVbaGlobals::getOptions() +{ + return getApplication()->getOptions(); +} + +uno::Any SAL_CALL +SwVbaGlobals::CommandBars( const uno::Any& aIndex ) +{ + return getApplication()->CommandBars( aIndex ); +} + +uno::Any SAL_CALL +SwVbaGlobals::Documents( const uno::Any& index ) +{ + return getApplication()->Documents( index ); +} + +uno::Any SAL_CALL +SwVbaGlobals::Addins( const uno::Any& index ) +{ + return getApplication()->Addins( index ); +} + +uno::Any SAL_CALL +SwVbaGlobals::Dialogs( const uno::Any& index ) +{ + return getApplication()->Dialogs( index ); +} + +uno::Any SAL_CALL +SwVbaGlobals::ListGalleries( const uno::Any& index ) +{ + return getApplication()->ListGalleries( index ); +} + +uno::Reference<word::XSelection > SAL_CALL +SwVbaGlobals::getSelection() +{ + return getApplication()->getSelection(); +} + +uno::Reference<word::XGlobals> SwVbaGlobals::getWord() +{ + return uno::Reference<word::XGlobals>(this); +} + +uno::Reference<word::XWordBasic> SAL_CALL SwVbaGlobals::getWordBasic() +{ + assert(dynamic_cast<SwVbaApplication*>(getApplication().get())); + SwVbaApplication* pVbaApp = static_cast<SwVbaApplication*>(getApplication().get()); + uno::Reference<word::XWordBasic> xWB(new SwWordBasic(pVbaApp)); + return xWB; +} + +float SAL_CALL SwVbaGlobals::CentimetersToPoints( float Centimeters ) +{ + return getApplication()->CentimetersToPoints( Centimeters ); +} + +float SAL_CALL SwVbaGlobals::PointsToCentimeters( float Points ) +{ + return getApplication()->PointsToCentimeters( Points ); +} + +float SAL_CALL SwVbaGlobals::PixelsToPoints( float Pixels, ::sal_Bool fVertical ) +{ + return getApplication()->PixelsToPoints( Pixels, fVertical ); +} + +float SAL_CALL SwVbaGlobals::PointsToPixels( float Points, ::sal_Bool fVertical ) +{ + return getApplication()->PointsToPixels( Points, fVertical ); +} + +float SAL_CALL SwVbaGlobals::InchesToPoints( float Inches ) +{ + return getApplication()->InchesToPoints( Inches ); +} + +float SAL_CALL SwVbaGlobals::PointsToInches( float Points ) +{ + return getApplication()->PointsToInches( Points ); +} + +float SAL_CALL SwVbaGlobals::MillimetersToPoints( float Millimeters ) +{ + return getApplication()->MillimetersToPoints( Millimeters ); +} + +float SAL_CALL SwVbaGlobals::PointsToMillimeters( float Points ) +{ + return getApplication()->PointsToMillimeters( Points ); +} + +float SAL_CALL SwVbaGlobals::PicasToPoints( float Picas ) +{ + return getApplication()->PicasToPoints( Picas ); +} + +float SAL_CALL SwVbaGlobals::PointsToPicas( float Points ) +{ + return getApplication()->PointsToPicas( Points ); +} + +OUString +SwVbaGlobals::getServiceImplName() +{ + return "SwVbaGlobals"; +} + +uno::Sequence< OUString > +SwVbaGlobals::getServiceNames() +{ + return { "ooo.vba.word.Globals" }; +} + +uno::Sequence< OUString > +SwVbaGlobals::getAvailableServiceNames( ) +{ + static const uno::Sequence<OUString> serviceNames = comphelper::concatSequences( + SwVbaGlobals_BASE::getAvailableServiceNames(), + uno::Sequence<OUString>{ "ooo.vba.word.Document", + // "ooo.vba.word.Globals", + // "ooo.vba.word.WrapFormat", + "com.sun.star.script.vba.VBATextEventProcessor" }); + return serviceNames; +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +Writer_SwVbaGlobals_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args) +{ + return cppu::acquire(new SwVbaGlobals(args, context)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaglobals.hxx b/sw/source/ui/vba/vbaglobals.hxx new file mode 100644 index 0000000000..c1713502df --- /dev/null +++ b/sw/source/ui/vba/vbaglobals.hxx @@ -0,0 +1,80 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAGLOBALS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAGLOBALS_HXX + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <ooo/vba/word/XGlobals.hpp> +#include <ooo/vba/word/XApplication.hpp> +#include <ooo/vba/word/XSystem.hpp> +#include <ooo/vba/word/XOptions.hpp> +#include <ooo/vba/word/XSelection.hpp> +#include <cppuhelper/implbase.hxx> +#include <vbahelper/vbaglobalbase.hxx> + +typedef ::cppu::ImplInheritanceHelper<VbaGlobalsBase, ov::word::XGlobals> SwVbaGlobals_BASE; + +class SwVbaGlobals : public SwVbaGlobals_BASE +{ +private: + css::uno::Reference<ooo::vba::word::XApplication> mxApplication; + + /// @throws css::uno::RuntimeException + css::uno::Reference<ooo::vba::word::XApplication> const& getApplication(); + +public: + SwVbaGlobals(css::uno::Sequence<css::uno::Any> const& aArgs, + css::uno::Reference<css::uno::XComponentContext> const& rxContext); + virtual ~SwVbaGlobals() override; + + // XGlobals + virtual OUString SAL_CALL getName() override; + virtual css::uno::Reference<ooo::vba::word::XSystem> SAL_CALL getSystem() override; + virtual css::uno::Reference<ov::word::XDocument> SAL_CALL getActiveDocument() override; + virtual css::uno::Reference<ov::word::XWindow> SAL_CALL getActiveWindow() override; + virtual css::uno::Reference<ooo::vba::word::XOptions> SAL_CALL getOptions() override; + virtual css::uno::Reference<ooo::vba::word::XSelection> SAL_CALL getSelection() override; + virtual css::uno::Reference<ooo::vba::word::XGlobals> SAL_CALL getWord() override; + virtual css::uno::Reference<ooo::vba::word::XWordBasic> SAL_CALL getWordBasic() override; + virtual css::uno::Any SAL_CALL CommandBars(const css::uno::Any& aIndex) override; + virtual css::uno::Any SAL_CALL Documents(const css::uno::Any& aIndex) override; + virtual css::uno::Any SAL_CALL Addins(const css::uno::Any& aIndex) override; + virtual css::uno::Any SAL_CALL Dialogs(const css::uno::Any& aIndex) override; + virtual css::uno::Any SAL_CALL ListGalleries(const css::uno::Any& aIndex) override; + virtual float SAL_CALL CentimetersToPoints(float Centimeters) override; + virtual float SAL_CALL PointsToCentimeters(float Points) override; + virtual float SAL_CALL PixelsToPoints(float Pixels, ::sal_Bool fVertical) override; + virtual float SAL_CALL PointsToPixels(float Pixels, ::sal_Bool fVertical) override; + virtual float SAL_CALL InchesToPoints(float Inches) override; + virtual float SAL_CALL PointsToInches(float Points) override; + virtual float SAL_CALL MillimetersToPoints(float Millimeters) override; + virtual float SAL_CALL PointsToMillimeters(float Points) override; + virtual float SAL_CALL PicasToPoints(float Picas) override; + virtual float SAL_CALL PointsToPicas(float Points) override; + + // XMultiServiceFactory + virtual css::uno::Sequence<OUString> SAL_CALL getAvailableServiceNames() override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAGLOBALS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaheaderfooter.cxx b/sw/source/ui/vba/vbaheaderfooter.cxx new file mode 100644 index 0000000000..a031b0ecda --- /dev/null +++ b/sw/source/ui/vba/vbaheaderfooter.cxx @@ -0,0 +1,102 @@ +/* -*- 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 "vbaheaderfooter.hxx" +#include <ooo/vba/word/WdHeaderFooterIndex.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> +#include "vbarange.hxx" +#include <utility> +#include <vbahelper/vbashapes.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaHeaderFooter::SwVbaHeaderFooter( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< frame::XModel > xModel, uno::Reference< beans::XPropertySet > xProps, bool isHeader, sal_Int32 index ) : SwVbaHeaderFooter_BASE( rParent, rContext ), mxModel(std::move( xModel )), mxPageStyleProps(std::move( xProps )), mbHeader( isHeader ), mnIndex( index ) +{ +} + +sal_Bool SAL_CALL SwVbaHeaderFooter::getIsHeader() +{ + return mbHeader; +} + +sal_Bool SAL_CALL SwVbaHeaderFooter::getLinkToPrevious() +{ + // seems always false + return false; +} + +void SAL_CALL SwVbaHeaderFooter::setLinkToPrevious( sal_Bool /*_linktoprevious*/ ) +{ + // not support in Writer +} + +uno::Reference< word::XRange > SAL_CALL SwVbaHeaderFooter::getRange() +{ + OUString sPropsNameText; + if( mbHeader ) + { + sPropsNameText = "HeaderText"; + } + else + { + sPropsNameText = "FooterText"; + } + if( mnIndex == word::WdHeaderFooterIndex::wdHeaderFooterEvenPages ) + { + sPropsNameText += "Left"; + } + + uno::Reference< text::XText > xText( mxPageStyleProps->getPropertyValue( sPropsNameText ), uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextDocument > xDocument( mxModel, uno::UNO_QUERY_THROW ); + return uno::Reference< word::XRange >( new SwVbaRange( this, mxContext, xDocument, xText->getStart(), xText->getEnd(), xText ) ); +} + +uno::Any SAL_CALL +SwVbaHeaderFooter::Shapes( const uno::Any& index ) +{ + // #FIXME: only get the shapes in the current header/footer + uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( mxModel, uno::UNO_QUERY_THROW ); + //uno::Reference< drawing::XShapes > xShapes( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW ); + uno::Reference< XCollection > xCol( new ScVbaShapes( this, mxContext, xIndexAccess, mxModel ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +OUString +SwVbaHeaderFooter::getServiceImplName() +{ + return "SwVbaHeaderFooter"; +} + +uno::Sequence< OUString > +SwVbaHeaderFooter::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Pane" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaheaderfooter.hxx b/sw/source/ui/vba/vbaheaderfooter.hxx new file mode 100644 index 0000000000..7425057b26 --- /dev/null +++ b/sw/source/ui/vba/vbaheaderfooter.hxx @@ -0,0 +1,53 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERFOOTER_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERFOOTER_HXX + +#include <ooo/vba/word/XHeaderFooter.hpp> +#include <ooo/vba/word/XRange.hpp> +#include <vbahelper/vbahelperinterface.hxx> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XHeaderFooter > SwVbaHeaderFooter_BASE; + +class SwVbaHeaderFooter : public SwVbaHeaderFooter_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::beans::XPropertySet > mxPageStyleProps; + bool mbHeader; + sal_Int32 mnIndex; + +public: + /// @throws css::uno::RuntimeException + SwVbaHeaderFooter( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::frame::XModel > xModel, css::uno::Reference< css::beans::XPropertySet > xProps, bool isHeader, sal_Int32 index ); + + // Attributes + virtual sal_Bool SAL_CALL getIsHeader() override; + virtual sal_Bool SAL_CALL getLinkToPrevious() override; + virtual void SAL_CALL setLinkToPrevious( sal_Bool _linktoprevious ) override; + virtual css::uno::Reference< ::ooo::vba::word::XRange > SAL_CALL getRange() override; + virtual css::uno::Any SAL_CALL Shapes( const css::uno::Any& aIndex ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERFOOTER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaheaderfooterhelper.cxx b/sw/source/ui/vba/vbaheaderfooterhelper.cxx new file mode 100644 index 0000000000..987088b6a5 --- /dev/null +++ b/sw/source/ui/vba/vbaheaderfooterhelper.cxx @@ -0,0 +1,174 @@ +/* -*- 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 "vbaheaderfooterhelper.hxx" +#include "wordvbahelper.hxx" +#include <com/sun/star/text/XTextRangeCompare.hpp> +#include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/text/XPageCursor.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +#define FIRST_PAGE 1 + +// Class HeaderFooterHelper +bool HeaderFooterHelper::isHeaderFooter( const uno::Reference< frame::XModel >& xModel ) +{ + return isHeaderFooter( word::getCurrentXText( xModel ) ); +} + +bool HeaderFooterHelper::isHeaderFooter( const uno::Reference< text::XText >& xText ) +{ + uno::Reference< lang::XServiceInfo > xServiceInfo( xText, uno::UNO_QUERY_THROW ); + OUString aImplName = xServiceInfo->getImplementationName(); + return aImplName == "SwXHeadFootText"; +} + +bool HeaderFooterHelper::isHeader( const uno::Reference< frame::XModel >& xModel ) +{ + const uno::Reference< text::XText > xCurrentText = word::getCurrentXText( xModel ); + if( !isHeaderFooter( xCurrentText ) ) + return false; + + OUString aPropText = "HeaderText"; + uno::Reference< style::XStyle > xPageStyle = word::getCurrentPageStyle( xModel ); + uno::Reference< beans::XPropertySet > xPageProps( xPageStyle, uno::UNO_QUERY_THROW ); + bool isShared = true; + xPageProps->getPropertyValue( "HeaderIsShared" ) >>= isShared; + if( !isShared ) + { + uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW ); + if( 0 == xPageCursor->getPage() % 2 ) + aPropText = "HeaderTextLeft"; + else + aPropText = "HeaderTextRight"; + } + + uno::Reference< text::XText > xHeaderText( xPageProps->getPropertyValue( aPropText ), uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextRangeCompare > xTRC( xHeaderText, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextRange > xTR1( xCurrentText, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextRange > xTR2( xHeaderText, uno::UNO_QUERY_THROW ); + try + { + if( xTRC->compareRegionStarts( xTR1, xTR2 ) == 0 ) + return true; + } + catch (const lang::IllegalArgumentException&) + { + return false; + } + + return false; +} + +bool HeaderFooterHelper::isFirstPageHeader( const uno::Reference< frame::XModel >& xModel ) +{ + if( isHeader( xModel ) ) + { + uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW ); + // FIXME: getPage always returns 1 + sal_Int32 nPage = xPageCursor->getPage(); + return nPage == FIRST_PAGE; + } + return false; +} + +bool HeaderFooterHelper::isEvenPagesHeader( const uno::Reference< frame::XModel >& xModel ) +{ + if( isHeader( xModel ) ) + { + uno::Reference< beans::XPropertySet > xStyleProps( word::getCurrentPageStyle( xModel ), uno::UNO_QUERY_THROW ); + bool isShared = false; + xStyleProps->getPropertyValue("HeaderIsShared") >>= isShared; + if( !isShared ) + { + uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW ); + return ( 0 == xPageCursor->getPage() % 2 ); + } + } + return false; +} + +bool HeaderFooterHelper::isFooter( const uno::Reference< frame::XModel >& xModel ) +{ + const uno::Reference< text::XText > xCurrentText = word::getCurrentXText( xModel ); + if( !isHeaderFooter( xCurrentText ) ) + return false; + + OUString aPropText = "FooterText"; + uno::Reference< style::XStyle > xPageStyle = word::getCurrentPageStyle( xModel ); + uno::Reference< beans::XPropertySet > xPageProps( xPageStyle, uno::UNO_QUERY_THROW ); + bool isShared = true; + xPageProps->getPropertyValue( "FooterIsShared" ) >>= isShared; + if( !isShared ) + { + uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW ); + if( 0 == xPageCursor->getPage() % 2 ) + aPropText = "FooterTextLeft"; + else + aPropText = "FooterTextRight"; + } + + uno::Reference< text::XText > xFooterText( xPageProps->getPropertyValue( aPropText ), uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextRangeCompare > xTRC( xFooterText, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextRange > xTR1( xCurrentText, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextRange > xTR2( xFooterText, uno::UNO_QUERY_THROW ); + try + { + if( xTRC->compareRegionStarts( xTR1, xTR2 ) == 0 ) + return true; + } + catch (const lang::IllegalArgumentException&) + { + return false; + } + + return false; +} + +bool HeaderFooterHelper::isFirstPageFooter( const uno::Reference< frame::XModel >& xModel ) +{ + if( isFooter( xModel ) ) + { + uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW ); + sal_Int32 nPage = xPageCursor->getPage(); + return nPage == FIRST_PAGE; + } + return false; +} + +bool HeaderFooterHelper::isEvenPagesFooter( const uno::Reference< frame::XModel >& xModel ) +{ + if( isFooter( xModel ) ) + { + uno::Reference< beans::XPropertySet > xStyleProps( word::getCurrentPageStyle( xModel ), uno::UNO_QUERY_THROW ); + bool isShared = false; + xStyleProps->getPropertyValue("FooterIsShared") >>= isShared; + if( !isShared ) + { + uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW ); + return ( 0 == xPageCursor->getPage() % 2 ); + } + } + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaheaderfooterhelper.hxx b/sw/source/ui/vba/vbaheaderfooterhelper.hxx new file mode 100644 index 0000000000..ca66b208ad --- /dev/null +++ b/sw/source/ui/vba/vbaheaderfooterhelper.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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERFOOTERHELPER_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERFOOTERHELPER_HXX + +#include <vbahelper/vbahelper.hxx> +#include <com/sun/star/text/XText.hpp> + +class HeaderFooterHelper +{ +public: + /// @throws css::uno::RuntimeException + static bool isHeaderFooter(const css::uno::Reference<css::frame::XModel>& xModel); + /// @throws css::uno::RuntimeException + static bool isHeaderFooter(const css::uno::Reference<css::text::XText>& xText); + /// @throws css::uno::RuntimeException + static bool isHeader(const css::uno::Reference<css::frame::XModel>& xModel); + /// @throws css::uno::RuntimeException + static bool isFirstPageHeader(const css::uno::Reference<css::frame::XModel>& xModel); + /// @throws css::uno::RuntimeException + static bool isEvenPagesHeader(const css::uno::Reference<css::frame::XModel>& xModel); + /// @throws css::uno::RuntimeException + static bool isFooter(const css::uno::Reference<css::frame::XModel>& xModel); + /// @throws css::uno::RuntimeException + static bool isFirstPageFooter(const css::uno::Reference<css::frame::XModel>& xModel); + /// @throws css::uno::RuntimeException + static bool isEvenPagesFooter(const css::uno::Reference<css::frame::XModel>& xModel); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaheadersfooters.cxx b/sw/source/ui/vba/vbaheadersfooters.cxx new file mode 100644 index 0000000000..be205d8e13 --- /dev/null +++ b/sw/source/ui/vba/vbaheadersfooters.cxx @@ -0,0 +1,141 @@ +/* -*- 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 "vbaheadersfooters.hxx" +#include "vbaheaderfooter.hxx" +#include <cppuhelper/implbase.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +// I assume there is only one headersfooters in Writer +class HeadersFootersIndexAccess : public ::cppu::WeakImplHelper<container::XIndexAccess > +{ +private: + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< frame::XModel > mxModel; + uno::Reference< beans::XPropertySet > mxPageStyleProps; + bool mbHeader; + +public: + HeadersFootersIndexAccess( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel, uno::Reference< beans::XPropertySet > xPageStyleProps, bool bHeader ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxModel(std::move( xModel )), mxPageStyleProps(std::move( xPageStyleProps )), mbHeader( bHeader ) {} + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount( ) override + { + // first page, even pages and primary page + return 3; + } + virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override + { + if( Index < 1 || Index > 3 ) + throw lang::IndexOutOfBoundsException(); + return uno::Any( uno::Reference< word::XHeaderFooter >( new SwVbaHeaderFooter( mxParent, mxContext, mxModel, mxPageStyleProps, mbHeader, Index ) ) ); + } + virtual uno::Type SAL_CALL getElementType( ) override + { + return cppu::UnoType<word::XHeaderFooter>::get(); + } + virtual sal_Bool SAL_CALL hasElements( ) override + { + return true; + } +}; + +class HeadersFootersEnumWrapper : public EnumerationHelper_BASE +{ + SwVbaHeadersFooters* m_pHeadersFooters; + sal_Int32 m_nIndex; +public: + explicit HeadersFootersEnumWrapper( SwVbaHeadersFooters* _pHeadersFooters ) : m_pHeadersFooters( _pHeadersFooters ), m_nIndex( 0 ) {} + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( m_nIndex < m_pHeadersFooters->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( m_nIndex < m_pHeadersFooters->getCount() ) + return m_pHeadersFooters->Item( uno::Any( ++m_nIndex ), uno::Any() ); + throw container::NoSuchElementException(); + } +}; + +} + +SwVbaHeadersFooters::SwVbaHeadersFooters( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel, const uno::Reference< beans::XPropertySet >& xPageStyleProps, bool isHeader ): SwVbaHeadersFooters_BASE( xParent, xContext, new HeadersFootersIndexAccess( xParent, xContext, xModel, xPageStyleProps, isHeader ) ), mxModel( xModel ), mxPageStyleProps( xPageStyleProps ), mbHeader( isHeader ) +{ +} + +::sal_Int32 SAL_CALL SwVbaHeadersFooters::getCount() +{ + // wdHeaderFooterFirstPage, wdHeaderFooterPrimary and wdHeaderFooterEvenPages + return 3; +} + +uno::Any SAL_CALL SwVbaHeadersFooters::Item( const uno::Any& Index1, const uno::Any& ) +{ + sal_Int32 nIndex = 0; + Index1 >>= nIndex; + if( ( nIndex < 1 ) || ( nIndex > 3 ) ) + { + throw lang::IndexOutOfBoundsException(); + } + return uno::Any( uno::Reference< word::XHeaderFooter >( new SwVbaHeaderFooter( this, mxContext, mxModel, mxPageStyleProps, mbHeader, nIndex ) ) ); +} + +// XEnumerationAccess +uno::Type +SwVbaHeadersFooters::getElementType() +{ + return cppu::UnoType<word::XHeaderFooter>::get(); +} +uno::Reference< container::XEnumeration > + +SwVbaHeadersFooters::createEnumeration() +{ + return new HeadersFootersEnumWrapper( this ); +} + +uno::Any +SwVbaHeadersFooters::createCollectionObject( const uno::Any& aSource ) +{ + return aSource; +} + +OUString +SwVbaHeadersFooters::getServiceImplName() +{ + return "SwVbaHeadersFooters"; +} + +uno::Sequence<OUString> +SwVbaHeadersFooters::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.HeadersFooters" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaheadersfooters.hxx b/sw/source/ui/vba/vbaheadersfooters.hxx new file mode 100644 index 0000000000..44aa77cfde --- /dev/null +++ b/sw/source/ui/vba/vbaheadersfooters.hxx @@ -0,0 +1,51 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERSFOOTERS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERSFOOTERS_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XHeadersFooters.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XHeadersFooters > SwVbaHeadersFooters_BASE; + +class SwVbaHeadersFooters : public SwVbaHeadersFooters_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::beans::XPropertySet > mxPageStyleProps; + bool mbHeader; + +public: + SwVbaHeadersFooters( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::beans::XPropertySet >& xProps, bool isHeader ); + + virtual ::sal_Int32 SAL_CALL getCount() override; + virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& ) override; + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaHeadersFooters_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERSFOOTERS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbainformationhelper.cxx b/sw/source/ui/vba/vbainformationhelper.cxx new file mode 100644 index 0000000000..9cda14b7b2 --- /dev/null +++ b/sw/source/ui/vba/vbainformationhelper.cxx @@ -0,0 +1,66 @@ +/* -*- 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 "vbainformationhelper.hxx" +#include <com/sun/star/text/XPageCursor.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <tools/UnitConversion.hxx> +#include "wordvbahelper.hxx" +#include <docsh.hxx> +#include <doc.hxx> +#include <vbahelper/vbahelper.hxx> +#include <viewsh.hxx> +#include <IDocumentLayoutAccess.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +const sal_Int32 DEFAULT_PAGE_DISTANCE = 500; + +sal_Int32 SwVbaInformationHelper::handleWdActiveEndPageNumber( const css::uno::Reference< css::text::XTextViewCursor >& xTVCursor ) +{ + uno::Reference< text::XPageCursor > xPageCursor( xTVCursor, uno::UNO_QUERY_THROW ); + return xPageCursor->getPage(); +} + +sal_Int32 SwVbaInformationHelper::handleWdNumberOfPagesInDocument( const css::uno::Reference< css::frame::XModel >& xModel ) +{ + return word::getPageCount( xModel ); +} + +double SwVbaInformationHelper::handleWdVerticalPositionRelativeToPage( const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextViewCursor >& xTVCursor ) +{ + xTVCursor->collapseToStart(); + uno::Reference< beans::XPropertySet > xStyleProps( word::getCurrentPageStyle( xModel ), uno::UNO_QUERY_THROW ); + sal_Int32 nTopMargin = 0; + xStyleProps->getPropertyValue( "TopMargin" ) >>= nTopMargin; + sal_Int32 nCurrentPos = xTVCursor->getPosition().Y; + + sal_Int32 nCurrentPage = handleWdActiveEndPageNumber( xTVCursor ); + SwDoc* pDoc = word::getDocShell( xModel )->GetDoc(); + SwViewShell* pViewSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell(); + sal_Int32 nPageHeight = pViewSh ? pViewSh->GetPageSize( nCurrentPage, false ).Height() : 0; + // FIXME: handle multiple page style + // it is very strange that the cursor position is incorrect when open Word file. + // e.g. if current cursor in the top left of the text body of the first page without header, + // the top value of current position should be 0, but is 201 when open a Word file. + nCurrentPos = nCurrentPos + nTopMargin - ( DEFAULT_PAGE_DISTANCE + convertTwipToMm100( nPageHeight ) ) * ( nCurrentPage - 1 ); + return Millimeter::getInPoints( nCurrentPos ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbainformationhelper.hxx b/sw/source/ui/vba/vbainformationhelper.hxx new file mode 100644 index 0000000000..c60b300cd4 --- /dev/null +++ b/sw/source/ui/vba/vbainformationhelper.hxx @@ -0,0 +1,42 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAINFORMATIONHELPER_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAINFORMATIONHELPER_HXX + +#include <com/sun/star/text/XTextViewCursor.hpp> +#include <com/sun/star/frame/XModel.hpp> + +class SwVbaInformationHelper +{ +public: + /// @throws css::uno::RuntimeException + static sal_Int32 + handleWdActiveEndPageNumber(const css::uno::Reference<css::text::XTextViewCursor>& xTVCursor); + /// @throws css::uno::RuntimeException + static sal_Int32 + handleWdNumberOfPagesInDocument(const css::uno::Reference<css::frame::XModel>& xModel); + /// @throws css::uno::RuntimeException + static double handleWdVerticalPositionRelativeToPage( + const css::uno::Reference<css::frame::XModel>& xModel, + const css::uno::Reference<css::text::XTextViewCursor>& xTVCursor); + //static double verticalPositionRelativeToPageBoundary( const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextViewCursor >& xTVCursor, const css::uno::Reference< css::beans::XPropertySet >& xStyleProps ) throw( css::uno::RuntimeException ); +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAINFORMATIONHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalistformat.cxx b/sw/source/ui/vba/vbalistformat.cxx new file mode 100644 index 0000000000..efcbf2dbe8 --- /dev/null +++ b/sw/source/ui/vba/vbalistformat.cxx @@ -0,0 +1,328 @@ +/* -*- 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 "vbalistformat.hxx" +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include <ooo/vba/word/WdListApplyTo.hpp> +#include <ooo/vba/word/WdDefaultListBehavior.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XEnumeration.hpp> +#include <com/sun/star/document/XUndoManagerSupplier.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/style/TabStop.hpp> +#include <com/sun/star/text/PositionAndSpaceMode.hpp> +#include <com/sun/star/text/XTextTable.hpp> +#include <com/sun/star/util/Color.hpp> +#include <comphelper/sequence.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/scopeguard.hxx> +#include <editeng/numitem.hxx> +#include "vbalisttemplate.hxx" + +#include <vector> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaListFormat::SwVbaListFormat( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextRange > xTextRange ) : SwVbaListFormat_BASE( rParent, rContext ), mxTextRange(std::move( xTextRange )) +{ +} + +SwVbaListFormat::~SwVbaListFormat() +{ +} + +void SAL_CALL SwVbaListFormat::ApplyListTemplate( const css::uno::Reference< word::XListTemplate >& ListTemplate, const css::uno::Any& ContinuePreviousList, const css::uno::Any& ApplyTo, const css::uno::Any& DefaultListBehavior ) +{ + bool bContinuePreviousList = true; + if( ContinuePreviousList.hasValue() ) + ContinuePreviousList >>= bContinuePreviousList; + + // "applyto" must be current selection + sal_Int32 bApplyTo = word::WdListApplyTo::wdListApplyToSelection; + if( ApplyTo.hasValue() ) + ApplyTo >>= bApplyTo; + if( bApplyTo != word::WdListApplyTo::wdListApplyToSelection ) + throw uno::RuntimeException(); + + // default behaviour must be wdWord8ListBehavior + sal_Int32 nDefaultListBehavior = word::WdDefaultListBehavior::wdWord8ListBehavior; + if( DefaultListBehavior.hasValue() ) + DefaultListBehavior >>= nDefaultListBehavior; + if( nDefaultListBehavior != word::WdDefaultListBehavior::wdWord8ListBehavior ) + throw uno::RuntimeException(); + + uno::Reference< container::XEnumerationAccess > xEnumAccess( mxTextRange, uno::UNO_QUERY_THROW ); + uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration(); + if (!xEnum->hasMoreElements()) + return; + + SwVbaListTemplate& rListTemplate = dynamic_cast<SwVbaListTemplate&>(*ListTemplate); + + bool isFirstElement = true; + do + { + uno::Reference< beans::XPropertySet > xProps( xEnum->nextElement(), uno::UNO_QUERY_THROW ); + if( isFirstElement ) + { + bool isNumberingRestart = !bContinuePreviousList; + xProps->setPropertyValue("ParaIsNumberingRestart", uno::Any( isNumberingRestart ) ); + if( isNumberingRestart ) + { + xProps->setPropertyValue("NumberingStartValue", uno::Any( sal_Int16(1) ) ); + } + isFirstElement = false; + } + else + { + xProps->setPropertyValue("ParaIsNumberingRestart", uno::Any( false ) ); + } + rListTemplate.applyListTemplate( xProps ); + } + while( xEnum->hasMoreElements() ); +} + +template <class Ref> +static void addParagraphsToList(const Ref& a, + std::vector<css::uno::Reference<css::beans::XPropertySet>>& rList) +{ + if (css::uno::Reference<css::lang::XServiceInfo> xInfo{ a, css::uno::UNO_QUERY }) + { + if (xInfo->supportsService("com.sun.star.text.Paragraph")) + { + rList.emplace_back(xInfo, css::uno::UNO_QUERY_THROW); + } + else if (xInfo->supportsService("com.sun.star.text.TextTable")) + { + css::uno::Reference<css::text::XTextTable> xTable(xInfo, css::uno::UNO_QUERY_THROW); + const auto aNames = xTable->getCellNames(); + for (const auto& rName : aNames) + { + addParagraphsToList(xTable->getCellByName(rName), rList); + } + } + } + if (css::uno::Reference<css::container::XEnumerationAccess> xEnumAccess{ a, + css::uno::UNO_QUERY }) + { + auto xEnum = xEnumAccess->createEnumeration(); + while (xEnum->hasMoreElements()) + addParagraphsToList(xEnum->nextElement(), rList); + } +} + +void SAL_CALL SwVbaListFormat::ConvertNumbersToText( ) +{ + css::uno::Reference<css::frame::XModel> xModel(getThisWordDoc(mxContext)); + css::uno::Reference<css::document::XUndoManagerSupplier> xUndoSupplier( + xModel, css::uno::UNO_QUERY_THROW); + css::uno::Reference<css::document::XUndoManager> xUndoManager(xUndoSupplier->getUndoManager()); + xUndoManager->enterUndoContext("ConvertNumbersToText"); + xModel->lockControllers(); + comphelper::ScopeGuard g([xModel, xUndoManager]() { + xModel->unlockControllers(); + xUndoManager->leaveUndoContext(); + }); + + std::vector<css::uno::Reference<css::beans::XPropertySet>> aParagraphs; + addParagraphsToList(mxTextRange, aParagraphs); + + // in reverse order, to get proper label strings + for (auto iter = aParagraphs.rbegin(); iter != aParagraphs.rend(); ++iter) + { + auto& rPropertySet = *iter; + if (bool bNumber; (rPropertySet->getPropertyValue("NumberingIsNumber") >>= bNumber) && bNumber) + { + css::uno::Reference<css::text::XTextRange> xRange(rPropertySet, css::uno::UNO_QUERY_THROW); + OUString sLabelString; + rPropertySet->getPropertyValue("ListLabelString") >>= sLabelString; + // sal_Int16 nAdjust = SAL_MAX_INT16; // TODO? + sal_Int16 nNumberingType = SAL_MAX_INT16; // css::style::NumberingType + sal_Int16 nPositionAndSpaceMode = SAL_MAX_INT16; + sal_Int16 nLabelFollowedBy = SAL_MAX_INT16; + sal_Int32 nListtabStopPosition = SAL_MAX_INT32; + sal_Int32 nFirstLineIndent = SAL_MAX_INT32; + sal_Int32 nIndentAt = SAL_MAX_INT32; + sal_Int32 nLeftMargin = SAL_MAX_INT32; + sal_Int32 nSymbolTextDistance = SAL_MAX_INT32; + sal_Int32 nFirstLineOffset = SAL_MAX_INT32; + OUString sCharStyleName, sBulletChar; + css::awt::FontDescriptor aBulletFont; + bool bHasFont; + css::util::Color aBulletColor = css::util::Color(COL_AUTO); + bool bHasColor; + + { + sal_uInt16 nLevel = SAL_MAX_UINT16; + rPropertySet->getPropertyValue("NumberingLevel") >>= nLevel; + css::uno::Reference<css::container::XIndexAccess> xNumberingRules; + rPropertySet->getPropertyValue("NumberingRules") >>= xNumberingRules; + comphelper::SequenceAsHashMap aLevelRule(xNumberingRules->getByIndex(nLevel)); + + // See offapi/com/sun/star/text/NumberingLevel.idl + aLevelRule["CharStyleName"] >>= sCharStyleName; + aLevelRule["NumberingType"] >>= nNumberingType; + // TODO: aLevelRule["Adjust"] >>= nAdjust; // HoriOrientation::LEFT/RIGHT/CENTER + aLevelRule["PositionAndSpaceMode"] >>= nPositionAndSpaceMode; + + // for css::text::PositionAndSpaceMode::LABEL_ALIGNMENT + aLevelRule["LabelFollowedBy"] >>= nLabelFollowedBy; + aLevelRule["ListtabStopPosition"] >>= nListtabStopPosition; + aLevelRule["FirstLineIndent"] >>= nFirstLineIndent; + aLevelRule["IndentAt"] >>= nIndentAt; + + // for css::text::PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION + aLevelRule["LeftMargin"] >>= nLeftMargin; + aLevelRule["SymbolTextDistance"] >>= nSymbolTextDistance; + aLevelRule["FirstLineOffset"] >>= nFirstLineOffset; + + aLevelRule["BulletChar"] >>= sBulletChar; + bHasFont = (aLevelRule["BulletFont"] >>= aBulletFont); + bHasColor = (aLevelRule["BulletColor"] >>= aBulletColor); + } + + if (nNumberingType != css::style::NumberingType::BITMAP) // TODO + { + if (nPositionAndSpaceMode + == css::text::PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION) + { + nIndentAt = nLeftMargin; + nFirstLineIndent = nFirstLineOffset; + nListtabStopPosition = nSymbolTextDistance; + nLabelFollowedBy = SvxNumberFormat::LabelFollowedBy::LISTTAB; + } + + switch (nLabelFollowedBy) + { + case SvxNumberFormat::LabelFollowedBy::LISTTAB: + sLabelString += "\t"; + break; + case SvxNumberFormat::LabelFollowedBy::SPACE: + sLabelString += " "; + break; + case SvxNumberFormat::LabelFollowedBy::NEWLINE: + sLabelString += "\n"; + break; + } + + css::uno::Reference<css::text::XTextRange> xNumberText(xRange->getStart()); + xNumberText->setString(sLabelString); + css::uno::Reference<css::beans::XPropertySet> xNumberProps( + xNumberText, css::uno::UNO_QUERY_THROW); + if (!sCharStyleName.isEmpty()) + xNumberProps->setPropertyValue("CharStyleName", css::uno::Any(sCharStyleName)); + + if (nNumberingType == css::style::NumberingType::CHAR_SPECIAL) + { + css::uno::Reference<css::text::XTextRange> xBulletText(xNumberText->getStart()); + xBulletText->setString(sBulletChar); + + std::unordered_map<OUString, css::uno::Any> aNameValues; + if (bHasFont) + { + aNameValues.insert({ + { "CharFontName", css::uno::Any(aBulletFont.Name) }, + { "CharFontStyleName", css::uno::Any(aBulletFont.StyleName) }, + { "CharFontFamily", css::uno::Any(aBulletFont.Family) }, + { "CharFontCharSet", css::uno::Any(aBulletFont.CharSet) }, + { "CharWeight", css::uno::Any(aBulletFont.Weight) }, + { "CharUnderline", css::uno::Any(aBulletFont.Underline) }, + { "CharStrikeout", css::uno::Any(aBulletFont.Strikeout) }, + { "CharAutoKerning", css::uno::Any(aBulletFont.Kerning) }, + { "CharFontPitch", css::uno::Any(aBulletFont.Pitch) }, + { "CharWordMode", css::uno::Any(aBulletFont.WordLineMode) }, + { "CharRotation", css::uno::Any(static_cast<sal_Int16>( + std::round(aBulletFont.Orientation * 10))) }, + }); + if (aBulletFont.Height) + aNameValues["CharHeight"] <<= aBulletFont.Height; + } + if (bHasColor) + { + aNameValues["CharColor"] <<= aBulletColor; + } + + if (css::uno::Reference<css::beans::XMultiPropertySet> xBulletMultiProps{ + xBulletText, css::uno::UNO_QUERY }) + { + xBulletMultiProps->setPropertyValues( + comphelper::mapKeysToSequence(aNameValues), + comphelper::mapValuesToSequence(aNameValues)); + } + else + { + css::uno::Reference<css::beans::XPropertySet> xBulletProps( + xBulletText, css::uno::UNO_QUERY_THROW); + for (const auto& [rName, rVal] : aNameValues) + xBulletProps->setPropertyValue(rName, rVal); + } + } + else + { + // TODO: css::style::NumberingType::BITMAP + } + + rPropertySet->setPropertyValue("ParaLeftMargin", css::uno::Any(nIndentAt)); + rPropertySet->setPropertyValue("ParaFirstLineIndent", css::uno::Any(nFirstLineIndent)); + if (nLabelFollowedBy == SvxNumberFormat::LabelFollowedBy::LISTTAB) + { + css::uno::Sequence<css::style::TabStop> stops; + rPropertySet->getPropertyValue("ParaTabStops") >>= stops; + css::style::TabStop tabStop{}; + tabStop.Position = nListtabStopPosition; + tabStop.Alignment = com::sun::star::style::TabAlign::TabAlign_LEFT; + tabStop.FillChar = ' '; + rPropertySet->setPropertyValue("ParaTabStops", + css::uno::Any(comphelper::combineSequences({ tabStop }, stops))); + // FIXME: What if added tap stop is greater than already defined ones? + } + } + else + { + continue; // for now, keep such lists as is + } + + // In case of higher outline levels, each assignment of empty value just sets level 1 + while (rPropertySet->getPropertyValue("NumberingRules") != css::uno::Any()) + { + rPropertySet->setPropertyValue("NumberingRules", css::uno::Any()); + } + } + } +} + +OUString +SwVbaListFormat::getServiceImplName() +{ + return "SwVbaListFormat"; +} + +uno::Sequence< OUString > +SwVbaListFormat::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.ListFormat" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalistformat.hxx b/sw/source/ui/vba/vbalistformat.hxx new file mode 100644 index 0000000000..378a42fd62 --- /dev/null +++ b/sw/source/ui/vba/vbalistformat.hxx @@ -0,0 +1,49 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTFORMAT_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTFORMAT_HXX + +#include <ooo/vba/word/XListFormat.hpp> +#include <ooo/vba/word/XListTemplate.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextRange.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XListFormat > SwVbaListFormat_BASE; + +class SwVbaListFormat : public SwVbaListFormat_BASE +{ +private: + css::uno::Reference< css::text::XTextRange > mxTextRange; + +public: + /// @throws css::uno::RuntimeException + SwVbaListFormat( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextRange > xTextRange ); + virtual ~SwVbaListFormat() override; + + // Methods + virtual void SAL_CALL ApplyListTemplate( const css::uno::Reference< ::ooo::vba::word::XListTemplate >& ListTemplate, const css::uno::Any& ContinuePreviousList, const css::uno::Any& ApplyTo, const css::uno::Any& DefaultListBehavior ) override; + virtual void SAL_CALL ConvertNumbersToText( ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTFORMAT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalistgalleries.cxx b/sw/source/ui/vba/vbalistgalleries.cxx new file mode 100644 index 0000000000..9c047b1b64 --- /dev/null +++ b/sw/source/ui/vba/vbalistgalleries.cxx @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "vbalistgalleries.hxx" +#include "vbalistgallery.hxx" +#include <ooo/vba/word/WdListGalleryType.hpp> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class ListGalleriesEnumWrapper : public EnumerationHelper_BASE +{ + SwVbaListGalleries* m_pListGalleries; + sal_Int32 m_nIndex; +public: + explicit ListGalleriesEnumWrapper( SwVbaListGalleries* pGalleries ) : m_pListGalleries( pGalleries ), m_nIndex( 1 ) {} + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( m_nIndex <= m_pListGalleries->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( m_nIndex <= m_pListGalleries->getCount() ) + return m_pListGalleries->Item( uno::Any( m_nIndex++ ), uno::Any() ); + throw container::NoSuchElementException(); + } +}; + +} + +SwVbaListGalleries::SwVbaListGalleries( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< text::XTextDocument > xTextDoc ) : SwVbaListGalleries_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >() ), mxTextDocument(std::move( xTextDoc )) +{ +} + +::sal_Int32 SAL_CALL SwVbaListGalleries::getCount() +{ + // 3 types of list( bullet, numbered and outline ) + return 3; +} + +uno::Any SAL_CALL SwVbaListGalleries::Item( const uno::Any& Index1, const uno::Any& /*not processed in this base class*/ ) +{ + sal_Int32 nIndex = 0; + if( Index1 >>= nIndex ) + { + if( nIndex == word::WdListGalleryType::wdBulletGallery + || nIndex == word::WdListGalleryType::wdNumberGallery + || nIndex == word::WdListGalleryType::wdOutlineNumberGallery ) + return uno::Any( uno::Reference< word::XListGallery >( new SwVbaListGallery( this, mxContext, mxTextDocument, nIndex ) ) ); + } + throw uno::RuntimeException("Index out of bounds" ); +} + +// XEnumerationAccess +uno::Type +SwVbaListGalleries::getElementType() +{ + return cppu::UnoType<word::XListGallery>::get(); +} + +uno::Reference< container::XEnumeration > +SwVbaListGalleries::createEnumeration() +{ + return new ListGalleriesEnumWrapper( this ); +} + +uno::Any +SwVbaListGalleries::createCollectionObject( const css::uno::Any& aSource ) +{ + return aSource; +} + +OUString +SwVbaListGalleries::getServiceImplName() +{ + return "SwVbaListGalleries"; +} + +css::uno::Sequence<OUString> +SwVbaListGalleries::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.ListGalleries" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalistgalleries.hxx b/sw/source/ui/vba/vbalistgalleries.hxx new file mode 100644 index 0000000000..9eb8f58d93 --- /dev/null +++ b/sw/source/ui/vba/vbalistgalleries.hxx @@ -0,0 +1,51 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTGALLERIES_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTGALLERIES_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XListGalleries.hpp> +#include <com/sun/star/text/XTextDocument.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XListGalleries > SwVbaListGalleries_BASE; + +class SwVbaListGalleries : public SwVbaListGalleries_BASE +{ +private: + css::uno::Reference< css::text::XTextDocument > mxTextDocument; + +public: + /// @throws css::uno::RuntimeException + SwVbaListGalleries( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::text::XTextDocument > xTextDoc ); + + virtual ::sal_Int32 SAL_CALL getCount() override; + virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& /*not processed in this base class*/ ) override; + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaListGalleries_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTGALLERIES_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalistgallery.cxx b/sw/source/ui/vba/vbalistgallery.cxx new file mode 100644 index 0000000000..8eae71df8e --- /dev/null +++ b/sw/source/ui/vba/vbalistgallery.cxx @@ -0,0 +1,60 @@ +/* -*- 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 <utility> + +#include "vbalistgallery.hxx" +#include "vbalisttemplates.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaListGallery::SwVbaListGallery( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xTextDoc, sal_Int32 nType ) : SwVbaListGallery_BASE( rParent, rContext ), mxTextDocument(std::move( xTextDoc )), mnType( nType ) +{ +} + +SwVbaListGallery::~SwVbaListGallery() +{ +} + +uno::Any SAL_CALL +SwVbaListGallery::ListTemplates( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaListTemplates( mxParent, mxContext, mxTextDocument, mnType ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +OUString +SwVbaListGallery::getServiceImplName() +{ + return "SwVbaListGallery"; +} + +uno::Sequence< OUString > +SwVbaListGallery::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.ListGallery" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalistgallery.hxx b/sw/source/ui/vba/vbalistgallery.hxx new file mode 100644 index 0000000000..2b288aa266 --- /dev/null +++ b/sw/source/ui/vba/vbalistgallery.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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTGALLERY_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTGALLERY_HXX + +#include <ooo/vba/word/XListGallery.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextDocument.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XListGallery > SwVbaListGallery_BASE; + +class SwVbaListGallery : public SwVbaListGallery_BASE +{ +private: + css::uno::Reference< css::text::XTextDocument > mxTextDocument; + sal_Int32 mnType; + +public: + /// @throws css::uno::RuntimeException + SwVbaListGallery( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xTextDoc, sal_Int32 nType ); + virtual ~SwVbaListGallery() override; + + // Methods + virtual css::uno::Any SAL_CALL ListTemplates( const css::uno::Any& index ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTGALLERY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalisthelper.cxx b/sw/source/ui/vba/vbalisthelper.cxx new file mode 100644 index 0000000000..4b3ca1304e --- /dev/null +++ b/sw/source/ui/vba/vbalisthelper.cxx @@ -0,0 +1,661 @@ +/* -*- 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 "vbalisthelper.hxx" +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include <sal/log.hxx> +#include <ooo/vba/word/WdListGalleryType.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/style/NumberingType.hpp> +#include <com/sun/star/container/XIndexReplace.hpp> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +const sal_Int32 LIST_LEVEL_COUNT = 9; + +constexpr OUString UNO_NAME_PARENT_NUMBERING = u"ParentNumbering"_ustr; +constexpr OUString UNO_NAME_PREFIX = u"Prefix"_ustr; +constexpr OUString UNO_NAME_SUFFIX = u"Suffix"_ustr; +constexpr OUString UNO_NAME_CHAR_STYLE_NAME = u"CharStyleName"_ustr; +constexpr OUString UNO_NAME_NUMBERING_TYPE = u"NumberingType"_ustr; +constexpr OUString UNO_NAME_BULLET_CHAR = u"BulletChar"_ustr; + +constexpr OUString CHAR_CLOSED_DOT = u"\u2022"_ustr; +constexpr OUStringLiteral CHAR_EMPTY_DOT = u"o"; +constexpr OUString CHAR_SQUARE = u"\u2540"_ustr; +constexpr OUStringLiteral CHAR_STAR_SYMBOL = u"\u272A"; +constexpr OUString CHAR_FOUR_DIAMONDS = u"\u2756"_ustr; +constexpr OUStringLiteral CHAR_DIAMOND = u"\u2726"; +constexpr OUString CHAR_ARROW = u"\u27A2"_ustr; +constexpr OUStringLiteral CHAR_CHECK_MARK = u"\u2713"; + +SwVbaListHelper::SwVbaListHelper( css::uno::Reference< css::text::XTextDocument > xTextDoc, sal_Int32 nGalleryType, sal_Int32 nTemplateType ) : mxTextDocument(std::move( xTextDoc )), mnGalleryType( nGalleryType ), mnTemplateType( nTemplateType ) +{ + Init(); +} + +void SwVbaListHelper::Init() +{ + // set the numbering style name + switch( mnGalleryType ) + { + case word::WdListGalleryType::wdBulletGallery: + { + msStyleName = "WdBullet"; + break; + } + case word::WdListGalleryType::wdNumberGallery: + { + msStyleName = "WdNumber"; + break; + } + case word::WdListGalleryType::wdOutlineNumberGallery: + { + msStyleName = "WdOutlineNumber"; + break; + } + default: + { + throw uno::RuntimeException(); + } + } + msStyleName += OUString::number( mnTemplateType ); + + // get the numbering style + uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( mxTextDocument, uno::UNO_QUERY_THROW ); + mxStyleFamily.set( xStyleSupplier->getStyleFamilies()->getByName("NumberingStyles"), uno::UNO_QUERY_THROW ); + SAL_INFO("sw.vba", "numbering style name: " << msStyleName ); + if( mxStyleFamily->hasByName( msStyleName ) ) + { + mxStyleProps.set( mxStyleFamily->getByName( msStyleName ), uno::UNO_QUERY_THROW ); + mxNumberingRules.set( mxStyleProps->getPropertyValue("NumberingRules"), uno::UNO_QUERY_THROW ); + } + else + { + // create new numbering style + uno::Reference< lang::XMultiServiceFactory > xDocMSF( mxTextDocument, uno::UNO_QUERY_THROW ); + mxStyleProps.set( xDocMSF->createInstance("com.sun.star.style.NumberingStyle"), uno::UNO_QUERY_THROW ); + // insert this style into style family, or the property NumberingRules doesn't exist. + mxStyleFamily->insertByName( msStyleName, uno::Any( mxStyleProps ) ); + mxStyleProps->getPropertyValue("NumberingRules") >>= mxNumberingRules; + + CreateListTemplate(); + + mxStyleProps->setPropertyValue("NumberingRules", uno::Any( mxNumberingRules ) ); + } +} + +void SwVbaListHelper::CreateListTemplate() +{ + switch( mnGalleryType ) + { + case word::WdListGalleryType::wdBulletGallery: + { + CreateBulletListTemplate(); + break; + } + case word::WdListGalleryType::wdNumberGallery: + { + CreateNumberListTemplate(); + break; + } + case word::WdListGalleryType::wdOutlineNumberGallery: + { + CreateOutlineNumberListTemplate(); + break; + } + default: + { + throw uno::RuntimeException(); + } + } +} + +void SwVbaListHelper::CreateBulletListTemplate() +{ + // there is only 1 level for each bullet list in MSWord + sal_Int32 nLevel = 0; + uno::Sequence< beans::PropertyValue > aPropertyValues; + mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues; + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_CHAR_STYLE_NAME, uno::Any( OUString( "Bullet Symbols" ) ) ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( sal_Int16(style::NumberingType::CHAR_SPECIAL) ) ); + + OUString aBulletChar; + switch( mnTemplateType ) + { + case 1: + { + aBulletChar = CHAR_CLOSED_DOT; + break; + } + case 2: + { + aBulletChar = CHAR_EMPTY_DOT; + break; + } + case 3: + { + aBulletChar = CHAR_SQUARE; + break; + } + case 4: + { + aBulletChar = CHAR_STAR_SYMBOL; + break; + } + case 5: + { + aBulletChar = CHAR_FOUR_DIAMONDS; + break; + } + case 6: + { + aBulletChar = CHAR_ARROW; + break; + } + case 7: + { + aBulletChar = CHAR_CHECK_MARK; + break; + } + default: + { + // we only support 7 types template now + throw css::uno::RuntimeException(); + } + } + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_BULLET_CHAR, uno::Any( aBulletChar ) ); + + mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) ); +} + +void SwVbaListHelper::CreateNumberListTemplate() +{ + // there is only 1 level for each bullet list in MSWord + sal_Int32 nLevel = 0; + uno::Sequence< beans::PropertyValue > aPropertyValues; + mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues; + + sal_Int16 nNumberingType = 0; + OUString sSuffix; + switch( mnTemplateType ) + { + case 1: + { + nNumberingType = style::NumberingType::ARABIC; + sSuffix = "."; + break; + } + case 2: + { + nNumberingType = style::NumberingType::ARABIC; + sSuffix = ")"; + break; + } + case 3: + { + nNumberingType = style::NumberingType::ROMAN_UPPER; + sSuffix = "."; + break; + } + case 4: + { + nNumberingType = style::NumberingType::CHARS_UPPER_LETTER; + sSuffix = "."; + break; + } + case 5: + { + nNumberingType = style::NumberingType::CHARS_LOWER_LETTER; + sSuffix = ")"; + break; + } + case 6: + { + nNumberingType = style::NumberingType::CHARS_LOWER_LETTER; + sSuffix = "."; + break; + } + case 7: + { + nNumberingType = style::NumberingType::ROMAN_LOWER; + sSuffix = "."; + break; + } + default: + { + // we only support 7 types template now + throw css::uno::RuntimeException(); + } + } + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( nNumberingType ) ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_SUFFIX, uno::Any( sSuffix ) ); + + mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) ); +} + +void SwVbaListHelper::CreateOutlineNumberListTemplate() +{ + switch( mnTemplateType ) + { + case 1: + { + CreateOutlineNumberForType1(); + break; + } + case 2: + { + CreateOutlineNumberForType2(); + break; + } + case 3: + { + CreateOutlineNumberForType3(); + break; + } + case 4: + { + CreateOutlineNumberForType4(); + break; + } + case 5: + { + CreateOutlineNumberForType5(); + break; + } + case 6: + { + CreateOutlineNumberForType6(); + break; + } + case 7: + { + CreateOutlineNumberForType7(); + break; + } + default: + { + // we only support 7 types template now + throw css::uno::RuntimeException(); + } + } +} + +void SwVbaListHelper::CreateOutlineNumberForType1() +{ + sal_Int16 nNumberingType = 0; + OUString sPrefix; + OUString sSuffix; + uno::Sequence< beans::PropertyValue > aPropertyValues; + + for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ ) + { + mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues; + switch( nLevel ) + { + case 0: + case 1: + { + nNumberingType = style::NumberingType::ARABIC; + sPrefix.clear(); + sSuffix = ")"; + break; + } + case 2: + { + nNumberingType = style::NumberingType::ROMAN_LOWER; + sPrefix.clear(); + sSuffix = ")"; + break; + } + case 3: + { + nNumberingType = style::NumberingType::ARABIC; + sPrefix = "("; + sSuffix = ")"; + break; + } + case 4: + { + nNumberingType = style::NumberingType::CHARS_LOWER_LETTER; + sPrefix = "("; + sSuffix = ")"; + break; + } + case 5: + { + nNumberingType = style::NumberingType::ROMAN_LOWER; + sPrefix = "("; + sSuffix = ")"; + break; + } + case 6: + { + nNumberingType = style::NumberingType::ARABIC; + sPrefix.clear(); + sSuffix = "."; + break; + } + case 7: + { + nNumberingType = style::NumberingType::CHARS_LOWER_LETTER; + sPrefix.clear(); + sSuffix = "."; + break; + } + case 8: + { + nNumberingType = style::NumberingType::ROMAN_LOWER; + sPrefix.clear(); + sSuffix = "."; + break; + } + } + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( nNumberingType ) ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PREFIX, uno::Any( sPrefix ) ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_SUFFIX, uno::Any( sSuffix ) ); + mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) ); + } +} + +void SwVbaListHelper::CreateOutlineNumberForType2() +{ + sal_Int16 nParentNumbering = 0; + OUString sSuffix( '.' ); + uno::Sequence< beans::PropertyValue > aPropertyValues; + + for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ ) + { + mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues; + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( sal_Int16(style::NumberingType::ARABIC) ) ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_SUFFIX, uno::Any( sSuffix ) ); + if( nLevel != 0 ) + { + nParentNumbering = sal_Int16( nLevel - 1 ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PARENT_NUMBERING, uno::Any( nParentNumbering ) ); + } + mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) ); + } +} + +void SwVbaListHelper::CreateOutlineNumberForType3() +{ + OUString aBulletChar; + uno::Sequence< beans::PropertyValue > aPropertyValues; + + for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ ) + { + mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues; + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( sal_Int16(style::NumberingType::CHAR_SPECIAL) ) ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_CHAR_STYLE_NAME, uno::Any( OUString("Bullet Symbols") ) ); + switch( nLevel ) + { + case 0: + { + aBulletChar = CHAR_FOUR_DIAMONDS; + break; + } + case 1: + case 5: + { + aBulletChar = CHAR_ARROW; + break; + } + case 2: + case 6: + { + aBulletChar = CHAR_SQUARE; + break; + } + case 3: + case 7: + { + aBulletChar = CHAR_CLOSED_DOT; + break; + } + case 4: + case 8: + { + aBulletChar = CHAR_DIAMOND; + break; + } + } + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_BULLET_CHAR, uno::Any( aBulletChar ) ); + mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) ); + } +} + +void SwVbaListHelper::CreateOutlineNumberForType4() +{ + sal_Int16 nNumberingType = 0; + OUString sPrefix; + OUString sSuffix; + uno::Sequence< beans::PropertyValue > aPropertyValues; + + for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ ) + { + mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues; + switch( nLevel ) + { + case 0: + { + nNumberingType = style::NumberingType::ROMAN_UPPER; + sPrefix.clear(); + sSuffix = "."; + break; + } + case 1: + { + nNumberingType = style::NumberingType::ARABIC; + sPrefix.clear(); + sSuffix = "."; + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PARENT_NUMBERING, uno::Any( sal_Int16(0) ) ); + break; + } + case 2: + { + nNumberingType = style::NumberingType::CHARS_LOWER_LETTER; + sPrefix = "("; + sSuffix = ")"; + break; + } + case 3: + { + nNumberingType = style::NumberingType::ROMAN_LOWER; + sPrefix = "("; + sSuffix = ")"; + break; + } + case 4: + { + nNumberingType = style::NumberingType::ARABIC; + sPrefix.clear(); + sSuffix = ")"; + break; + } + case 5: + { + nNumberingType = style::NumberingType::CHARS_LOWER_LETTER; + sPrefix.clear(); + sSuffix = ")"; + break; + } + case 6: + { + nNumberingType = style::NumberingType::ROMAN_LOWER; + sPrefix.clear(); + sSuffix = ")"; + break; + } + case 7: + { + nNumberingType = style::NumberingType::CHARS_LOWER_LETTER; + sPrefix.clear(); + sSuffix = "."; + break; + } + case 8: + { + nNumberingType = style::NumberingType::ROMAN_LOWER; + sPrefix.clear(); + sSuffix = "."; + break; + } + } + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( nNumberingType ) ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PREFIX, uno::Any( sPrefix ) ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_SUFFIX, uno::Any( sSuffix ) ); + mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) ); + } +} + +void SwVbaListHelper::CreateOutlineNumberForType5() +{ + sal_Int16 nParentNumbering = 0; + uno::Sequence< beans::PropertyValue > aPropertyValues; + + for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ ) + { + mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues; + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( sal_Int16(style::NumberingType::ARABIC) ) ); + if( nLevel != 0 ) + { + nParentNumbering = sal_Int16( nLevel - 1 ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PARENT_NUMBERING, uno::Any( nParentNumbering ) ); + } + mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) ); + } +} + +void SwVbaListHelper::CreateOutlineNumberForType6() +{ + sal_Int16 nNumberingType = 0; + OUString sPrefix; + OUString sSuffix; + uno::Sequence< beans::PropertyValue > aPropertyValues; + + for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ ) + { + mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues; + switch( nLevel ) + { + case 0: + { + nNumberingType = style::NumberingType::ROMAN_UPPER; + sPrefix.clear(); + sSuffix = "."; + break; + } + case 1: + { + nNumberingType = style::NumberingType::CHARS_UPPER_LETTER; + sPrefix.clear(); + sSuffix = "."; + break; + } + case 2: + { + nNumberingType = style::NumberingType::ARABIC; + sPrefix.clear(); + sSuffix = ")"; + break; + } + case 3: + { + nNumberingType = style::NumberingType::CHARS_LOWER_LETTER; + sPrefix.clear(); + sSuffix = ")"; + break; + } + case 4: + { + nNumberingType = style::NumberingType::ARABIC; + sPrefix = "("; + sSuffix = ")"; + break; + } + case 5: + { + nNumberingType = style::NumberingType::CHARS_LOWER_LETTER; + sPrefix = "("; + sSuffix = ")"; + break; + } + case 6: + { + nNumberingType = style::NumberingType::ROMAN_LOWER; + sPrefix = "("; + sSuffix = ")"; + break; + } + case 7: + { + nNumberingType = style::NumberingType::CHARS_LOWER_LETTER; + sPrefix = "("; + sSuffix = "."; + break; + } + case 8: + { + nNumberingType = style::NumberingType::ROMAN_LOWER; + sPrefix = "("; + sSuffix = "."; + break; + } + } + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( nNumberingType ) ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PREFIX, uno::Any( sPrefix ) ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_SUFFIX, uno::Any( sSuffix ) ); + mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) ); + } +} + +void SwVbaListHelper::CreateOutlineNumberForType7() +{ + uno::Sequence< beans::PropertyValue > aPropertyValues; + + for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ ) + { + mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues; + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( sal_Int16(style::NumberingType::ARABIC) ) ); + setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PREFIX, uno::Any( OUString("Chapter ") ) ); + mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) ); + } +} + +uno::Any SwVbaListHelper::getPropertyValueWithNameAndLevel( sal_Int32 nLevel, const OUString& sName ) +{ + uno::Sequence< beans::PropertyValue > aPropertyValues; + mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues; + return getPropertyValue( aPropertyValues, sName ); +} + +void SwVbaListHelper::setPropertyValueWithNameAndLevel( sal_Int32 nLevel, const OUString& sName, const css::uno::Any& aValue ) +{ + uno::Sequence< beans::PropertyValue > aPropertyValues; + mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues; + setOrAppendPropertyValue( aPropertyValues, sName, aValue ); + mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) ); + mxStyleProps->setPropertyValue("NumberingRules", uno::Any( mxNumberingRules ) ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalisthelper.hxx b/sw/source/ui/vba/vbalisthelper.hxx new file mode 100644 index 0000000000..599e4f6864 --- /dev/null +++ b/sw/source/ui/vba/vbalisthelper.hxx @@ -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/. + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTHELPER_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTHELPER_HXX + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XIndexReplace.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/text/XTextDocument.hpp> + +#include <memory> + +class SwVbaListHelper; +typedef std::shared_ptr< SwVbaListHelper > SwVbaListHelperRef; + +class SwVbaListHelper +{ +private: + css::uno::Reference< css::text::XTextDocument > mxTextDocument; + css::uno::Reference< css::container::XIndexReplace > mxNumberingRules; + css::uno::Reference< css::container::XNameContainer > mxStyleFamily; + css::uno::Reference< css::beans::XPropertySet > mxStyleProps; + sal_Int32 mnGalleryType; + sal_Int32 mnTemplateType; + OUString msStyleName; + + /// @throws css::uno::RuntimeException + void Init(); + /// @throws css::uno::RuntimeException + void CreateListTemplate(); + /// @throws css::uno::RuntimeException + void CreateBulletListTemplate(); + /// @throws css::uno::RuntimeException + void CreateNumberListTemplate(); + /// @throws css::uno::RuntimeException + void CreateOutlineNumberListTemplate(); + /// @throws css::uno::RuntimeException + void CreateOutlineNumberForType1(); + /// @throws css::uno::RuntimeException + void CreateOutlineNumberForType2(); + /// @throws css::uno::RuntimeException + void CreateOutlineNumberForType3(); + /// @throws css::uno::RuntimeException + void CreateOutlineNumberForType4(); + /// @throws css::uno::RuntimeException + void CreateOutlineNumberForType5(); + /// @throws css::uno::RuntimeException + void CreateOutlineNumberForType6(); + /// @throws css::uno::RuntimeException + void CreateOutlineNumberForType7(); + +public: + /// @throws css::uno::RuntimeException + SwVbaListHelper( css::uno::Reference< css::text::XTextDocument > xTextDoc, sal_Int32 nGalleryType, sal_Int32 nTemplateType ); + + sal_Int32 getGalleryType() const { return mnGalleryType; } + const css::uno::Reference< css::container::XIndexReplace >& getNumberingRules() const { return mxNumberingRules; } + /// @throws css::uno::RuntimeException + css::uno::Any getPropertyValueWithNameAndLevel( sal_Int32 nLevel, const OUString& sName ); + /// @throws css::uno::RuntimeException + void setPropertyValueWithNameAndLevel( sal_Int32 nLevel, const OUString& sName, const css::uno::Any& aValue ); + +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalistlevel.cxx b/sw/source/ui/vba/vbalistlevel.cxx new file mode 100644 index 0000000000..43f16e8524 --- /dev/null +++ b/sw/source/ui/vba/vbalistlevel.cxx @@ -0,0 +1,386 @@ +/* -*- 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 "vbalistlevel.hxx" +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include <com/sun/star/style/NumberingType.hpp> +#include <ooo/vba/word/WdListNumberStyle.hpp> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <ooo/vba/word/WdListLevelAlignment.hpp> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaListLevel::SwVbaListLevel( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, SwVbaListHelperRef pHelper, sal_Int32 nLevel ) : SwVbaListLevel_BASE( rParent, rContext ), m_pListHelper(std::move( pHelper )), mnLevel( nLevel ) +{ +} + +SwVbaListLevel::~SwVbaListLevel() +{ +} + +::sal_Int32 SAL_CALL SwVbaListLevel::getAlignment() +{ + sal_Int16 nAlignment = 0; + m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "Adjust" ) >>= nAlignment; + switch( nAlignment ) + { + case text::HoriOrientation::LEFT: + { + nAlignment = word::WdListLevelAlignment::wdListLevelAlignLeft; + break; + } + case text::HoriOrientation::RIGHT: + { + nAlignment = word::WdListLevelAlignment::wdListLevelAlignRight; + break; + } + case text::HoriOrientation::CENTER: + { + nAlignment = word::WdListLevelAlignment::wdListLevelAlignCenter; + break; + } + default: + { + throw uno::RuntimeException(); + } + } + return nAlignment; +} + +void SAL_CALL SwVbaListLevel::setAlignment( ::sal_Int32 _alignment ) +{ + sal_Int16 nAlignment = text::HoriOrientation::LEFT; + switch( _alignment ) + { + case word::WdListLevelAlignment::wdListLevelAlignLeft: + { + nAlignment = text::HoriOrientation::LEFT; + break; + } + case word::WdListLevelAlignment::wdListLevelAlignRight: + { + nAlignment = text::HoriOrientation::RIGHT; + break; + } + case word::WdListLevelAlignment::wdListLevelAlignCenter: + { + nAlignment = text::HoriOrientation::CENTER; + break; + } + default: + { + throw uno::RuntimeException(); + } + } + m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "Adjust", uno::Any( nAlignment ) ); +} + +uno::Reference< ::ooo::vba::word::XFont > SAL_CALL SwVbaListLevel::getFont() +{ + throw uno::RuntimeException("Not implemented" ); +} + +void SAL_CALL SwVbaListLevel::setFont( const uno::Reference< ::ooo::vba::word::XFont >& /*_font*/ ) +{ + throw uno::RuntimeException("Not implemented" ); +} + +::sal_Int32 SAL_CALL SwVbaListLevel::getIndex() +{ + return mnLevel + 1; +} + +OUString SAL_CALL SwVbaListLevel::getLinkedStyle() +{ + // TODO: + return OUString(); +} + +void SAL_CALL SwVbaListLevel::setLinkedStyle( const OUString& /*_linkedstyle*/ ) +{ + // TODO: +} + +OUString SAL_CALL SwVbaListLevel::getNumberFormat() +{ + // TODO:: + return OUString(); +} + +void SAL_CALL SwVbaListLevel::setNumberFormat( const OUString& /*_numberformat*/ ) +{ + // TODO:: +} + +float SAL_CALL SwVbaListLevel::getNumberPosition() +{ + // indentAt + firstlineindent + sal_Int32 nIndentAt = 0; + sal_Int32 nFirstLineIndent = 0; + m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "IndentAt" ) >>= nIndentAt; + m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "FirstLineIndent" ) >>= nFirstLineIndent; + + sal_Int32 nResult = nIndentAt + nFirstLineIndent; + + return static_cast< float >( Millimeter::getInPoints( nResult ) ); +} + +void SAL_CALL SwVbaListLevel::setNumberPosition( float _numberposition ) +{ + sal_Int32 nNumberPosition = Millimeter::getInHundredthsOfOneMillimeter( _numberposition ); + + sal_Int32 nIndentAt = 0; + m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "IndentAt" ) >>= nIndentAt; + + sal_Int32 nFirstLineIndent = nNumberPosition - nIndentAt; + m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "FirstLineIndent", uno::Any( nFirstLineIndent ) ); +} + +::sal_Int32 SAL_CALL SwVbaListLevel::getNumberStyle() +{ + sal_Int16 nNumberingType = 0; + m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "NumberingType" ) >>= nNumberingType; + switch( nNumberingType ) + { + case style::NumberingType::CHAR_SPECIAL: + { + nNumberingType = word::WdListNumberStyle::wdListNumberStyleBullet; + break; + } + case style::NumberingType::CHARS_UPPER_LETTER: + { + nNumberingType = word::WdListNumberStyle::wdListNumberStyleUppercaseLetter; + break; + } + case style::NumberingType::CHARS_LOWER_LETTER: + { + nNumberingType = word::WdListNumberStyle::wdListNumberStyleLowercaseLetter; + break; + } + case style::NumberingType::ROMAN_UPPER: + { + nNumberingType = word::WdListNumberStyle::wdListNumberStyleUppercaseRoman; + break; + } + case style::NumberingType::ROMAN_LOWER: + { + nNumberingType = word::WdListNumberStyle::wdListNumberStyleLowercaseRoman; + break; + } + case style::NumberingType::ARABIC: + { + nNumberingType = word::WdListNumberStyle::wdListNumberStyleArabic; + break; + } + case style::NumberingType::NUMBER_NONE: + { + nNumberingType = word::WdListNumberStyle::wdListNumberStyleNone; + break; + } + case style::NumberingType::FULLWIDTH_ARABIC: + { + nNumberingType = word::WdListNumberStyle::wdListNumberStyleArabicFullWidth; + break; + } + case style::NumberingType::CIRCLE_NUMBER: + { + nNumberingType = word::WdListNumberStyle::wdListNumberStyleNumberInCircle; + break; + } + case style::NumberingType::CHARS_ARABIC: + { + nNumberingType = word::WdListNumberStyle::wdListNumberStyleCardinalText; + break; + } + default: + { + throw uno::RuntimeException("Not implemented" ); + } + } + return nNumberingType; +} + +void SAL_CALL SwVbaListLevel::setNumberStyle( ::sal_Int32 _numberstyle ) +{ + sal_Int16 nNumberingType = 0; + switch( _numberstyle ) + { + case word::WdListNumberStyle::wdListNumberStyleBullet: + { + nNumberingType = style::NumberingType::CHAR_SPECIAL; + break; + } + case word::WdListNumberStyle::wdListNumberStyleUppercaseLetter: + { + nNumberingType = style::NumberingType::CHARS_UPPER_LETTER_N; + break; + } + case word::WdListNumberStyle::wdListNumberStyleLowercaseLetter: + { + nNumberingType = style::NumberingType::CHARS_LOWER_LETTER_N; + break; + } + case word::WdListNumberStyle::wdListNumberStyleUppercaseRoman: + { + nNumberingType = style::NumberingType::ROMAN_UPPER; + break; + } + case word::WdListNumberStyle::wdListNumberStyleLowercaseRoman: + { + nNumberingType = style::NumberingType::ROMAN_LOWER; + break; + } + case word::WdListNumberStyle::wdListNumberStyleArabic: + { + nNumberingType = style::NumberingType::ARABIC; + break; + } + case word::WdListNumberStyle::wdListNumberStyleNone: + { + nNumberingType = style::NumberingType::NUMBER_NONE; + break; + } + case word::WdListNumberStyle::wdListNumberStyleArabicFullWidth: + { + nNumberingType = style::NumberingType::FULLWIDTH_ARABIC; + break; + } + case word::WdListNumberStyle::wdListNumberStyleNumberInCircle: + { + nNumberingType = style::NumberingType::CIRCLE_NUMBER; + break; + } + case word::WdListNumberStyle::wdListNumberStyleCardinalText: + { + nNumberingType = style::NumberingType::CHARS_ARABIC; + break; + } + case word::WdListNumberStyle::wdListNumberStyleOrdinal: + case word::WdListNumberStyle::wdListNumberStyleOrdinalText: + case word::WdListNumberStyle::wdListNumberStyleKanji: + case word::WdListNumberStyle::wdListNumberStyleKanjiDigit: + case word::WdListNumberStyle::wdListNumberStyleAiueoHalfWidth: + case word::WdListNumberStyle::wdListNumberStyleIrohaHalfWidth: + { + nNumberingType = style::NumberingType::ARABIC; + break; + } + default: + { + throw uno::RuntimeException("Not implemented" ); + } + } + + m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "NumberingType", uno::Any( nNumberingType ) ); +} + +::sal_Int32 SAL_CALL SwVbaListLevel::getResetOnHigher() +{ + //seems not support? + return 0; +} + +void SAL_CALL SwVbaListLevel::setResetOnHigher( ::sal_Int32 /*_resetonhigher*/ ) +{ + //seems not support? +} + +::sal_Int32 SAL_CALL SwVbaListLevel::getStartAt() +{ + sal_Int16 nStartWith = 0; + m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "StartWith" ) >>= nStartWith; + return nStartWith; +} + +void SAL_CALL SwVbaListLevel::setStartAt( ::sal_Int32 _startat ) +{ + sal_Int16 nStartWith = static_cast<sal_Int16>(_startat); + m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "StartWith", uno::Any( nStartWith ) ); +} + +float SAL_CALL SwVbaListLevel::getTabPosition() +{ + sal_Int32 nTabPosition = 0; + m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "ListtabStopPosition" ) >>= nTabPosition; + + return static_cast< float >( Millimeter::getInPoints( nTabPosition ) ); +} + +void SAL_CALL SwVbaListLevel::setTabPosition( float _tabposition ) +{ + sal_Int32 nTabPosition = Millimeter::getInHundredthsOfOneMillimeter( _tabposition ); + m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "ListtabStopPosition", uno::Any( nTabPosition ) ); +} + +float SAL_CALL SwVbaListLevel::getTextPosition() +{ + // indentAt + sal_Int32 nIndentAt = 0; + m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "IndentAt" ) >>= nIndentAt; + + return static_cast< float >( Millimeter::getInPoints( nIndentAt ) ); +} + +void SAL_CALL SwVbaListLevel::setTextPosition( float _textposition ) +{ + sal_Int32 nIndentAt = 0; + sal_Int32 nFirstLineIndent = 0; + m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "IndentAt" ) >>= nIndentAt; + m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "FirstLineIndent" ) >>= nFirstLineIndent; + + sal_Int32 nAlignedAt = nIndentAt + nFirstLineIndent; + + nIndentAt = Millimeter::getInHundredthsOfOneMillimeter( _textposition ); + nFirstLineIndent = nAlignedAt - nIndentAt; + m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "IndentAt", uno::Any( nIndentAt ) ); + m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "FirstLineIndent", uno::Any( nFirstLineIndent ) ); +} + +::sal_Int32 SAL_CALL SwVbaListLevel::getTrailingCharacter() +{ + sal_Int16 nLabelFollowedBy= 0; + m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "LabelFollowedBy" ) >>= nLabelFollowedBy; + + return nLabelFollowedBy; +} + +void SAL_CALL SwVbaListLevel::setTrailingCharacter( ::sal_Int32 _trailingcharacter ) +{ + sal_Int16 nLabelFollowedBy = static_cast<sal_Int16>(_trailingcharacter); + m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "LabelFollowedBy", uno::Any( nLabelFollowedBy ) ); +} + +OUString +SwVbaListLevel::getServiceImplName() +{ + return "SwVbaListLevel"; +} + +uno::Sequence< OUString > +SwVbaListLevel::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.ListLevel" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalistlevel.hxx b/sw/source/ui/vba/vbalistlevel.hxx new file mode 100644 index 0000000000..e9a8e23e13 --- /dev/null +++ b/sw/source/ui/vba/vbalistlevel.hxx @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTLEVEL_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTLEVEL_HXX + +#include <ooo/vba/word/XListLevel.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include "vbalisthelper.hxx" + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XListLevel > SwVbaListLevel_BASE; + +class SwVbaListLevel : public SwVbaListLevel_BASE +{ +private: + SwVbaListHelperRef m_pListHelper; + sal_Int32 mnLevel; + +public: + /// @throws css::uno::RuntimeException + SwVbaListLevel( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, SwVbaListHelperRef pHelper, sal_Int32 nLevel ); + virtual ~SwVbaListLevel() override; + + // Attributes + virtual ::sal_Int32 SAL_CALL getAlignment() override; + virtual void SAL_CALL setAlignment( ::sal_Int32 _alignment ) override; + virtual css::uno::Reference< ::ooo::vba::word::XFont > SAL_CALL getFont() override; + virtual void SAL_CALL setFont( const css::uno::Reference< ::ooo::vba::word::XFont >& _font ) override; + virtual ::sal_Int32 SAL_CALL getIndex() override; + virtual OUString SAL_CALL getLinkedStyle() override; + virtual void SAL_CALL setLinkedStyle( const OUString& _linkedstyle ) override; + virtual OUString SAL_CALL getNumberFormat() override; + virtual void SAL_CALL setNumberFormat( const OUString& _numberformat ) override; + virtual float SAL_CALL getNumberPosition() override; + virtual void SAL_CALL setNumberPosition( float _numberposition ) override; + virtual ::sal_Int32 SAL_CALL getNumberStyle() override; + virtual void SAL_CALL setNumberStyle( ::sal_Int32 _numberstyle ) override; + virtual ::sal_Int32 SAL_CALL getResetOnHigher() override; + virtual void SAL_CALL setResetOnHigher( ::sal_Int32 _resetonhigher ) override; + virtual ::sal_Int32 SAL_CALL getStartAt() override; + virtual void SAL_CALL setStartAt( ::sal_Int32 _startat ) override; + virtual float SAL_CALL getTabPosition() override; + virtual void SAL_CALL setTabPosition( float _tabposition ) override; + virtual float SAL_CALL getTextPosition() override; + virtual void SAL_CALL setTextPosition( float _textposition ) override; + virtual ::sal_Int32 SAL_CALL getTrailingCharacter() override; + virtual void SAL_CALL setTrailingCharacter( ::sal_Int32 _trailingcharacter ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTLEVEL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalistlevels.cxx b/sw/source/ui/vba/vbalistlevels.cxx new file mode 100644 index 0000000000..3f0d83e478 --- /dev/null +++ b/sw/source/ui/vba/vbalistlevels.cxx @@ -0,0 +1,111 @@ +/* -*- 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 "vbalistlevels.hxx" +#include "vbalistlevel.hxx" +#include <ooo/vba/word/WdListGalleryType.hpp> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class ListLevelsEnumWrapper : public EnumerationHelper_BASE +{ + SwVbaListLevels* m_pListLevels; + sal_Int32 m_nIndex; +public: + explicit ListLevelsEnumWrapper( SwVbaListLevels* pLevels ) : m_pListLevels( pLevels ), m_nIndex( 1 ) {} + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( m_nIndex <= m_pListLevels->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( m_nIndex <= m_pListLevels->getCount() ) + return m_pListLevels->Item( uno::Any( m_nIndex++ ), uno::Any() ); + throw container::NoSuchElementException(); + } +}; + +} + +SwVbaListLevels::SwVbaListLevels( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, SwVbaListHelperRef pHelper ) : SwVbaListLevels_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >() ), m_pListHelper(std::move( pHelper )) +{ +} + +::sal_Int32 SAL_CALL SwVbaListLevels::getCount() +{ + sal_Int32 nGalleryType = m_pListHelper->getGalleryType(); + if( nGalleryType == word::WdListGalleryType::wdBulletGallery + || nGalleryType == word::WdListGalleryType::wdNumberGallery ) + return 1; + else if( nGalleryType == word::WdListGalleryType::wdOutlineNumberGallery ) + return 9; + return 0; +} + +uno::Any SAL_CALL SwVbaListLevels::Item( const uno::Any& Index1, const uno::Any& /*not processed in this base class*/ ) +{ + sal_Int32 nIndex = 0; + if( !( Index1 >>= nIndex ) ) + throw uno::RuntimeException(); + if( nIndex <=0 || nIndex > getCount() ) + throw uno::RuntimeException("Index out of bounds" ); + + return uno::Any( uno::Reference< word::XListLevel >( new SwVbaListLevel( this, mxContext, m_pListHelper, nIndex - 1 ) ) ); +} + +// XEnumerationAccess +uno::Type +SwVbaListLevels::getElementType() +{ + return cppu::UnoType<word::XListLevel>::get(); +} + +uno::Reference< container::XEnumeration > +SwVbaListLevels::createEnumeration() +{ + return new ListLevelsEnumWrapper( this ); +} + +uno::Any +SwVbaListLevels::createCollectionObject( const css::uno::Any& aSource ) +{ + return aSource; +} + +OUString +SwVbaListLevels::getServiceImplName() +{ + return "SwVbaListLevels"; +} + +css::uno::Sequence<OUString> +SwVbaListLevels::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.ListLevels" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalistlevels.hxx b/sw/source/ui/vba/vbalistlevels.hxx new file mode 100644 index 0000000000..2b3bb44d0f --- /dev/null +++ b/sw/source/ui/vba/vbalistlevels.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 <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XListLevels.hpp> +#include "vbalisthelper.hxx" + +typedef CollTestImplHelper< ooo::vba::word::XListLevels > SwVbaListLevels_BASE; + +class SwVbaListLevels : public SwVbaListLevels_BASE +{ +private: + SwVbaListHelperRef m_pListHelper; + +public: + /// @throws css::uno::RuntimeException + SwVbaListLevels( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, SwVbaListHelperRef pHelper ); + + virtual ::sal_Int32 SAL_CALL getCount() override; + virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& /*not processed in this base class*/ ) override; + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaListLevels_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalisttemplate.cxx b/sw/source/ui/vba/vbalisttemplate.cxx new file mode 100644 index 0000000000..032bc98162 --- /dev/null +++ b/sw/source/ui/vba/vbalisttemplate.cxx @@ -0,0 +1,66 @@ +/* -*- 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 "vbalisttemplate.hxx" +#include "vbalistlevels.hxx" +#include <com/sun/star/beans/XPropertySet.hpp> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaListTemplate::SwVbaListTemplate( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, const uno::Reference< text::XTextDocument >& xTextDoc, sal_Int32 nGalleryType, sal_Int32 nTemplateType ) : SwVbaListTemplate_BASE( rParent, rContext ) +{ + m_pListHelper = std::make_shared<SwVbaListHelper>( xTextDoc, nGalleryType, nTemplateType ); +} + +SwVbaListTemplate::~SwVbaListTemplate() +{ +} + +uno::Any SAL_CALL +SwVbaListTemplate::ListLevels( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaListLevels( mxParent, mxContext, m_pListHelper ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +void SwVbaListTemplate::applyListTemplate( uno::Reference< beans::XPropertySet > const & xProps ) +{ + uno::Reference< container::XIndexReplace > xNumberingRules = m_pListHelper->getNumberingRules(); + xProps->setPropertyValue("NumberingRules", uno::Any( xNumberingRules ) ); +} + +OUString +SwVbaListTemplate::getServiceImplName() +{ + return "SwVbaListTemplate"; +} + +uno::Sequence< OUString > +SwVbaListTemplate::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.ListTemplate" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalisttemplate.hxx b/sw/source/ui/vba/vbalisttemplate.hxx new file mode 100644 index 0000000000..a690b6c820 --- /dev/null +++ b/sw/source/ui/vba/vbalisttemplate.hxx @@ -0,0 +1,51 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTTEMPLATE_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTTEMPLATE_HXX + +#include <ooo/vba/word/XListTemplate.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextDocument.hpp> +#include "vbalisthelper.hxx" + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XListTemplate > SwVbaListTemplate_BASE; + +class SwVbaListTemplate : public SwVbaListTemplate_BASE +{ +private: + SwVbaListHelperRef m_pListHelper; + +public: + /// @throws css::uno::RuntimeException + SwVbaListTemplate( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, const css::uno::Reference< css::text::XTextDocument >& xTextDoc, sal_Int32 nGalleryType, sal_Int32 nTemplateType ); + virtual ~SwVbaListTemplate() override; + + /// @throws css::uno::RuntimeException + void applyListTemplate( css::uno::Reference< css::beans::XPropertySet > const & xProps ); + + // Methods + virtual css::uno::Any SAL_CALL ListLevels( const css::uno::Any& index ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTTEMPLATE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalisttemplates.cxx b/sw/source/ui/vba/vbalisttemplates.cxx new file mode 100644 index 0000000000..a9cc52d4bc --- /dev/null +++ b/sw/source/ui/vba/vbalisttemplates.cxx @@ -0,0 +1,106 @@ +/* -*- 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 <utility> + +#include "vbalisttemplates.hxx" +#include "vbalisttemplate.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class ListTemplatesEnumWrapper : public EnumerationHelper_BASE +{ + SwVbaListTemplates* m_pListTemplates; + sal_Int32 m_nIndex; +public: + explicit ListTemplatesEnumWrapper( SwVbaListTemplates* pTemplates ) : m_pListTemplates( pTemplates ), m_nIndex( 1 ) {} + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( m_nIndex <= m_pListTemplates->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( m_nIndex <= m_pListTemplates->getCount() ) + return m_pListTemplates->Item( uno::Any( m_nIndex++ ), uno::Any() ); + throw container::NoSuchElementException(); + } +}; + +} + +SwVbaListTemplates::SwVbaListTemplates( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< text::XTextDocument > xTextDoc, sal_Int32 nType ) : SwVbaListTemplates_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >() ), mxTextDocument(std::move( xTextDoc )), mnGalleryType( nType ) +{ +} + +::sal_Int32 SAL_CALL SwVbaListTemplates::getCount() +{ + // 3 types of list( bullet, numbered and outline ) + return 7; +} + +uno::Any SAL_CALL SwVbaListTemplates::Item( const uno::Any& Index1, const uno::Any& /*not processed in this base class*/ ) +{ + sal_Int32 nIndex = 0; + if( !( Index1 >>= nIndex ) ) + throw uno::RuntimeException(); + if( nIndex <=0 || nIndex > getCount() ) + throw uno::RuntimeException("Index out of bounds" ); + + return uno::Any( uno::Reference< word::XListTemplate >( new SwVbaListTemplate( this, mxContext, mxTextDocument, mnGalleryType, nIndex ) ) ); +} + +// XEnumerationAccess +uno::Type +SwVbaListTemplates::getElementType() +{ + return cppu::UnoType<word::XListTemplate>::get(); +} + +uno::Reference< container::XEnumeration > +SwVbaListTemplates::createEnumeration() +{ + return new ListTemplatesEnumWrapper( this ); +} + +uno::Any +SwVbaListTemplates::createCollectionObject( const css::uno::Any& aSource ) +{ + return aSource; +} + +OUString +SwVbaListTemplates::getServiceImplName() +{ + return "SwVbaListTemplates"; +} + +css::uno::Sequence<OUString> +SwVbaListTemplates::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.ListTemplates" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbalisttemplates.hxx b/sw/source/ui/vba/vbalisttemplates.hxx new file mode 100644 index 0000000000..bf5c34f6ee --- /dev/null +++ b/sw/source/ui/vba/vbalisttemplates.hxx @@ -0,0 +1,52 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTTEMPLATES_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTTEMPLATES_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XListTemplates.hpp> +#include <com/sun/star/text/XTextDocument.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XListTemplates > SwVbaListTemplates_BASE; + +class SwVbaListTemplates : public SwVbaListTemplates_BASE +{ +private: + css::uno::Reference< css::text::XTextDocument > mxTextDocument; + sal_Int32 mnGalleryType; + +public: + /// @throws css::uno::RuntimeException + SwVbaListTemplates( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::text::XTextDocument > xTextDoc, sal_Int32 nType ); + + virtual ::sal_Int32 SAL_CALL getCount() override; + virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& /*not processed in this base class*/ ) override; + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaListTemplates_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTTEMPLATES_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbamailmerge.cxx b/sw/source/ui/vba/vbamailmerge.cxx new file mode 100644 index 0000000000..479f5dfd7d --- /dev/null +++ b/sw/source/ui/vba/vbamailmerge.cxx @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column:100 -*- */ +/* + * 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/. + */ + +#include "vbamailmerge.hxx" + +#include <ooo/vba/word/WdMailMergeMainDocType.hpp> + +SwVbaMailMerge::SwVbaMailMerge(const css::uno::Reference<ooo::vba::XHelperInterface>& xParent, + const css::uno::Reference<css::uno::XComponentContext>& xContext) + : SwVbaMailMerge_BASE(xParent, xContext) + , m_nMainDocType(ooo::vba::word::WdMailMergeMainDocType::wdNotAMergeDocument) +{ +} + +SwVbaMailMerge::~SwVbaMailMerge() {} + +rtl::Reference<SwVbaMailMerge> const& +SwVbaMailMerge::get(const css::uno::Reference<ooo::vba::XHelperInterface>& xParent, + const css::uno::Reference<css::uno::XComponentContext>& xContext) +{ + static rtl::Reference<SwVbaMailMerge> xInstance(new SwVbaMailMerge(xParent, xContext)); + + return xInstance; +} + +sal_Int32 SAL_CALL SwVbaMailMerge::getMainDocumentType() { return m_nMainDocType; } + +void SAL_CALL SwVbaMailMerge::setMainDocumentType(sal_Int32 _maindocumenttype) +{ + m_nMainDocType = _maindocumenttype; +} + +// Completely dummy, no-op. +void SAL_CALL SwVbaMailMerge::OpenDataSource( + const OUString&, const css::uno::Any&, const css::uno::Any&, const css::uno::Any&, + const css::uno::Any&, const css::uno::Any&, const css::uno::Any&, const css::uno::Any&, + const css::uno::Any&, const css::uno::Any&, const css::uno::Any&, const css::uno::Any&, + const css::uno::Any&, const css::uno::Any&, const css::uno::Any&, const css::uno::Any&) +{ +} + +OUString SwVbaMailMerge::getServiceImplName() { return "SwVbaMailMerge"; } + +css::uno::Sequence<OUString> SwVbaMailMerge::getServiceNames() +{ + static css::uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.MailMerge" }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbamailmerge.hxx b/sw/source/ui/vba/vbamailmerge.hxx new file mode 100644 index 0000000000..bfc28667d7 --- /dev/null +++ b/sw/source/ui/vba/vbamailmerge.hxx @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAMAILMERGE_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAMAILMERGE_HXX + +#include <ooo/vba/word/XMailMerge.hpp> +#include <rtl/ref.hxx> +#include <vbahelper/vbahelperinterface.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XMailMerge> SwVbaMailMerge_BASE; + +// Singleton class. Get the single instance using the get() method. + +class SwVbaMailMerge : public SwVbaMailMerge_BASE +{ + sal_Int32 m_nMainDocType; + + SwVbaMailMerge(const css::uno::Reference<ooo::vba::XHelperInterface>& xParent, + const css::uno::Reference<css::uno::XComponentContext>& xContext); + +public: + virtual ~SwVbaMailMerge() override; + + static rtl::Reference<SwVbaMailMerge> const& + get(const css::uno::Reference<ooo::vba::XHelperInterface>& xParent, + const css::uno::Reference<css::uno::XComponentContext>& xContext); + + // XMailMerge + virtual sal_Int32 SAL_CALL getMainDocumentType() override; + virtual void SAL_CALL setMainDocumentType(sal_Int32 _maindocumenttype) override; + + virtual void SAL_CALL + OpenDataSource(const OUString& Name, const css::uno::Any& Format, + const css::uno::Any& ConfirmConversions, const css::uno::Any& ReadOnly, + const css::uno::Any& LinkToSource, const css::uno::Any& AddToRecentFiles, + const css::uno::Any& PasswordDocument, const css::uno::Any& PasswordTemplate, + const css::uno::Any& Revert, const css::uno::Any& WritePasswordDocument, + const css::uno::Any& WritePasswordTemplate, const css::uno::Any& Connection, + const css::uno::Any& SQLStatement, const css::uno::Any& SQLStatement1, + const css::uno::Any& OpenExclusive, const css::uno::Any& SubType) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAMAILMERGE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaoptions.cxx b/sw/source/ui/vba/vbaoptions.cxx new file mode 100644 index 0000000000..ef74dcd8a6 --- /dev/null +++ b/sw/source/ui/vba/vbaoptions.cxx @@ -0,0 +1,274 @@ +/* -*- 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 "vbaoptions.hxx" +#include <vbahelper/vbahelper.hxx> +#include <ooo/vba/word/WdDefaultFilePath.hpp> +#include <ooo/vba/word/WdLineStyle.hpp> +#include <ooo/vba/word/WdLineWidth.hpp> +#include <ooo/vba/word/WdColorIndex.hpp> +#include <com/sun/star/util/thePathSettings.hpp> +#include <comphelper/processfactory.hxx> +#include <basic/sberrors.hxx> +#include <osl/file.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaOptions::SwVbaOptions( uno::Reference<uno::XComponentContext > const & xContext ) : SwVbaOptions_BASE( uno::Reference< XHelperInterface >(), xContext ) +{ +} + +SwVbaOptions::~SwVbaOptions() +{ +} + +uno::Any SAL_CALL +SwVbaOptions::DefaultFilePath( sal_Int32 _path ) +{ + switch( _path ) + { + case word::WdDefaultFilePath::wdDocumentsPath: + { + msDefaultFilePath = "Work"; + break; + } + case word::WdDefaultFilePath::wdPicturesPath: + { + msDefaultFilePath = "Gallery"; + break; + } + case word::WdDefaultFilePath::wdUserTemplatesPath: + case word::WdDefaultFilePath::wdWorkgroupTemplatesPath: + { + msDefaultFilePath = "Template"; + break; + } + case word::WdDefaultFilePath::wdStartupPath: + { + msDefaultFilePath = "Addin"; + break; + } + case word::WdDefaultFilePath::wdUserOptionsPath: + { + msDefaultFilePath = "UserConfig"; + break; + } + case word::WdDefaultFilePath::wdToolsPath: + case word::WdDefaultFilePath::wdProgramPath: + { + msDefaultFilePath = "Module"; + break; + } + case word::WdDefaultFilePath::wdTempFilePath: + { + msDefaultFilePath = "Temp"; + break; + } + default: + { + DebugHelper::basicexception( ERRCODE_BASIC_NOT_IMPLEMENTED, {} ); + break; + } + } + return uno::Any( uno::Reference< XPropValue > ( new ScVbaPropValue( this ) ) ); +} + +void SwVbaOptions::setValueEvent( const uno::Any& value ) +{ + OUString sNewPath; + value >>= sNewPath; + OUString sNewPathUrl; + ::osl::File::getFileURLFromSystemPath( sNewPath, sNewPathUrl ); + uno::Reference< util::XPathSettings > xPathSettings = util::thePathSettings::get( comphelper::getProcessComponentContext() ); + OUString sOldPathUrl; + xPathSettings->getPropertyValue( msDefaultFilePath ) >>= sOldPathUrl; + // path could be a multipath, Microsoft doesn't support this feature in Word currently + // only the last path is from interest. + sal_Int32 nIndex = sOldPathUrl.lastIndexOf( ';' ); + if( nIndex != -1 ) + { + sNewPathUrl = sOldPathUrl.subView( 0, nIndex + 1 ) + sNewPathUrl; + } + xPathSettings->setPropertyValue( msDefaultFilePath, uno::Any( sNewPathUrl ) ); +} + +uno::Any SwVbaOptions::getValueEvent() +{ + uno::Reference< util::XPathSettings > xPathSettings = util::thePathSettings::get( comphelper::getProcessComponentContext() ); + OUString sPathUrl; + xPathSettings->getPropertyValue( msDefaultFilePath ) >>= sPathUrl; + // path could be a multipath, Microsoft doesn't support this feature in Word currently + // only the last path is from interest. + sal_Int32 nIndex = sPathUrl.lastIndexOf( ';' ); + if( nIndex != -1 ) + { + sPathUrl = sPathUrl.copy( nIndex + 1 ); + } + OUString sPath; + ::osl::File::getSystemPathFromFileURL( sPathUrl, sPath ); + return uno::Any( sPath ); +} + +sal_Int32 SAL_CALL SwVbaOptions::getDefaultBorderLineStyle() +{ + return word::WdLineStyle::wdLineStyleSingle; +} + +void SAL_CALL SwVbaOptions::setDefaultBorderLineStyle( ::sal_Int32 /*_defaultborderlinestyle*/ ) +{ + // not support in Writer +} + +sal_Int32 SAL_CALL SwVbaOptions::getDefaultBorderLineWidth() +{ + return word::WdLineWidth::wdLineWidth050pt; +} + +void SAL_CALL SwVbaOptions::setDefaultBorderLineWidth( ::sal_Int32 /*_defaultborderlinewidth*/ ) +{ + // not support in Writer +} + +sal_Int32 SAL_CALL SwVbaOptions::getDefaultBorderColorIndex() +{ + return word::WdColorIndex::wdAuto; +} + +void SAL_CALL SwVbaOptions::setDefaultBorderColorIndex( ::sal_Int32 /*_defaultbordercolorindex*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL SwVbaOptions::getReplaceSelection() +{ + return true; +} + +void SAL_CALL SwVbaOptions::setReplaceSelection( sal_Bool /*_replaceselection*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL SwVbaOptions::getMapPaperSize() +{ + return false; +} + +void SAL_CALL SwVbaOptions::setMapPaperSize( sal_Bool /*_mappapersize*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL SwVbaOptions::getAutoFormatAsYouTypeApplyHeadings() +{ + return false; +} + +void SAL_CALL SwVbaOptions::setAutoFormatAsYouTypeApplyHeadings( sal_Bool /*_autoformatasyoutypeapplyheadings*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL SwVbaOptions::getAutoFormatAsYouTypeApplyBulletedLists() +{ + return false; +} + +void SAL_CALL SwVbaOptions::setAutoFormatAsYouTypeApplyBulletedLists( sal_Bool /*_autoformatasyoutypeapplybulletedlists*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL SwVbaOptions::getAutoFormatAsYouTypeApplyNumberedLists() +{ + return false; +} + +void SAL_CALL SwVbaOptions::setAutoFormatAsYouTypeApplyNumberedLists( sal_Bool /*_autoformatasyoutypeapplynumberedlists*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL SwVbaOptions::getAutoFormatAsYouTypeFormatListItemBeginning() +{ + return false; +} + +void SAL_CALL SwVbaOptions::setAutoFormatAsYouTypeFormatListItemBeginning( sal_Bool /*_autoformatasyoutypeformatlistitembeginning*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL SwVbaOptions::getAutoFormatAsYouTypeDefineStyles() +{ + return false; +} + +void SAL_CALL SwVbaOptions::setAutoFormatAsYouTypeDefineStyles( sal_Bool /*_autoformatasyoutypedefinestyles*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL SwVbaOptions::getAutoFormatApplyHeadings() +{ + return false; +} + +void SAL_CALL SwVbaOptions::setAutoFormatApplyHeadings( sal_Bool /*_autoformatapplyheadings*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL SwVbaOptions::getAutoFormatApplyLists() +{ + return false; +} + +void SAL_CALL SwVbaOptions::setAutoFormatApplyLists( sal_Bool /*_autoformatapplylists*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL SwVbaOptions::getAutoFormatApplyBulletedLists() +{ + return false; +} + +void SAL_CALL SwVbaOptions::setAutoFormatApplyBulletedLists( sal_Bool /*_autoformatapplybulletedlists*/ ) +{ + // not support in Writer +} + +OUString +SwVbaOptions::getServiceImplName() +{ + return "SwVbaOptions"; +} + +uno::Sequence< OUString > +SwVbaOptions::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Options" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaoptions.hxx b/sw/source/ui/vba/vbaoptions.hxx new file mode 100644 index 0000000000..92994d5589 --- /dev/null +++ b/sw/source/ui/vba/vbaoptions.hxx @@ -0,0 +1,78 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAOPTIONS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAOPTIONS_HXX + +#include <ooo/vba/word/XOptions.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <vbahelper/vbapropvalue.hxx> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XOptions > SwVbaOptions_BASE; + +class SwVbaOptions : public SwVbaOptions_BASE, + public PropListener +{ +private: + OUString msDefaultFilePath; +public: + explicit SwVbaOptions( css::uno::Reference< css::uno::XComponentContext > const & m_xContext ); + virtual ~SwVbaOptions() override; + + // Attributes + virtual ::sal_Int32 SAL_CALL getDefaultBorderLineStyle() override; + virtual void SAL_CALL setDefaultBorderLineStyle( ::sal_Int32 _defaultborderlinestyle ) override; + virtual ::sal_Int32 SAL_CALL getDefaultBorderLineWidth() override; + virtual void SAL_CALL setDefaultBorderLineWidth( ::sal_Int32 _defaultborderlinewidth ) override; + virtual ::sal_Int32 SAL_CALL getDefaultBorderColorIndex() override; + virtual void SAL_CALL setDefaultBorderColorIndex( ::sal_Int32 _defaultbordercolorindex ) override; + virtual sal_Bool SAL_CALL getReplaceSelection() override; + virtual void SAL_CALL setReplaceSelection( sal_Bool _replaceselection ) override; + virtual sal_Bool SAL_CALL getMapPaperSize() override; + virtual void SAL_CALL setMapPaperSize( sal_Bool _mappapersize ) override; + virtual sal_Bool SAL_CALL getAutoFormatAsYouTypeApplyHeadings() override; + virtual void SAL_CALL setAutoFormatAsYouTypeApplyHeadings( sal_Bool _autoformatasyoutypeapplyheadings ) override; + virtual sal_Bool SAL_CALL getAutoFormatAsYouTypeApplyBulletedLists() override; + virtual void SAL_CALL setAutoFormatAsYouTypeApplyBulletedLists( sal_Bool _autoformatasyoutypeapplybulletedlists ) override; + virtual sal_Bool SAL_CALL getAutoFormatAsYouTypeApplyNumberedLists() override; + virtual void SAL_CALL setAutoFormatAsYouTypeApplyNumberedLists( sal_Bool _autoformatasyoutypeapplynumberedlists ) override; + virtual sal_Bool SAL_CALL getAutoFormatAsYouTypeFormatListItemBeginning() override; + virtual void SAL_CALL setAutoFormatAsYouTypeFormatListItemBeginning( sal_Bool _autoformatasyoutypeformatlistitembeginning ) override; + virtual sal_Bool SAL_CALL getAutoFormatAsYouTypeDefineStyles() override; + virtual void SAL_CALL setAutoFormatAsYouTypeDefineStyles( sal_Bool _autoformatasyoutypedefinestyles ) override; + virtual sal_Bool SAL_CALL getAutoFormatApplyHeadings() override; + virtual void SAL_CALL setAutoFormatApplyHeadings( sal_Bool _autoformatapplyheadings ) override; + virtual sal_Bool SAL_CALL getAutoFormatApplyLists() override; + virtual void SAL_CALL setAutoFormatApplyLists( sal_Bool _autoformatapplylists ) override; + virtual sal_Bool SAL_CALL getAutoFormatApplyBulletedLists() override; + virtual void SAL_CALL setAutoFormatApplyBulletedLists( sal_Bool _autoformatapplybulletedlists ) override; + + // Methods + virtual css::uno::Any SAL_CALL DefaultFilePath( sal_Int32 _path ) override; + + //PropListener + virtual void setValueEvent( const css::uno::Any& value ) override; + virtual css::uno::Any getValueEvent() override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAOPTIONS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbapagesetup.cxx b/sw/source/ui/vba/vbapagesetup.cxx new file mode 100644 index 0000000000..b22437dbd2 --- /dev/null +++ b/sw/source/ui/vba/vbapagesetup.cxx @@ -0,0 +1,260 @@ +/* -*- 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 "vbapagesetup.hxx" +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/text/XPageCursor.hpp> +#include <ooo/vba/word/WdSectionStart.hpp> +#include <ooo/vba/word/WdOrientation.hpp> +#include "wordvbahelper.hxx" + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +SwVbaPageSetup::SwVbaPageSetup(const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< beans::XPropertySet >& xProps ): + SwVbaPageSetup_BASE( xParent, xContext ) +{ + mxModel.set( xModel, uno::UNO_SET_THROW ); + mxPageProps.set( xProps, uno::UNO_SET_THROW ); + mnOrientPortrait = word::WdOrientation::wdOrientPortrait; + mnOrientLandscape = word::WdOrientation::wdOrientLandscape; +} + +double SAL_CALL SwVbaPageSetup::getGutter() +{ + // not support in Writer + return 0; +} + +void SAL_CALL SwVbaPageSetup::setGutter( double _gutter ) +{ + // default add gutter into left margin + if( _gutter != 0 ) + { + double margin = VbaPageSetupBase::getLeftMargin() + _gutter; + VbaPageSetupBase::setLeftMargin( margin ); + } +} + +double SAL_CALL SwVbaPageSetup::getHeaderDistance() +{ + bool isHeaderOn = false; + mxPageProps->getPropertyValue("HeaderIsOn") >>= isHeaderOn; + if( !isHeaderOn ) + mxPageProps->setPropertyValue("HeaderIsOn", uno::Any( true ) ); + return VbaPageSetupBase::getHeaderMargin(); +} + + /** + * changes the value of TopMargin to the value of new MS-Word-HeaderDistance. Subtracts the difference + * between old TopMargin and the new headerDistance from the value of HeaderSpacing (which defines the + * space between the header and the body of the text). calculates the new HeaderHeight (= height of the + * header + headerBodyDistance). + * + * @param: headerDistance is the value that is set in MS Word for the distance from the top of the page + * to the header + */ +void SAL_CALL SwVbaPageSetup::setHeaderDistance( double _headerdistance ) +{ + sal_Int32 newHeaderDistance = Millimeter::getInHundredthsOfOneMillimeter( _headerdistance ); + bool isHeaderOn = false; + sal_Int32 currentTopMargin = 0; + sal_Int32 currentSpacing = 0; + sal_Int32 currentHeaderHeight = 0; + + mxPageProps->getPropertyValue("HeaderIsOn") >>= isHeaderOn; + if( !isHeaderOn ) + mxPageProps->setPropertyValue("HeaderIsOn", uno::Any( true ) ); + + mxPageProps->getPropertyValue("TopMargin") >>= currentTopMargin; + mxPageProps->getPropertyValue("HeaderBodyDistance") >>= currentSpacing; + mxPageProps->getPropertyValue("HeaderHeight") >>= currentHeaderHeight; + + sal_Int32 newSpacing = currentSpacing - ( newHeaderDistance - currentTopMargin ); + sal_Int32 height = currentHeaderHeight - currentSpacing; + sal_Int32 newHeaderHeight = newSpacing + height; + + mxPageProps->setPropertyValue("TopMargin", uno::Any( newHeaderDistance ) ); + mxPageProps->setPropertyValue("HeaderBodyDistance", uno::Any( newSpacing ) ); + mxPageProps->setPropertyValue("HeaderHeight", uno::Any( newHeaderHeight ) ); +} + +double SAL_CALL SwVbaPageSetup::getFooterDistance() +{ + bool isFooterOn = false; + mxPageProps->getPropertyValue("FooterIsOn") >>= isFooterOn; + if( !isFooterOn ) + mxPageProps->setPropertyValue("FooterIsOn", uno::Any( true ) ); + return VbaPageSetupBase::getFooterMargin(); +} + +void SAL_CALL SwVbaPageSetup::setFooterDistance( double _footerdistance ) +{ + sal_Int32 newFooterDistance = Millimeter::getInHundredthsOfOneMillimeter( _footerdistance ); + bool isFooterOn = false; + sal_Int32 currentBottomMargin = 0; + sal_Int32 currentSpacing = 0; + sal_Int32 currentFooterHeight = 0; + + mxPageProps->getPropertyValue("FooterIsOn") >>= isFooterOn; + if( !isFooterOn ) + mxPageProps->setPropertyValue("FooterIsOn", uno::Any( true ) ); + + mxPageProps->getPropertyValue("BottomMargin") >>= currentBottomMargin; + mxPageProps->getPropertyValue("FooterBodyDistance") >>= currentSpacing; + mxPageProps->getPropertyValue("FooterHeight") >>= currentFooterHeight; + + sal_Int32 newSpacing = currentSpacing - ( newFooterDistance - currentBottomMargin ); + sal_Int32 height = currentFooterHeight - currentSpacing; + sal_Int32 newFooterHeight = newSpacing + height; + + mxPageProps->setPropertyValue("BottomMargin", uno::Any( newFooterDistance ) ); + mxPageProps->setPropertyValue("FooterBodyDistance", uno::Any( newSpacing ) ); + mxPageProps->setPropertyValue("FooterHeight", uno::Any( newFooterHeight ) ); +} + +sal_Bool SAL_CALL SwVbaPageSetup::getDifferentFirstPageHeaderFooter() +{ + OUString pageStyle = getStyleOfFirstPage(); + if ( pageStyle == "First Page" ) + return true; + + return false; +} + +void SAL_CALL SwVbaPageSetup::setDifferentFirstPageHeaderFooter( sal_Bool status ) +{ + if( status == getDifferentFirstPageHeaderFooter() ) + return; + + OUString newStyle; + if( status ) + newStyle = "First Page"; + else + newStyle = "Standard"; + + uno::Reference< beans::XPropertySet > xStyleProps( word::getCurrentPageStyle( mxModel ), uno::UNO_QUERY_THROW ); + sal_Int32 nTopMargin = 0; + xStyleProps->getPropertyValue("TopMargin") >>= nTopMargin; + sal_Int32 nBottomMargin = 0; + xStyleProps->getPropertyValue("BottomMargin") >>= nBottomMargin; + sal_Int32 nLeftMargin = 0; + xStyleProps->getPropertyValue("LeftMargin") >>= nLeftMargin; + sal_Int32 nRightMargin = 0; + xStyleProps->getPropertyValue("RightMargin") >>= nRightMargin; + sal_Int32 nHeaderHeight = 0; + xStyleProps->getPropertyValue("HeaderHeight") >>= nHeaderHeight; + sal_Int32 nFooterHeight = 0; + xStyleProps->getPropertyValue("FooterHeight") >>= nFooterHeight; + + bool isHeaderOn = false; + xStyleProps->getPropertyValue("HeaderIsOn") >>= isHeaderOn; + if( isHeaderOn ) + { + nTopMargin += nHeaderHeight; + nBottomMargin += nFooterHeight; + xStyleProps->setPropertyValue("HeaderIsOn", uno::Any( false ) ); + xStyleProps->setPropertyValue("FooterIsOn", uno::Any( false ) ); + } + uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( mxModel ), uno::UNO_QUERY_THROW ); + if( xPageCursor->getPage() != 1 ) + { + xPageCursor->jumpToFirstPage(); + } + + uno::Reference< beans::XPropertySet > xCursorProps( xPageCursor, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xTableProps( xCursorProps->getPropertyValue("TextTable"), uno::UNO_QUERY ); + if( xTableProps.is() ) + { + xTableProps->setPropertyValue("PageDescName", uno::Any( newStyle ) ); + } + else + { + xCursorProps->setPropertyValue("PageDescName", uno::Any( newStyle ) ); + } + + uno::Reference< beans::XPropertySet > xFirstPageProps( word::getCurrentPageStyle( mxModel ), uno::UNO_QUERY_THROW ); + xFirstPageProps->setPropertyValue("TopMargin", uno::Any( nTopMargin ) ); + xFirstPageProps->setPropertyValue("BottomMargin", uno::Any( nBottomMargin ) ); + xFirstPageProps->setPropertyValue("LeftMargin", uno::Any( nLeftMargin ) ); + xFirstPageProps->setPropertyValue("RightMargin", uno::Any( nRightMargin ) ); +} + +OUString SwVbaPageSetup::getStyleOfFirstPage() const +{ + OUString styleFirstPage; + uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( mxModel ), uno::UNO_QUERY_THROW ); + if( xPageCursor->getPage() != 1 ) + { + xPageCursor->jumpToFirstPage(); + } + + uno::Reference< beans::XPropertySet > xCursorProps( xPageCursor, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xTableProps( xCursorProps->getPropertyValue("TextTable"), uno::UNO_QUERY ); + if( xTableProps.is() ) + { + xTableProps->getPropertyValue("PageDescName") >>= styleFirstPage; + } + else + { + xCursorProps->getPropertyValue("PageDescName") >>= styleFirstPage; + } + return styleFirstPage; +} + +::sal_Int32 SAL_CALL SwVbaPageSetup::getSectionStart() +{ + // FIXME: + sal_Int32 wdSectionStart = word::WdSectionStart::wdSectionNewPage; + uno::Reference< container::XNamed > xNamed( mxPageProps, uno::UNO_QUERY_THROW ); + OUString sStyleName = xNamed->getName(); + if ( sStyleName == "Left Page" ) + wdSectionStart = word::WdSectionStart::wdSectionEvenPage; + else if ( sStyleName == "Right Page" ) + wdSectionStart = word::WdSectionStart::wdSectionOddPage; + else + wdSectionStart = word::WdSectionStart::wdSectionNewPage; + return wdSectionStart; +} + +void SAL_CALL SwVbaPageSetup::setSectionStart( ::sal_Int32 /*_sectionstart*/ ) +{ + // fail to find corresponding feature in Writer + // #FIXME: +} + +OUString +SwVbaPageSetup::getServiceImplName() +{ + return "SwVbaPageSetup"; +} + +uno::Sequence< OUString > +SwVbaPageSetup::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.PageSetup" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbapagesetup.hxx b/sw/source/ui/vba/vbapagesetup.hxx new file mode 100644 index 0000000000..b6b9c01551 --- /dev/null +++ b/sw/source/ui/vba/vbapagesetup.hxx @@ -0,0 +1,62 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAPAGESETUP_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAPAGESETUP_HXX + +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/word/XPageSetup.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <vbahelper/vbapagesetupbase.hxx> + +typedef cppu::ImplInheritanceHelper< VbaPageSetupBase, ooo::vba::word::XPageSetup > SwVbaPageSetup_BASE; + +class SwVbaPageSetup : public SwVbaPageSetup_BASE +{ +private: + /// @throws css::uno::RuntimeException + OUString getStyleOfFirstPage() const; + +public: + /// @throws css::uno::RuntimeException + SwVbaPageSetup( const css::uno::Reference< ooo::vba::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::beans::XPropertySet >& xProps ); + + // Attributes + virtual double SAL_CALL getGutter() override; + virtual void SAL_CALL setGutter( double _gutter ) override; + virtual double SAL_CALL getHeaderDistance() override; + virtual void SAL_CALL setHeaderDistance( double _headerdistance ) override; + virtual double SAL_CALL getFooterDistance() override; + virtual void SAL_CALL setFooterDistance( double _footerdistance ) override; + virtual sal_Bool SAL_CALL getDifferentFirstPageHeaderFooter() override; + virtual void SAL_CALL setDifferentFirstPageHeaderFooter( sal_Bool status ) override; + virtual ::sal_Int32 SAL_CALL getSectionStart() override; + virtual void SAL_CALL setSectionStart( ::sal_Int32 _sectionstart ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbapalette.cxx b/sw/source/ui/vba/vbapalette.cxx new file mode 100644 index 0000000000..351f2711c5 --- /dev/null +++ b/sw/source/ui/vba/vbapalette.cxx @@ -0,0 +1,93 @@ +/* -*- 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 "vbapalette.hxx" +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <ooo/vba/word/WdColor.hpp> +#include <sal/macros.h> + +using namespace ::ooo::vba; +using namespace ::ooo::vba::word; +using namespace ::com::sun::star; + +const sal_Int32 ColorTable[] = +{ +WdColor::wdColorAutomatic, // 0 +WdColor::wdColorBlack, // 1 +WdColor::wdColorBlue, // 2 +WdColor::wdColorTurquoise, // 3 +WdColor::wdColorBrightGreen, // 4 +WdColor::wdColorPink, // 5 +WdColor::wdColorRed, // 6 +WdColor::wdColorYellow, // 7 +WdColor::wdColorWhite, // 8 +WdColor::wdColorDarkBlue, // 9 +WdColor::wdColorTeal, // 10 +WdColor::wdColorGreen, // 11 +WdColor::wdColorViolet, // 12 +WdColor::wdColorDarkRed, // 13 +WdColor::wdColorDarkYellow, // 14 +WdColor::wdColorGray50, // 15 +WdColor::wdColorGray25, // 16 +}; + +typedef ::cppu::WeakImplHelper< container::XIndexAccess > XIndexAccess_BASE; + +namespace { + +class DefaultPalette : public XIndexAccess_BASE +{ +public: + DefaultPalette(){} + + // Methods XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount() override + { + return SAL_N_ELEMENTS(ColorTable); + } + + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override + { + if ( Index < 0 || Index >= getCount() ) + throw lang::IndexOutOfBoundsException(); + return uno::Any( sal_Int32( ColorTable[ Index ] ) ); + } + + // Methods XElementAccess + virtual uno::Type SAL_CALL getElementType() override + { + return ::cppu::UnoType<sal_Int32>::get(); + } + virtual sal_Bool SAL_CALL hasElements() override + { + return true; + } + +}; + +} + +VbaPalette::VbaPalette() + : mxPalette(new DefaultPalette()) +{ +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbapalette.hxx b/sw/source/ui/vba/vbapalette.hxx new file mode 100644 index 0000000000..cbf639301f --- /dev/null +++ b/sw/source/ui/vba/vbapalette.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 . + */ + +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAPALETTE_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAPALETTE_HXX + +#include <com/sun/star/container/XIndexAccess.hpp> + +class VbaPalette +{ + css::uno::Reference< css::container::XIndexAccess > mxPalette; +public: + VbaPalette(); + // if no palette available e.g. because the document doesn't have a + // palette defined then a default palette will be returned. + const css::uno::Reference< css::container::XIndexAccess >& getPalette() const { return mxPalette;} +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbapane.cxx b/sw/source/ui/vba/vbapane.cxx new file mode 100644 index 0000000000..64a7c411c7 --- /dev/null +++ b/sw/source/ui/vba/vbapane.cxx @@ -0,0 +1,65 @@ +/* -*- 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 "vbapane.hxx" +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include "vbaview.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaPane::SwVbaPane( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, + uno::Reference< frame::XModel > xModel ) : + SwVbaPane_BASE( rParent, rContext ), mxModel(std::move( xModel )) +{ +} + +SwVbaPane::~SwVbaPane() +{ +} + +uno::Any SAL_CALL +SwVbaPane::View() +{ + return uno::Any( uno::Reference< word::XView >( new SwVbaView( this, mxContext, mxModel ) ) ); +} + +void SAL_CALL +SwVbaPane::Close( ) +{ + dispatchRequests( mxModel,".uno:CloseWin" ); +} + +OUString +SwVbaPane::getServiceImplName() +{ + return "SwVbaPane"; +} + +uno::Sequence< OUString > +SwVbaPane::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Pane" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbapane.hxx b/sw/source/ui/vba/vbapane.hxx new file mode 100644 index 0000000000..e0a81b9e0f --- /dev/null +++ b/sw/source/ui/vba/vbapane.hxx @@ -0,0 +1,49 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAPANE_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAPANE_HXX + +#include <ooo/vba/word/XPane.hpp> +#include <vbahelper/vbahelperinterface.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XPane> SwVbaPane_BASE; + +class SwVbaPane : public SwVbaPane_BASE +{ +private: + css::uno::Reference<css::frame::XModel> mxModel; + +public: + /// @throws css::uno::RuntimeException + SwVbaPane(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, + css::uno::Reference<css::frame::XModel> xModel); + virtual ~SwVbaPane() override; + + // Methods + virtual css::uno::Any SAL_CALL View() override; + virtual void SAL_CALL Close() override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAPANE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbapanes.cxx b/sw/source/ui/vba/vbapanes.cxx new file mode 100644 index 0000000000..05b288e290 --- /dev/null +++ b/sw/source/ui/vba/vbapanes.cxx @@ -0,0 +1,119 @@ +/* -*- 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 "vbapanes.hxx" +#include "vbapane.hxx" +#include <cppuhelper/implbase.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +// I assume there is only one pane in Writer +class PanesIndexAccess : public ::cppu::WeakImplHelper<container::XIndexAccess > +{ +private: + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< frame::XModel > mxModel; + +public: + PanesIndexAccess( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxModel(std::move( xModel )) {} + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount( ) override + { + return 1; + } + virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override + { + if( Index != 0 ) + throw lang::IndexOutOfBoundsException(); + return uno::Any( uno::Reference< word::XPane >( new SwVbaPane( mxParent, mxContext, mxModel ) ) ); + } + virtual uno::Type SAL_CALL getElementType( ) override + { + return cppu::UnoType<word::XPane>::get(); + } + virtual sal_Bool SAL_CALL hasElements( ) override + { + return true; + } +}; + +class PanesEnumWrapper : public EnumerationHelper_BASE +{ + uno::Reference<container::XIndexAccess > m_xIndexAccess; + sal_Int32 m_nIndex; +public: + explicit PanesEnumWrapper( uno::Reference< container::XIndexAccess > xIndexAccess ) : m_xIndexAccess(std::move( xIndexAccess )), m_nIndex( 0 ) {} + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( m_nIndex < m_xIndexAccess->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( m_nIndex < m_xIndexAccess->getCount() ) + return m_xIndexAccess->getByIndex( m_nIndex++ ); + throw container::NoSuchElementException(); + } +}; + +} + +SwVbaPanes::SwVbaPanes( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel ): SwVbaPanes_BASE( xParent, xContext, new PanesIndexAccess( xParent, xContext, xModel ) ) +{ +} +// XEnumerationAccess +uno::Type +SwVbaPanes::getElementType() +{ + return cppu::UnoType<word::XPane>::get(); +} +uno::Reference< container::XEnumeration > +SwVbaPanes::createEnumeration() +{ + return new PanesEnumWrapper( m_xIndexAccess ); +} + +uno::Any +SwVbaPanes::createCollectionObject( const css::uno::Any& aSource ) +{ + return aSource; +} + +OUString +SwVbaPanes::getServiceImplName() +{ + return "SwVbaPanes"; +} + +css::uno::Sequence<OUString> +SwVbaPanes::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.Panes" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbapanes.hxx b/sw/source/ui/vba/vbapanes.hxx new file mode 100644 index 0000000000..27a6d65671 --- /dev/null +++ b/sw/source/ui/vba/vbapanes.hxx @@ -0,0 +1,41 @@ +/* -*- 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 <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XPanes.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XPanes > SwVbaPanes_BASE; + +class SwVbaPanes : public SwVbaPanes_BASE +{ +public: + SwVbaPanes( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel ); + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaPanes_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaparagraph.cxx b/sw/source/ui/vba/vbaparagraph.cxx new file mode 100644 index 0000000000..19a3127959 --- /dev/null +++ b/sw/source/ui/vba/vbaparagraph.cxx @@ -0,0 +1,179 @@ +/* -*- 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 "vbaparagraph.hxx" +#include "vbarange.hxx" +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaParagraph::SwVbaParagraph( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xDocument, uno::Reference< text::XTextRange > xTextRange ) : + SwVbaParagraph_BASE( rParent, rContext ), mxTextDocument(std::move( xDocument )), mxTextRange(std::move( xTextRange )) +{ +} + +SwVbaParagraph::~SwVbaParagraph() +{ +} + +uno::Reference< word::XRange > SAL_CALL +SwVbaParagraph::getRange( ) +{ + return uno::Reference< word::XRange >( new SwVbaRange( this, mxContext, mxTextDocument, mxTextRange->getStart(), mxTextRange->getEnd(), mxTextRange->getText() ) ); +} + +uno::Any SAL_CALL +SwVbaParagraph::getStyle( ) +{ + uno::Reference< word::XRange > xRange = getRange(); + return xRange->getStyle(); +} + +void SAL_CALL +SwVbaParagraph::setStyle( const uno::Any& style ) +{ + uno::Reference< word::XRange > xRange = getRange(); + xRange->setStyle( style ); +} + +OUString +SwVbaParagraph::getServiceImplName() +{ + return "SwVbaParagraph"; +} + +uno::Sequence< OUString > +SwVbaParagraph::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Paragraph" + }; + return aServiceNames; +} + +namespace { + +class ParagraphCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess, + container::XEnumerationAccess > +{ +private: + uno::Reference< text::XTextDocument > mxTextDocument; + + /// @throws uno::RuntimeException + uno::Reference< container::XEnumeration > getEnumeration() + { + uno::Reference< container::XEnumerationAccess > xParEnumAccess( mxTextDocument->getText(), uno::UNO_QUERY_THROW ); + return xParEnumAccess->createEnumeration(); + } + +public: + /// @throws uno::RuntimeException + explicit ParagraphCollectionHelper( uno::Reference< text::XTextDocument > xDocument ): mxTextDocument(std::move( xDocument )) + { + } + // XElementAccess + virtual uno::Type SAL_CALL getElementType( ) override { return cppu::UnoType<text::XTextRange>::get(); } + virtual sal_Bool SAL_CALL hasElements( ) override { return true; } + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override + { + sal_Int32 nCount = 0; + uno::Reference< container::XEnumeration > xParEnum = getEnumeration(); + while( xParEnum->hasMoreElements() ) + { + uno::Reference< lang::XServiceInfo > xServiceInfo( xParEnum->nextElement(), uno::UNO_QUERY_THROW ); + if( xServiceInfo->supportsService("com.sun.star.text.Paragraph") ) + { + nCount++; + } + } + return nCount; + } + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override + { + if( Index < getCount() ) + { + sal_Int32 nCount = 0; + uno::Reference< container::XEnumeration > xParEnum = getEnumeration(); + while( xParEnum->hasMoreElements() ) + { + uno::Reference< lang::XServiceInfo > xServiceInfo( xParEnum->nextElement(), uno::UNO_QUERY_THROW ); + if( xServiceInfo->supportsService("com.sun.star.text.Paragraph") ) + { + if( Index == nCount ) + return uno::Any( xServiceInfo ); + nCount++; + } + } + } + throw lang::IndexOutOfBoundsException(); + } + // XEnumerationAccess + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override + { + return getEnumeration(); + } +}; + +} + +SwVbaParagraphs::SwVbaParagraphs( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< text::XTextDocument >& xDocument ) : SwVbaParagraphs_BASE( xParent, xContext, new ParagraphCollectionHelper( xDocument ) ), mxTextDocument( xDocument ) +{ +} + +// XEnumerationAccess +uno::Type +SwVbaParagraphs::getElementType() +{ + return cppu::UnoType<word::XParagraph>::get(); +} +uno::Reference< container::XEnumeration > +SwVbaParagraphs::createEnumeration() +{ + uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); + return xEnumerationAccess->createEnumeration(); +} + +uno::Any +SwVbaParagraphs::createCollectionObject( const css::uno::Any& aSource ) +{ + uno::Reference< text::XTextRange > xTextRange( aSource, uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< word::XParagraph >( new SwVbaParagraph( this, mxContext, mxTextDocument, xTextRange ) ) ); +} + +OUString +SwVbaParagraphs::getServiceImplName() +{ + return "SwVbaParagraphs"; +} + +css::uno::Sequence<OUString> +SwVbaParagraphs::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.Paragraphs" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaparagraph.hxx b/sw/source/ui/vba/vbaparagraph.hxx new file mode 100644 index 0000000000..6c35455614 --- /dev/null +++ b/sw/source/ui/vba/vbaparagraph.hxx @@ -0,0 +1,74 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAPARAGRAPH_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAPARAGRAPH_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XParagraphs.hpp> +#include <ooo/vba/word/XParagraph.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/text/XTextDocument.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XParagraph > SwVbaParagraph_BASE; + +class SwVbaParagraph : public SwVbaParagraph_BASE +{ +private: + css::uno::Reference< css::text::XTextDocument > mxTextDocument; + css::uno::Reference< css::text::XTextRange > mxTextRange; + +public: + /// @throws css::uno::RuntimeException + SwVbaParagraph( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xDocument, css::uno::Reference< css::text::XTextRange > xTextRange ); + virtual ~SwVbaParagraph() override; + + // XParagraph + virtual css::uno::Reference< ooo::vba::word::XRange > SAL_CALL getRange() override; + virtual css::uno::Any SAL_CALL getStyle() override; + virtual void SAL_CALL setStyle( const css::uno::Any& style ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +typedef CollTestImplHelper< ooo::vba::word::XParagraphs > SwVbaParagraphs_BASE; + +class SwVbaParagraphs : public SwVbaParagraphs_BASE +{ +private: + css::uno::Reference< css::text::XTextDocument > mxTextDocument; +public: + /// @throws css::uno::RuntimeException + SwVbaParagraphs( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::text::XTextDocument >& xDocument ); + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaParagraphs_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAPARAGRAPH_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaparagraphformat.cxx b/sw/source/ui/vba/vbaparagraphformat.cxx new file mode 100644 index 0000000000..4e5a61fdeb --- /dev/null +++ b/sw/source/ui/vba/vbaparagraphformat.cxx @@ -0,0 +1,567 @@ +/* -*- 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 "vbaparagraphformat.hxx" +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include <basic/sberrors.hxx> +#include <com/sun/star/style/LineSpacingMode.hpp> +#include <ooo/vba/word/WdLineSpacing.hpp> +#include <ooo/vba/word/WdParagraphAlignment.hpp> +#include <ooo/vba/word/WdOutlineLevel.hpp> +#include <com/sun/star/style/ParagraphAdjust.hpp> +#include <com/sun/star/style/BreakType.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include "vbatabstops.hxx" +#include <o3tl/string_view.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +const sal_Int16 CHARACTER_INDENT_FACTOR = 12; +const sal_Int16 PERCENT100 = 100; +const sal_Int16 PERCENT150 = 150; +const sal_Int16 PERCENT200 = 200; + +SwVbaParagraphFormat::SwVbaParagraphFormat( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< beans::XPropertySet > xParaProps ) : SwVbaParagraphFormat_BASE( rParent, rContext ), mxParaProps(std::move( xParaProps )) +{ +} + +SwVbaParagraphFormat::~SwVbaParagraphFormat() +{ +} + +sal_Int32 SAL_CALL SwVbaParagraphFormat::getAlignment() +{ + style::ParagraphAdjust aParaAdjust = style::ParagraphAdjust_LEFT; + mxParaProps->getPropertyValue("ParaAdjust") >>= aParaAdjust; + return getMSWordAlignment( aParaAdjust ); +} + +void SAL_CALL SwVbaParagraphFormat::setAlignment( sal_Int32 _alignment ) +{ + style::ParagraphAdjust aParaAdjust = getOOoAlignment( _alignment ); + mxParaProps->setPropertyValue("ParaAdjust", uno::Any( aParaAdjust ) ); +} + +float SAL_CALL SwVbaParagraphFormat::getFirstLineIndent() +{ + sal_Int32 indent = 0; + mxParaProps->getPropertyValue("ParaFirstLineIndent") >>= indent; + return static_cast<float>( Millimeter::getInPoints( indent ) ); +} + +void SAL_CALL SwVbaParagraphFormat::setFirstLineIndent( float _firstlineindent ) +{ + sal_Int32 indent = Millimeter::getInHundredthsOfOneMillimeter( _firstlineindent ); + mxParaProps->setPropertyValue("ParaFirstLineIndent", uno::Any( indent ) ); +} + +uno::Any SAL_CALL SwVbaParagraphFormat::getKeepTogether() +{ + bool bKeep = false; + mxParaProps->getPropertyValue("ParaKeepTogether") >>= bKeep; + return uno::Any ( bKeep ); +} + +void SAL_CALL SwVbaParagraphFormat::setKeepTogether( const uno::Any& _keeptogether ) +{ + bool bKeep = false; + if( _keeptogether >>= bKeep ) + { + mxParaProps->setPropertyValue("ParaKeepTogether", uno::Any( bKeep ) ); + } + else + { + DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER ); + } +} + +uno::Any SAL_CALL SwVbaParagraphFormat::getKeepWithNext() +{ + bool bKeep = false; + mxParaProps->getPropertyValue("ParaSplit") >>= bKeep; + return uno::Any ( bKeep ); +} + +void SAL_CALL SwVbaParagraphFormat::setKeepWithNext( const uno::Any& _keepwithnext ) +{ + bool bKeep = false; + if( _keepwithnext >>= bKeep ) + { + mxParaProps->setPropertyValue("ParaSplit", uno::Any( bKeep ) ); + } + else + { + DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER ); + } +} + +uno::Any SAL_CALL SwVbaParagraphFormat::getHyphenation() +{ + bool bHypn = false; + mxParaProps->getPropertyValue("ParaIsHyphenation") >>= bHypn; + return uno::Any ( bHypn ); +} + +void SAL_CALL SwVbaParagraphFormat::setHyphenation( const uno::Any& _hyphenation ) +{ + bool bHypn = false; + if( _hyphenation >>= bHypn ) + { + mxParaProps->setPropertyValue("ParaIsHyphenation", uno::Any( bHypn ) ); + } + else + { + DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER ); + } +} + +float SAL_CALL SwVbaParagraphFormat::getLineSpacing() +{ + style::LineSpacing aLineSpacing; + mxParaProps->getPropertyValue("ParaLineSpacing") >>= aLineSpacing; + return getMSWordLineSpacing( aLineSpacing ); +} + +void SAL_CALL SwVbaParagraphFormat::setLineSpacing( float _linespacing ) +{ + style::LineSpacing aLineSpacing; + mxParaProps->getPropertyValue("ParaLineSpacing") >>= aLineSpacing; + aLineSpacing = getOOoLineSpacing( _linespacing, aLineSpacing.Mode ); + mxParaProps->setPropertyValue("ParaLineSpacing", uno::Any( aLineSpacing ) ); +} + +sal_Int32 SAL_CALL SwVbaParagraphFormat::getLineSpacingRule() +{ + style::LineSpacing aLineSpacing; + mxParaProps->getPropertyValue("ParaLineSpacing") >>= aLineSpacing; + return getMSWordLineSpacingRule( aLineSpacing ); +} + +void SAL_CALL SwVbaParagraphFormat::setLineSpacingRule( sal_Int32 _linespacingrule ) +{ + style::LineSpacing aLineSpacing = getOOoLineSpacingFromRule( _linespacingrule ); + mxParaProps->setPropertyValue("ParaLineSpacing", uno::Any( aLineSpacing ) ); +} + +uno::Any SAL_CALL SwVbaParagraphFormat::getNoLineNumber() +{ + bool noLineNum = false; + mxParaProps->getPropertyValue("ParaLineNumberCount") >>= noLineNum; + return uno::Any ( noLineNum ); +} + +void SAL_CALL SwVbaParagraphFormat::setNoLineNumber( const uno::Any& _nolinenumber ) +{ + bool noLineNum = false; + if( _nolinenumber >>= noLineNum ) + { + mxParaProps->setPropertyValue("ParaLineNumberCount", uno::Any( noLineNum ) ); + } + else + { + DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER ); + } +} + +sal_Int32 SAL_CALL SwVbaParagraphFormat::getOutlineLevel() +{ + sal_Int32 nLevel = word::WdOutlineLevel::wdOutlineLevelBodyText; + OUString aHeading; + static constexpr OUString HEADING = u"Heading"_ustr; + mxParaProps->getPropertyValue("ParaStyleName") >>= aHeading; + if( aHeading.startsWith( HEADING ) ) + { + // get the sub string after "Heading" + nLevel = o3tl::toInt32(aHeading.subView( HEADING.getLength() )); + } + return nLevel; +} + +void SAL_CALL SwVbaParagraphFormat::setOutlineLevel( sal_Int32 _outlinelevel ) +{ + if( _outlinelevel != getOutlineLevel() ) + { + // TODO: in my test in msword, there is no effect for this function. + } +} + +uno::Any SAL_CALL SwVbaParagraphFormat::getPageBreakBefore() +{ + style::BreakType aBreakType; + mxParaProps->getPropertyValue("BreakType") >>= aBreakType; + bool bBreakBefore = ( aBreakType == style::BreakType_PAGE_BEFORE || aBreakType == style::BreakType_PAGE_BOTH ); + return uno::Any( bBreakBefore ); +} + +void SAL_CALL SwVbaParagraphFormat::setPageBreakBefore( const uno::Any& _breakbefore ) +{ + bool bBreakBefore = false; + if( _breakbefore >>= bBreakBefore ) + { + style::BreakType aBreakType; + mxParaProps->getPropertyValue("BreakType") >>= aBreakType; + if( bBreakBefore ) + { + if( aBreakType == style::BreakType_NONE ) + aBreakType = style::BreakType_PAGE_BEFORE; + else if ( aBreakType == style::BreakType_PAGE_AFTER ) + aBreakType = style::BreakType_PAGE_BOTH; + } + else + { + if( aBreakType == style::BreakType_PAGE_BOTH ) + aBreakType = style::BreakType_PAGE_AFTER; + else if ( aBreakType == style::BreakType_PAGE_BEFORE ) + aBreakType = style::BreakType_PAGE_AFTER; + } + mxParaProps->setPropertyValue("BreakType", uno::Any( aBreakType ) ); + } + else + { + DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER ); + } +} + +float SAL_CALL SwVbaParagraphFormat::getSpaceBefore() +{ + sal_Int32 nSpace = 0; + mxParaProps->getPropertyValue("ParaTopMargin") >>= nSpace; + return static_cast<float>( Millimeter::getInPoints( nSpace ) ); +} + +void SAL_CALL SwVbaParagraphFormat::setSpaceBefore( float _space ) +{ + sal_Int32 nSpace = Millimeter::getInHundredthsOfOneMillimeter( _space ); + mxParaProps->setPropertyValue("ParaTopMargin", uno::Any( nSpace ) ); +} + +float SAL_CALL SwVbaParagraphFormat::getSpaceAfter() +{ + sal_Int32 nSpace = 0; + mxParaProps->getPropertyValue("ParaBottomMargin") >>= nSpace; + return static_cast<float>( Millimeter::getInPoints( nSpace ) ); +} + +void SAL_CALL SwVbaParagraphFormat::setSpaceAfter( float _space ) +{ + sal_Int32 nSpace = Millimeter::getInHundredthsOfOneMillimeter( _space ); + mxParaProps->setPropertyValue("ParaBottomMargin", uno::Any( nSpace ) ); +} + +float SAL_CALL SwVbaParagraphFormat::getLeftIndent() +{ + sal_Int32 nIndent = 0; + mxParaProps->getPropertyValue("ParaLeftMargin") >>= nIndent; + return static_cast<float>( Millimeter::getInPoints( nIndent ) ); +} + +void SAL_CALL SwVbaParagraphFormat::setLeftIndent( float _leftindent ) +{ + sal_Int32 nIndent = Millimeter::getInHundredthsOfOneMillimeter( _leftindent ); + mxParaProps->setPropertyValue("ParaLeftMargin", uno::Any( nIndent ) ); +} + +float SAL_CALL SwVbaParagraphFormat::getRightIndent() +{ + sal_Int32 nIndent = 0; + mxParaProps->getPropertyValue("ParaRightMargin") >>= nIndent; + return static_cast<float>( Millimeter::getInPoints( nIndent ) ); +} + +void SAL_CALL SwVbaParagraphFormat::setRightIndent( float _rightindent ) +{ + sal_Int32 nIndent = Millimeter::getInHundredthsOfOneMillimeter( _rightindent ); + mxParaProps->setPropertyValue("ParaRightMargin", uno::Any( nIndent ) ); +} + +uno::Any SAL_CALL SwVbaParagraphFormat::getTabStops() +{ + return uno::Any( uno::Reference< word::XTabStops >( new SwVbaTabStops( this, mxContext, mxParaProps ) ) ); +} + +void SAL_CALL SwVbaParagraphFormat::setTabStops( const uno::Any& /*_tabstops*/ ) +{ + throw uno::RuntimeException("Not implemented" ); +} + +uno::Any SAL_CALL SwVbaParagraphFormat::getWidowControl() +{ + sal_Int8 nWidow = 0; + mxParaProps->getPropertyValue("ParaWidows") >>= nWidow; + sal_Int8 nOrphan = 0; + mxParaProps->getPropertyValue("ParaOrphans") >>= nOrphan; + // if the amount of single lines on one page > 1 and the same of start and end of the paragraph, + // true is returned. + bool bWidow = ( nWidow > 1 && nOrphan == nWidow ); + return uno::Any( bWidow ); +} + +void SAL_CALL SwVbaParagraphFormat::setWidowControl( const uno::Any& _widowcontrol ) +{ + // if we get true, the part of the paragraph on one page has to be + // at least two lines + bool bWidow = false; + if( _widowcontrol >>= bWidow ) + { + sal_Int8 nControl = bWidow? 2:1; + mxParaProps->setPropertyValue("ParaWidows", uno::Any( nControl ) ); + mxParaProps->setPropertyValue("ParaOrphans", uno::Any( nControl ) ); + } + else + { + DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER ); + } +} + +style::LineSpacing SwVbaParagraphFormat::getOOoLineSpacing( float _lineSpace, sal_Int16 mode ) +{ + style::LineSpacing aLineSpacing; + if( mode != style::LineSpacingMode::MINIMUM && mode != style::LineSpacingMode::FIX ) + { + // special behaviour of word: if the space is set to these values, the rule and + // the height are changed accordingly + if( _lineSpace == CHARACTER_INDENT_FACTOR ) + { + aLineSpacing.Mode = style::LineSpacingMode::PROP; + aLineSpacing.Height = PERCENT100; + } + else if( _lineSpace == CHARACTER_INDENT_FACTOR * 1.5 ) // no rounding issues, == 18 + { + aLineSpacing.Mode = style::LineSpacingMode::PROP; + aLineSpacing.Height = PERCENT150; + } + else if( _lineSpace == CHARACTER_INDENT_FACTOR * 2 ) + { + aLineSpacing.Mode = style::LineSpacingMode::PROP; + aLineSpacing.Height = PERCENT200; + } + else + { + aLineSpacing.Mode = style::LineSpacingMode::FIX; + aLineSpacing.Height = static_cast<sal_Int16>( Millimeter::getInHundredthsOfOneMillimeter( _lineSpace ) ); + } + } + else + { + aLineSpacing.Mode = mode; + aLineSpacing.Height = static_cast<sal_Int16>( Millimeter::getInHundredthsOfOneMillimeter( _lineSpace ) ); + } + return aLineSpacing; +} + +style::LineSpacing SwVbaParagraphFormat::getOOoLineSpacingFromRule( sal_Int32 _linespacingrule ) +{ + style::LineSpacing aLineSpacing; + switch( _linespacingrule ) + { + case word::WdLineSpacing::wdLineSpace1pt5: + { + aLineSpacing.Mode = style::LineSpacingMode::PROP; + aLineSpacing.Height = PERCENT150; + break; + } + case word::WdLineSpacing::wdLineSpaceAtLeast: + { + aLineSpacing.Mode = style::LineSpacingMode::MINIMUM; + aLineSpacing.Height = getCharHeight(); + break; + } + case word::WdLineSpacing::wdLineSpaceDouble: + { + aLineSpacing.Mode = style::LineSpacingMode::PROP; + aLineSpacing.Height = getCharHeight(); + break; + } + case word::WdLineSpacing::wdLineSpaceExactly: + case word::WdLineSpacing::wdLineSpaceMultiple: + { + aLineSpacing.Mode = style::LineSpacingMode::FIX; + aLineSpacing.Height = getCharHeight(); + break; + } + case word::WdLineSpacing::wdLineSpaceSingle: + { + aLineSpacing.Mode = style::LineSpacingMode::PROP; + aLineSpacing.Height = PERCENT100; + break; + } + default: + { + DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER ); + break; + } + } + return aLineSpacing; +} + +float SwVbaParagraphFormat::getMSWordLineSpacing( style::LineSpacing const & rLineSpacing ) +{ + float wdLineSpacing = 0; + if( rLineSpacing.Mode != style::LineSpacingMode::PROP ) + { + wdLineSpacing = static_cast<float>( Millimeter::getInPoints( rLineSpacing.Height ) ); + } + else + { + wdLineSpacing = static_cast<float>( CHARACTER_INDENT_FACTOR * rLineSpacing.Height ) / PERCENT100; + } + return wdLineSpacing; +} + +sal_Int32 SwVbaParagraphFormat::getMSWordLineSpacingRule( style::LineSpacing const & rLineSpacing ) +{ + sal_Int32 wdLineSpacing = word::WdLineSpacing::wdLineSpaceSingle; + switch( rLineSpacing.Mode ) + { + case style::LineSpacingMode::PROP: + { + switch( rLineSpacing.Height ) + { + case PERCENT100: + { + wdLineSpacing = word::WdLineSpacing::wdLineSpaceSingle; + break; + } + case PERCENT150: + { + wdLineSpacing = word::WdLineSpacing::wdLineSpace1pt5; + break; + } + case PERCENT200: + { + wdLineSpacing = word::WdLineSpacing::wdLineSpaceDouble; + break; + } + default: + { + wdLineSpacing = word::WdLineSpacing::wdLineSpaceMultiple; + } + } + break; + } + case style::LineSpacingMode::MINIMUM: + { + wdLineSpacing = word::WdLineSpacing::wdLineSpaceAtLeast; + break; + } + case style::LineSpacingMode::FIX: + case style::LineSpacingMode::LEADING: + { + wdLineSpacing = word::WdLineSpacing::wdLineSpaceExactly; + break; + } + default: + { + DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER ); + } + } + return wdLineSpacing; +} + +sal_Int16 SwVbaParagraphFormat::getCharHeight() +{ + float fCharHeight = 0.0; + mxParaProps->getPropertyValue("CharHeight") >>= fCharHeight; + return static_cast<sal_Int16>( Millimeter::getInHundredthsOfOneMillimeter( fCharHeight ) ); +} + +style::ParagraphAdjust SwVbaParagraphFormat::getOOoAlignment( sal_Int32 _alignment ) +{ + style::ParagraphAdjust nParaAjust = style::ParagraphAdjust_LEFT; + switch( _alignment ) + { + case word::WdParagraphAlignment::wdAlignParagraphCenter: + { + nParaAjust = style::ParagraphAdjust_CENTER; + break; + } + case word::WdParagraphAlignment::wdAlignParagraphJustify: + { + nParaAjust = style::ParagraphAdjust_BLOCK; + break; + } + case word::WdParagraphAlignment::wdAlignParagraphLeft: + { + nParaAjust = style::ParagraphAdjust_LEFT; + break; + } + case word::WdParagraphAlignment::wdAlignParagraphRight: + { + nParaAjust = style::ParagraphAdjust_RIGHT; + break; + } + default: + { + DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER ); + } + } + return nParaAjust; +} + +sal_Int32 SwVbaParagraphFormat::getMSWordAlignment( style::ParagraphAdjust _alignment ) +{ + sal_Int32 wdAlignment = word::WdParagraphAlignment::wdAlignParagraphLeft; + switch( _alignment ) + { + case style::ParagraphAdjust_CENTER: + { + wdAlignment = word::WdParagraphAlignment::wdAlignParagraphCenter; + break; + } + case style::ParagraphAdjust_LEFT: + { + wdAlignment = word::WdParagraphAlignment::wdAlignParagraphLeft; + break; + } + case style::ParagraphAdjust_BLOCK: + { + wdAlignment = word::WdParagraphAlignment::wdAlignParagraphJustify; + break; + } + case style::ParagraphAdjust_RIGHT: + { + wdAlignment = word::WdParagraphAlignment::wdAlignParagraphRight; + break; + } + default: + { + DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETER, {} ); + } + } + return wdAlignment; +} + +OUString +SwVbaParagraphFormat::getServiceImplName() +{ + return "SwVbaParagraphFormat"; +} + +uno::Sequence< OUString > +SwVbaParagraphFormat::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.ParagraphFormat" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaparagraphformat.hxx b/sw/source/ui/vba/vbaparagraphformat.hxx new file mode 100644 index 0000000000..a80c21e1b1 --- /dev/null +++ b/sw/source/ui/vba/vbaparagraphformat.hxx @@ -0,0 +1,88 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAPARAGRAPHFORMAT_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAPARAGRAPHFORMAT_HXX + +#include <ooo/vba/word/XParagraphFormat.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/style/LineSpacing.hpp> +#include <com/sun/star/style/ParagraphAdjust.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XParagraphFormat > SwVbaParagraphFormat_BASE; + +class SwVbaParagraphFormat : public SwVbaParagraphFormat_BASE +{ +private: + css::uno::Reference< css::beans::XPropertySet > mxParaProps; + +private: + static css::style::LineSpacing getOOoLineSpacing( float _lineSpace, sal_Int16 mode ); + css::style::LineSpacing getOOoLineSpacingFromRule( sal_Int32 _linespacingrule ); + static float getMSWordLineSpacing( css::style::LineSpacing const & rLineSpacing ); + static sal_Int32 getMSWordLineSpacingRule( css::style::LineSpacing const & rLineSpacing ); + /// @throws css::uno::RuntimeException + sal_Int16 getCharHeight(); + static css::style::ParagraphAdjust getOOoAlignment( sal_Int32 _alignment ); + static sal_Int32 getMSWordAlignment( css::style::ParagraphAdjust _alignment ); + +public: + SwVbaParagraphFormat( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::beans::XPropertySet > xParaProps ); + virtual ~SwVbaParagraphFormat() override; + + // Attributes + virtual ::sal_Int32 SAL_CALL getAlignment() override; + virtual void SAL_CALL setAlignment( ::sal_Int32 _alignment ) override; + virtual float SAL_CALL getFirstLineIndent() override; + virtual void SAL_CALL setFirstLineIndent( float _firstlineindent ) override; + virtual css::uno::Any SAL_CALL getKeepTogether() override; + virtual void SAL_CALL setKeepTogether( const css::uno::Any& _keeptogether ) override; + virtual css::uno::Any SAL_CALL getKeepWithNext() override; + virtual void SAL_CALL setKeepWithNext( const css::uno::Any& _keepwithnext ) override; + virtual css::uno::Any SAL_CALL getHyphenation() override; + virtual void SAL_CALL setHyphenation( const css::uno::Any& _hyphenation ) override; + virtual float SAL_CALL getLineSpacing() override; + virtual void SAL_CALL setLineSpacing( float _linespacing ) override; + virtual ::sal_Int32 SAL_CALL getLineSpacingRule() override; + virtual void SAL_CALL setLineSpacingRule( ::sal_Int32 _linespacingrule ) override; + virtual css::uno::Any SAL_CALL getNoLineNumber() override; + virtual void SAL_CALL setNoLineNumber( const css::uno::Any& _nolinenumber ) override; + virtual ::sal_Int32 SAL_CALL getOutlineLevel() override; + virtual void SAL_CALL setOutlineLevel( ::sal_Int32 _outlinelevel ) override; + virtual css::uno::Any SAL_CALL getPageBreakBefore() override; + virtual void SAL_CALL setPageBreakBefore( const css::uno::Any& _pagebreakbefore ) override; + virtual float SAL_CALL getSpaceBefore() override; + virtual void SAL_CALL setSpaceBefore( float _spacebefore ) override; + virtual float SAL_CALL getSpaceAfter() override; + virtual void SAL_CALL setSpaceAfter( float _spaceafter ) override; + virtual float SAL_CALL getLeftIndent() override; + virtual void SAL_CALL setLeftIndent( float _leftindent ) override; + virtual float SAL_CALL getRightIndent() override; + virtual void SAL_CALL setRightIndent( float _rightindent ) override; + virtual css::uno::Any SAL_CALL getTabStops() override; + virtual void SAL_CALL setTabStops( const css::uno::Any& _tabstops ) override; + virtual css::uno::Any SAL_CALL getWidowControl() override; + virtual void SAL_CALL setWidowControl( const css::uno::Any& _widowcontrol ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAPARAGRAPHFORMAT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbarange.cxx b/sw/source/ui/vba/vbarange.cxx new file mode 100644 index 0000000000..c48dd6193c --- /dev/null +++ b/sw/source/ui/vba/vbarange.cxx @@ -0,0 +1,434 @@ +/* -*- 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 "vbarange.hxx" +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include <basic/sberrors.hxx> +#include "vbarangehelper.hxx" +#include <ooo/vba/word/WdBreakType.hpp> +#include <com/sun/star/style/BreakType.hpp> +#include <com/sun/star/text/ControlCharacter.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/text/XTextRangeCompare.hpp> +#include <com/sun/star/text/XTextViewCursor.hpp> +#include "vbaparagraphformat.hxx" +#include "vbastyle.hxx" +#include "vbafont.hxx" +#include "vbafind.hxx" +#include "vbapalette.hxx" +#include "vbapagesetup.hxx" +#include "vbalistformat.hxx" +#include "vbarevisions.hxx" +#include "vbabookmarks.hxx" +#include "vbasections.hxx" +#include "vbafield.hxx" +#include "wordvbahelper.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaRange::SwVbaRange( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xTextDocument, const uno::Reference< text::XTextRange >& rStart ) : SwVbaRange_BASE( rParent, rContext ), mxTextDocument(std::move( xTextDocument )) +{ + uno::Reference< text::XTextRange > xEnd; + initialize( rStart, xEnd ); +} + +SwVbaRange::SwVbaRange( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xTextDocument, const uno::Reference< text::XTextRange >& rStart, const uno::Reference< text::XTextRange >& rEnd ) : SwVbaRange_BASE( rParent, rContext ), mxTextDocument(std::move( xTextDocument )) +{ + initialize( rStart, rEnd ); +} + +SwVbaRange::SwVbaRange( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xTextDocument, const uno::Reference< text::XTextRange >& rStart, const uno::Reference< text::XTextRange >& rEnd, uno::Reference< text::XText > xText ) : SwVbaRange_BASE( rParent, rContext ),mxTextDocument(std::move( xTextDocument )), mxText(std::move( xText )) +{ + initialize( rStart, rEnd ); +} + +SwVbaRange::~SwVbaRange() +{ +} + +void SwVbaRange::initialize( const uno::Reference< text::XTextRange >& rStart, const uno::Reference< text::XTextRange >& rEnd ) +{ + if( !mxText.is() ) + { + mxText = mxTextDocument->getText(); + } + + mxTextCursor = SwVbaRangeHelper::initCursor( rStart, mxText ); + if( !mxTextCursor.is() ) + throw uno::RuntimeException("Fails to create text cursor" ); + mxTextCursor->collapseToStart(); + + if( rEnd.is() ) + mxTextCursor->gotoRange( rEnd, true ); + else + mxTextCursor->gotoEnd( true ); +} + +uno::Reference< text::XTextRange > SAL_CALL +SwVbaRange::getXTextRange() +{ + uno::Reference< text::XTextRange > xTextRange( mxTextCursor, uno::UNO_QUERY_THROW ); + return xTextRange; +} + +/** +* The complexity in this method is because we need to workaround +* an issue that the last paragraph in a document does not have a trailing CRLF. +* @return +*/ +OUString SAL_CALL +SwVbaRange::getText() +{ + OUString aText = mxTextCursor->getString(); + sal_Int32 nLen = aText.getLength(); + + // FIXME: should add a line separator if the range includes the last paragraph + if( nLen == 0 ) + { + if( mxTextCursor->isCollapsed() ) + { + mxTextCursor->goRight( 1, true ); + aText = mxTextCursor->getString(); + mxTextCursor->collapseToStart(); + } + else + { + uno::Reference< text::XTextRange > xStart = mxTextCursor->getStart(); + uno::Reference< text::XTextRange > xEnd = mxTextCursor->getEnd(); + mxTextCursor->collapseToEnd(); + mxTextCursor->goRight( 1, true ); + mxTextCursor->gotoRange( xStart, false ); + mxTextCursor->gotoRange( xEnd, true ); + } + } + + return aText; +} + +void SAL_CALL +SwVbaRange::setText( const OUString& rText ) +{ + // Emulate the MSWord behavior, Don't delete the bookmark + // which contains no text string in current inserting position, + OUString sName; + uno::Reference< text::XTextRange > xRange( mxTextCursor, uno::UNO_QUERY_THROW ); + try + { + uno::Reference< text::XTextContent > xBookmark = SwVbaRangeHelper::findBookmarkByPosition( mxTextDocument, xRange->getStart() ); + if( xBookmark.is() ) + { + uno::Reference< container::XNamed > xNamed( xBookmark, uno::UNO_QUERY_THROW ); + sName = xNamed->getName(); + } + } + catch (const uno::Exception&) + { + // do nothing + } + + if( rText.indexOf( '\n' ) != -1 ) + { + mxTextCursor->setString( OUString() ); + // process CR in strings + SwVbaRangeHelper::insertString( xRange, mxText, rText, true ); + } + else + { + mxTextCursor->setString( rText ); + } + + // insert the bookmark if the bookmark is deleted during setting text string + if( !sName.isEmpty() ) + { + uno::Reference< text::XBookmarksSupplier > xBookmarksSupplier( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameAccess > xNameAccess( xBookmarksSupplier->getBookmarks(), uno::UNO_SET_THROW ); + if( !xNameAccess->hasByName( sName ) ) + { + uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW ); + SwVbaBookmarks::addBookmarkByName( xModel, sName, xRange->getStart() ); + } + } +} + +// FIXME: test is not pass +void SAL_CALL SwVbaRange::InsertBreak(const uno::Any& _breakType) +{ + // default type is wdPageBreak; + sal_Int32 nBreakType = word::WdBreakType::wdPageBreak; + if( _breakType.hasValue() ) + _breakType >>= nBreakType; + + style::BreakType eBreakType = style::BreakType_NONE; + switch( nBreakType ) + { + case word::WdBreakType::wdPageBreak: + eBreakType = style::BreakType_PAGE_BEFORE; + break; + case word::WdBreakType::wdColumnBreak: + eBreakType = style::BreakType_COLUMN_AFTER; + break; + case word::WdBreakType::wdLineBreak: + case word::WdBreakType::wdLineBreakClearLeft: + case word::WdBreakType::wdLineBreakClearRight: + case word::WdBreakType::wdSectionBreakContinuous: + case word::WdBreakType::wdSectionBreakEvenPage: + case word::WdBreakType::wdSectionBreakNextPage: + case word::WdBreakType::wdSectionBreakOddPage: + case word::WdBreakType::wdTextWrappingBreak: + DebugHelper::basicexception( ERRCODE_BASIC_NOT_IMPLEMENTED, {} ); + break; + default: + DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETER, {} ); + } + + if( eBreakType != style::BreakType_NONE ) + { + if( !mxTextCursor->isCollapsed() ) + { + mxTextCursor->setString( OUString() ); + mxTextCursor->collapseToStart(); + } + + uno::Reference< beans::XPropertySet > xProp( mxTextCursor, uno::UNO_QUERY_THROW ); + xProp->setPropertyValue("BreakType", uno::Any( eBreakType ) ); + } +} + +void SAL_CALL +SwVbaRange::Select() +{ + uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextViewCursor > xTextViewCursor = word::getXTextViewCursor( xModel ); + xTextViewCursor->gotoRange( mxTextCursor->getStart(), false ); + xTextViewCursor->gotoRange( mxTextCursor->getEnd(), true ); +} + +void SAL_CALL +SwVbaRange::InsertParagraph() +{ + mxTextCursor->setString( "" ); + InsertParagraphBefore(); +} + +void SAL_CALL +SwVbaRange::InsertParagraphBefore() +{ + uno::Reference< text::XTextRange > xTextRange = mxTextCursor->getStart(); + mxText->insertControlCharacter( xTextRange, text::ControlCharacter::PARAGRAPH_BREAK, true ); + mxTextCursor->gotoRange( xTextRange, true ); +} + +void SAL_CALL +SwVbaRange::InsertParagraphAfter() +{ + uno::Reference< text::XTextRange > xTextRange = mxTextCursor->getEnd(); + mxText->insertControlCharacter( xTextRange, text::ControlCharacter::PARAGRAPH_BREAK, true ); +} + +uno::Reference< word::XParagraphFormat > SAL_CALL +SwVbaRange::getParagraphFormat() +{ + uno::Reference< beans::XPropertySet > xParaProps( mxTextCursor, uno::UNO_QUERY_THROW ); + return uno::Reference< word::XParagraphFormat >( new SwVbaParagraphFormat( this, mxContext, xParaProps ) ); +} + +void SAL_CALL +SwVbaRange::setParagraphFormat( const uno::Reference< word::XParagraphFormat >& /*rParagraphFormat*/ ) +{ + throw uno::RuntimeException("Not implemented" ); +} + +void SwVbaRange::GetStyleInfo(OUString& aStyleName, OUString& aStyleType ) +{ + uno::Reference< beans::XPropertySet > xProp( mxTextCursor, uno::UNO_QUERY_THROW ); + if( ( xProp->getPropertyValue("CharStyleName") >>= aStyleName ) && !aStyleName.isEmpty() ) + { + aStyleType = "CharacterStyles"; + } + else if( ( xProp->getPropertyValue("ParaStyleName") >>= aStyleName ) && !aStyleName.isEmpty() ) + { + aStyleType = "ParagraphStyles"; + } + if( aStyleType.isEmpty() ) + { + DebugHelper::runtimeexception( ERRCODE_BASIC_INTERNAL_ERROR ); + } +} + +uno::Any SAL_CALL +SwVbaRange::getStyle() +{ + OUString aStyleName; + OUString aStyleType; + GetStyleInfo( aStyleName, aStyleType ); + uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( mxTextDocument, uno::UNO_QUERY_THROW); + uno::Reference< container::XNameAccess > xStylesAccess( xStyleSupplier->getStyleFamilies()->getByName( aStyleType ), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xStyleProps( xStylesAccess->getByName( aStyleName ), uno::UNO_QUERY_THROW ); + uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< word::XStyle >( new SwVbaStyle( this, mxContext, xModel, xStyleProps ) ) ); +} + +void SAL_CALL +SwVbaRange::setStyle( const uno::Any& rStyle ) +{ + uno::Reference< beans::XPropertySet > xParaProps( mxTextCursor, uno::UNO_QUERY_THROW ); + SwVbaStyle::setStyle( xParaProps, rStyle ); +} + +uno::Reference< word::XFont > SAL_CALL +SwVbaRange::getFont() +{ + VbaPalette aColors; + return new SwVbaFont( mxParent, mxContext, aColors.getPalette(), uno::Reference< beans::XPropertySet >( getXTextRange(), uno::UNO_QUERY_THROW ) ); +} + +uno::Reference< word::XFind > SAL_CALL +SwVbaRange::getFind() +{ + uno::Reference< text::XTextRange > xTextRange = getXTextRange(); + uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW ); + return SwVbaFind::GetOrCreateFind(this, mxContext, xModel, xTextRange); +} + +uno::Reference< word::XListFormat > SAL_CALL +SwVbaRange::getListFormat() +{ + return uno::Reference< word::XListFormat >( new SwVbaListFormat( this, mxContext, getXTextRange() ) ); +} + +::sal_Int32 SAL_CALL SwVbaRange::getLanguageID() +{ + uno::Reference< beans::XPropertySet > xParaProps( mxTextCursor, uno::UNO_QUERY_THROW ); + return static_cast<sal_uInt16>(SwVbaStyle::getLanguageID( xParaProps )); +} + +void SAL_CALL SwVbaRange::setLanguageID( ::sal_Int32 _languageid ) +{ + uno::Reference< beans::XPropertySet > xParaProps( mxTextCursor, uno::UNO_QUERY_THROW ); + SwVbaStyle::setLanguageID( xParaProps, LanguageType(_languageid) ); +} + +uno::Any SAL_CALL +SwVbaRange::PageSetup( ) +{ + uno::Reference< beans::XPropertySet > xParaProps( mxTextCursor, uno::UNO_QUERY_THROW ); + uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW ); + OUString aPageStyleName; + xParaProps->getPropertyValue("PageStyleName") >>= aPageStyleName; + uno::Reference< style::XStyleFamiliesSupplier > xSytleFamSupp( xModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameAccess > xSytleFamNames( xSytleFamSupp->getStyleFamilies(), uno::UNO_SET_THROW ); + uno::Reference< container::XNameAccess > xPageStyles( xSytleFamNames->getByName("PageStyles"), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xPageProps( xPageStyles->getByName( aPageStyleName ), uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< word::XPageSetup >( new SwVbaPageSetup( this, mxContext, xModel, xPageProps ) ) ); +} + +::sal_Int32 SAL_CALL SwVbaRange::getStart() +{ + uno::Reference< text::XText > xText = mxTextDocument->getText(); + return SwVbaRangeHelper::getPosition( xText, mxTextCursor->getStart() ); +} + +void SAL_CALL SwVbaRange::setStart( ::sal_Int32 _start ) +{ + uno::Reference< text::XText > xText = mxTextDocument->getText(); + uno::Reference< text::XTextRange > xStart = SwVbaRangeHelper::getRangeByPosition( xText, _start ); + uno::Reference< text::XTextRange > xEnd = mxTextCursor->getEnd(); + + mxTextCursor->gotoRange( xStart, false ); + mxTextCursor->gotoRange( xEnd, true ); +} + +::sal_Int32 SAL_CALL SwVbaRange::getEnd() +{ + uno::Reference< text::XText > xText = mxTextDocument->getText(); + return SwVbaRangeHelper::getPosition( xText, mxTextCursor->getEnd() ); +} + +void SAL_CALL SwVbaRange::setEnd( ::sal_Int32 _end ) +{ + uno::Reference< text::XText > xText = mxTextDocument->getText(); + uno::Reference< text::XTextRange > xEnd = SwVbaRangeHelper::getRangeByPosition( xText, _end ); + + mxTextCursor->collapseToStart(); + mxTextCursor->gotoRange( xEnd, true ); +} + +sal_Bool SAL_CALL SwVbaRange::InRange( const uno::Reference< ::ooo::vba::word::XRange >& Range ) +{ + SwVbaRange* pRange = dynamic_cast< SwVbaRange* >( Range.get() ); + if( !pRange ) + throw uno::RuntimeException(); + uno::Reference< text::XTextRange > xTextRange = pRange->getXTextRange(); + uno::Reference< text::XTextRangeCompare > xTRC( mxTextCursor->getText(), uno::UNO_QUERY_THROW ); + if( xTRC->compareRegionStarts( xTextRange, getXTextRange() ) >= 0 && xTRC->compareRegionEnds( xTextRange, getXTextRange() ) <= 0 ) + return true; + return false; +} + +uno::Any SAL_CALL +SwVbaRange::Revisions( const uno::Any& index ) +{ + uno::Reference< text::XTextRange > xTextRange = getXTextRange(); + uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< XCollection > xCol( new SwVbaRevisions( mxParent, mxContext, xModel, xTextRange ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaRange::Sections( const uno::Any& index ) +{ + uno::Reference< text::XTextRange > xTextRange = getXTextRange(); + uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< XCollection > xCol( new SwVbaSections( mxParent, mxContext, xModel, xTextRange ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaRange::Fields( const uno::Any& index ) +{ + //FIXME: should be get the field in current range + uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< XCollection > xCol( new SwVbaFields( mxParent, mxContext, xModel ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +OUString +SwVbaRange::getServiceImplName() +{ + return "SwVbaRange"; +} + +uno::Sequence< OUString > +SwVbaRange::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Range" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbarange.hxx b/sw/source/ui/vba/vbarange.hxx new file mode 100644 index 0000000000..f0dd156350 --- /dev/null +++ b/sw/source/ui/vba/vbarange.hxx @@ -0,0 +1,101 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBARANGE_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBARANGE_HXX + +#include <ooo/vba/word/XRange.hpp> +#include <ooo/vba/word/XParagraphFormat.hpp> +#include <ooo/vba/word/XFont.hpp> +#include <ooo/vba/word/XFind.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <ooo/vba/word/XListFormat.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XRange > SwVbaRange_BASE; + +class SwVbaRange : public SwVbaRange_BASE +{ +private: + css::uno::Reference< css::text::XTextDocument > mxTextDocument; + css::uno::Reference< css::text::XTextCursor > mxTextCursor; + css::uno::Reference< css::text::XText > mxText; + +private: + /// @throws css::script::BasicErrorException + /// @throws css::uno::RuntimeException + void initialize( const css::uno::Reference< css::text::XTextRange >& rStart, const css::uno::Reference< css::text::XTextRange >& rEnd ); + /// @throws css::uno::RuntimeException + void GetStyleInfo(OUString& aStyleName, OUString& aStyleType ); +public: + /// @throws css::script::BasicErrorException + /// @throws css::uno::RuntimeException + SwVbaRange( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xTextDocument, const css::uno::Reference< css::text::XTextRange >& rStart); + /// @throws css::script::BasicErrorException + /// @throws css::uno::RuntimeException + SwVbaRange( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xTextDocument, const css::uno::Reference< css::text::XTextRange >& rStart, const css::uno::Reference< css::text::XTextRange >& rEnd ); + /// @throws css::script::BasicErrorException + /// @throws css::uno::RuntimeException + SwVbaRange( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xTextDocument, const css::uno::Reference< css::text::XTextRange >& rStart, const css::uno::Reference< css::text::XTextRange >& rEnd, css::uno::Reference< css::text::XText > xText); + virtual ~SwVbaRange() override; + const css::uno::Reference< css::text::XTextDocument >& getDocument() const { return mxTextDocument; } + + virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getXTextRange() override; + const css::uno::Reference< css::text::XText >& getXText() const { return mxText; } + void setXTextCursor( const css::uno::Reference< css::text::XTextCursor >& xTextCursor ) { mxTextCursor = xTextCursor; } + + // Attribute + virtual OUString SAL_CALL getText() override; + virtual void SAL_CALL setText( const OUString& rText ) override; + virtual css::uno::Reference< ooo::vba::word::XParagraphFormat > SAL_CALL getParagraphFormat() override; + virtual void SAL_CALL setParagraphFormat( const css::uno::Reference< ooo::vba::word::XParagraphFormat >& rParagraphFormat ) override; + virtual css::uno::Any SAL_CALL getStyle() override; + virtual void SAL_CALL setStyle( const css::uno::Any& _xStyle ) override; + virtual css::uno::Reference< ooo::vba::word::XFont > SAL_CALL getFont() override; + virtual css::uno::Reference< ooo::vba::word::XFind > SAL_CALL getFind() override; + virtual css::uno::Reference< ooo::vba::word::XListFormat > SAL_CALL getListFormat() override; + + //XDefaultProperty + virtual OUString SAL_CALL getDefaultPropertyName() override { return "Text"; } + + // Methods + virtual void SAL_CALL InsertBreak(const css::uno::Any& _breakType) override; + virtual void SAL_CALL Select() override; + virtual void SAL_CALL InsertParagraph() override; + virtual void SAL_CALL InsertParagraphBefore() override; + virtual void SAL_CALL InsertParagraphAfter() override; + virtual ::sal_Int32 SAL_CALL getLanguageID() override; + virtual void SAL_CALL setLanguageID( ::sal_Int32 _languageid ) override; + virtual css::uno::Any SAL_CALL PageSetup() override; + virtual ::sal_Int32 SAL_CALL getStart() override; + virtual void SAL_CALL setStart( ::sal_Int32 _start ) override; + virtual ::sal_Int32 SAL_CALL getEnd() override; + virtual void SAL_CALL setEnd( ::sal_Int32 _end ) override; + virtual sal_Bool SAL_CALL InRange( const css::uno::Reference< ::ooo::vba::word::XRange >& Range ) override; + virtual css::uno::Any SAL_CALL Revisions( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL Sections( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL Fields( const css::uno::Any& aIndex ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBARANGE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbarangehelper.cxx b/sw/source/ui/vba/vbarangehelper.cxx new file mode 100644 index 0000000000..1760d0f985 --- /dev/null +++ b/sw/source/ui/vba/vbarangehelper.cxx @@ -0,0 +1,191 @@ +/* -*- 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 "vbarangehelper.hxx" +#include <vbahelper/vbahelper.hxx> +#include <com/sun/star/text/ControlCharacter.hpp> +#include <com/sun/star/text/XTextRangeCompare.hpp> +#include <com/sun/star/text/XBookmarksSupplier.hpp> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +/** + * get a range in a xText by creating + * a cursor that iterates over the text. If the iterating cursor is + * equal to the desired position, the range equivalent is returned. + * Some special cases are tables that are inside of the text, because the + * position has to be adjusted. + * @param xText a text where a range position is searched + * @param position a position inside o the text + * @return a range for the position; null is returned if no range can be + * constructed. + */ +uno::Reference< text::XTextRange > SwVbaRangeHelper::getRangeByPosition( const uno::Reference< text::XText >& rText, sal_Int32 _position ) +{ + uno::Reference< text::XTextRange > xRange; + if( rText.is() ) + { + sal_Int32 nPos = 0; + uno::Reference< text::XTextCursor > xCursor = rText->createTextCursor(); + xCursor->collapseToStart(); + bool bCanGo = true; + while( !xRange.is() && bCanGo ) + { + if( _position == nPos ) + { + xRange = xCursor->getStart(); + } + else + { + bCanGo = xCursor->goRight( 1, false ); + nPos++; + } + } + } + return xRange; +} + +void SwVbaRangeHelper::insertString( uno::Reference< text::XTextRange > const & rTextRange, uno::Reference< text::XText > const & rText, std::u16string_view aStr, bool _bAbsorb ) +{ + size_t nlastIndex = 0; + size_t nIndex = 0; + uno::Reference< text::XTextRange > xRange = rTextRange; + + while( ( nIndex = aStr.find('\n', nlastIndex)) != std::u16string_view::npos ) + { + xRange = xRange->getEnd(); + if( nlastIndex < ( nIndex - 1 ) ) + { + rText->insertString( xRange, OUString(aStr.substr( nlastIndex, ( nIndex - 1 - nlastIndex ) )), _bAbsorb ); + xRange = xRange->getEnd(); + } + + rText->insertControlCharacter( xRange, text::ControlCharacter::PARAGRAPH_BREAK, _bAbsorb ); + nlastIndex = nIndex + 1; + } + + if( nlastIndex < aStr.size() ) + { + xRange = xRange->getEnd(); + + OUString aWatt( aStr.substr( nlastIndex ) ); + rText->insertString( xRange, aWatt, _bAbsorb ); + } +} + +uno::Reference< text::XTextCursor > SwVbaRangeHelper::initCursor( const uno::Reference< text::XTextRange >& rTextRange, + const uno::Reference< text::XText >& rText ) +{ + uno::Reference< text::XTextCursor > xTextCursor; + bool bGotTextCursor = false; + + try + { + xTextCursor = rText->createTextCursorByRange( rTextRange ); + bGotTextCursor = true; + } + catch (const uno::Exception& e) + { + DebugHelper::basicexception(e); + } + + if( !bGotTextCursor || !xTextCursor.is() ) + { + try + { + uno::Reference< text::XText > xText = rTextRange->getText(); + xTextCursor = xText->createTextCursor(); + bGotTextCursor = true; + } + catch (const uno::Exception& e) + { + DebugHelper::basicexception(e); + } + } + + if( !bGotTextCursor || !xTextCursor.is() ) + { + try + { + xTextCursor = rText->createTextCursor(); + } + catch (const uno::Exception& e) + { + DebugHelper::basicexception(e); + } + } + return xTextCursor; +} + +sal_Int32 SwVbaRangeHelper::getPosition( const uno::Reference< text::XText >& rText, const uno::Reference< text::XTextRange >& rTextRange ) +{ + sal_Int32 nPosition = -1; + if( rText.is() && rTextRange.is() ) + { + nPosition = 0; + uno::Reference< text::XTextCursor > xCursor = rText->createTextCursor(); + xCursor->collapseToStart(); + uno::Reference< text::XTextRangeCompare > xCompare( rText, uno::UNO_QUERY_THROW ); + // compareValue is 0 if the ranges are equal + sal_Int32 nCompareValue = xCompare->compareRegionStarts( xCursor->getStart(), rTextRange ); + bool canGo = true; + + while( nCompareValue !=0 && canGo ) + { + canGo = xCursor->goRight( 1, false ); + nCompareValue = xCompare->compareRegionStarts( xCursor->getStart(), rTextRange ); + nPosition++; + } + + // check fails: no correct position found + if( !canGo && nCompareValue != 0 ) + { + nPosition = -1; + } + } + + return nPosition; +} + +uno::Reference< text::XTextContent > SwVbaRangeHelper::findBookmarkByPosition( const uno::Reference< text::XTextDocument >& xTextDoc, const uno::Reference< text::XTextRange >& xTextRange ) +{ + uno::Reference< text::XBookmarksSupplier > xBookmarksSupplier( xTextDoc, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xIndexAccess( xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY_THROW ); + for( sal_Int32 index = 0; index < xIndexAccess->getCount(); index++ ) + { + uno::Reference< text::XTextContent > xBookmark( xIndexAccess->getByIndex( index ), uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextRange > xBkAnchor = xBookmark->getAnchor(); + uno::Reference< text::XTextRangeCompare > xCompare( xBkAnchor->getText(), uno::UNO_QUERY_THROW ); + if( xCompare->compareRegionStarts( xBkAnchor->getStart(), xBkAnchor->getEnd() ) == 0 ) + { + try + { + if( xCompare->compareRegionStarts( xTextRange, xBkAnchor->getStart() ) == 0 ) + return xBookmark; + } + catch (const uno::Exception&) + { + continue; + } + } + } + return uno::Reference< text::XTextContent >(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbarangehelper.hxx b/sw/source/ui/vba/vbarangehelper.hxx new file mode 100644 index 0000000000..af3f885e4a --- /dev/null +++ b/sw/source/ui/vba/vbarangehelper.hxx @@ -0,0 +1,44 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBARANGEHELPER_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBARANGEHELPER_HXX + +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/text/XTextDocument.hpp> + +class SwVbaRangeHelper +{ +public: + /// @throws css::uno::RuntimeException + static css::uno::Reference< css::text::XTextRange > getRangeByPosition( const css::uno::Reference< css::text::XText >& rText, sal_Int32 _position ); + /// @throws css::uno::RuntimeException + static void insertString( css::uno::Reference< css::text::XTextRange > const & rTextRange, css::uno::Reference< css::text::XText > const & rText, std::u16string_view aStr, bool _bAbsorb ); + /// @throws css::uno::RuntimeException + /// @throws css::script::BasicErrorException + static css::uno::Reference< css::text::XTextCursor > initCursor( const css::uno::Reference< css::text::XTextRange >& rTextRange, const css::uno::Reference< css::text::XText >& rText ); + /// @throws css::uno::RuntimeException + static sal_Int32 getPosition( const css::uno::Reference< css::text::XText >& rText, const css::uno::Reference< css::text::XTextRange >& rTextRange ); + /// @throws css::uno::RuntimeException + static css::uno::Reference< css::text::XTextContent > findBookmarkByPosition( const css::uno::Reference< css::text::XTextDocument >& xTextDoc, const css::uno::Reference< css::text::XTextRange >& xTextRange ); + +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBARANGEHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbareplacement.cxx b/sw/source/ui/vba/vbareplacement.cxx new file mode 100644 index 0000000000..bed7aee8d7 --- /dev/null +++ b/sw/source/ui/vba/vbareplacement.cxx @@ -0,0 +1,67 @@ +/* -*- 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 <utility> + +#include "vbareplacement.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaReplacement::SwVbaReplacement( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< util::XPropertyReplace > xPropertyReplace ) : + SwVbaReplacement_BASE( rParent, rContext ), mxPropertyReplace(std::move( xPropertyReplace )) +{ +} + +SwVbaReplacement::~SwVbaReplacement() +{ +} + +OUString SAL_CALL SwVbaReplacement::getText() +{ + return mxPropertyReplace->getReplaceString(); +} + +void SAL_CALL SwVbaReplacement::setText( const OUString& _text ) +{ + mxPropertyReplace->setReplaceString( _text ); +} + +void SAL_CALL SwVbaReplacement::ClearFormatting( ) +{ + uno::Sequence< beans::PropertyValue > aPropValues; + mxPropertyReplace->setReplaceAttributes( aPropValues ); +} + +OUString +SwVbaReplacement::getServiceImplName() +{ + return "SwVbaReplacement"; +} + +uno::Sequence< OUString > +SwVbaReplacement::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Replacement" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbareplacement.hxx b/sw/source/ui/vba/vbareplacement.hxx new file mode 100644 index 0000000000..6c6ee89422 --- /dev/null +++ b/sw/source/ui/vba/vbareplacement.hxx @@ -0,0 +1,51 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAREPLACEMENT_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAREPLACEMENT_HXX + +#include <ooo/vba/word/XReplacement.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/util/XPropertyReplace.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XReplacement > SwVbaReplacement_BASE; + +class SwVbaReplacement : public SwVbaReplacement_BASE +{ +private: + css::uno::Reference< css::util::XPropertyReplace> mxPropertyReplace; + +public: + /// @throws css::uno::RuntimeException + SwVbaReplacement( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::util::XPropertyReplace > xPropertyReplace ); + virtual ~SwVbaReplacement() override; + + // Attributes + virtual OUString SAL_CALL getText() override; + virtual void SAL_CALL setText( const OUString& _text ) override; + + //Methods + virtual void SAL_CALL ClearFormatting() override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAREPLACEMENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbarevision.cxx b/sw/source/ui/vba/vbarevision.cxx new file mode 100644 index 0000000000..f8b1c5978d --- /dev/null +++ b/sw/source/ui/vba/vbarevision.cxx @@ -0,0 +1,95 @@ +/* -*- 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 "vbarevision.hxx" +#include <sal/log.hxx> +#include <com/sun/star/document/XRedlinesSupplier.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include "wordvbahelper.hxx" +#include <docsh.hxx> +#include <doc.hxx> +#include <IDocumentRedlineAccess.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaRevision::SwVbaRevision( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< frame::XModel > xModel, uno::Reference< beans::XPropertySet > xRedlineProps ) : SwVbaRevision_BASE( rParent, rContext ), mxModel(std::move( xModel )), mxRedlineProps(std::move( xRedlineProps )) +{ +} + +SwVbaRevision::~SwVbaRevision() +{ +} + +sal_Int32 SwVbaRevision::GetPosition() +{ + sal_Int32 nPos = -1; + uno::Reference< document::XRedlinesSupplier > xRedlinesSupp( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xRedlines( xRedlinesSupp->getRedlines(), uno::UNO_QUERY_THROW ); + sal_Int32 nCount = xRedlines->getCount(); + for( sal_Int32 i = 0; i < nCount; i++ ) + { + uno::Reference< beans::XPropertySet > xProps( xRedlines->getByIndex( i ), uno::UNO_QUERY_THROW ); + if( xProps == mxRedlineProps ) + { + nPos = i; + SAL_INFO("sw.ui", "the redline position is " << nPos); + break; + } + } + if( nPos == -1 ) + throw uno::RuntimeException(); + + return nPos; +} + +void SAL_CALL +SwVbaRevision::Accept() +{ + SwDoc* pDoc = word::getDocShell( mxModel )->GetDoc(); + if( pDoc ) + pDoc->getIDocumentRedlineAccess().AcceptRedline( GetPosition(), true ); +} + +void SAL_CALL +SwVbaRevision::Reject( ) +{ + SwDoc* pDoc = word::getDocShell( mxModel )->GetDoc(); + if( pDoc ) + pDoc->getIDocumentRedlineAccess().RejectRedline( GetPosition(), true ); +} + +OUString +SwVbaRevision::getServiceImplName() +{ + return "SwVbaRevision"; +} + +uno::Sequence< OUString > +SwVbaRevision::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Revision" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbarevision.hxx b/sw/source/ui/vba/vbarevision.hxx new file mode 100644 index 0000000000..c483f6578f --- /dev/null +++ b/sw/source/ui/vba/vbarevision.hxx @@ -0,0 +1,52 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAREVISION_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAREVISION_HXX + +#include <ooo/vba/word/XRevision.hpp> +#include <vbahelper/vbahelperinterface.hxx> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XRevision > SwVbaRevision_BASE; + +class SwVbaRevision : public SwVbaRevision_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::beans::XPropertySet > mxRedlineProps; + +private: + /// @throws css::uno::RuntimeException + sal_Int32 GetPosition(); + +public: + /// @throws css::uno::RuntimeException + SwVbaRevision( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::frame::XModel > xModel, css::uno::Reference< css::beans::XPropertySet > xRedlineProps ); + virtual ~SwVbaRevision() override; + + // Methods + virtual void SAL_CALL Accept( ) override; + virtual void SAL_CALL Reject( ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAREVISION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbarevisions.cxx b/sw/source/ui/vba/vbarevisions.cxx new file mode 100644 index 0000000000..bfd8c68eae --- /dev/null +++ b/sw/source/ui/vba/vbarevisions.cxx @@ -0,0 +1,185 @@ +/* -*- 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 "vbarevisions.hxx" +#include "vbarevision.hxx" +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/document/XRedlinesSupplier.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/text/XTextRangeCompare.hpp> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +typedef std::vector< uno::Reference< beans::XPropertySet > > RevisionMap; + +namespace { + +class RedlinesEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration > +{ + RevisionMap mRevisionMap; + RevisionMap::iterator mIt; +public: + explicit RedlinesEnumeration( RevisionMap&& sMap ) : mRevisionMap( std::move(sMap) ), mIt( mRevisionMap.begin() ) {} + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( mIt != mRevisionMap.end() ); + } + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( !hasMoreElements() ) + throw container::NoSuchElementException(); + uno::Reference< beans::XPropertySet > xRevision( *mIt++ ); + return uno::Any( xRevision ) ; + } +}; + +class RevisionCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess, + container::XEnumerationAccess > +{ + RevisionMap mRevisionMap; +public: +/// @throws css::uno::RuntimeException +RevisionCollectionHelper( const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextRange >& xTextRange ); + + // XElementAccess + virtual uno::Type SAL_CALL getElementType( ) override { return cppu::UnoType<beans::XPropertySet>::get(); } + virtual sal_Bool SAL_CALL hasElements( ) override { return ( !mRevisionMap.empty() ); } + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override { return mRevisionMap.size(); } + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override + { + if ( Index < 0 || Index >= getCount() ) + throw lang::IndexOutOfBoundsException(); + + return uno::Any( mRevisionMap[ Index ] ); + + } + // XEnumerationAccess + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override + { + return new RedlinesEnumeration( std::vector(mRevisionMap) ); + } +}; + +} + +RevisionCollectionHelper::RevisionCollectionHelper( const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextRange >& xTextRange ) + { + uno::Reference< text::XTextRangeCompare > xTRC( xTextRange->getText(), uno::UNO_QUERY_THROW ); + uno::Reference< document::XRedlinesSupplier > xRedlinesSupp( xModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xRedlines( xRedlinesSupp->getRedlines(), uno::UNO_QUERY_THROW ); + sal_Int32 nCount = xRedlines->getCount(); + for( sal_Int32 index = 0; index < nCount; index++ ) + { + uno::Reference< text::XTextRange > xRedlineRange( xRedlines->getByIndex( index ), uno::UNO_QUERY_THROW ); + if( xTRC->compareRegionStarts( xTextRange, xRedlineRange ) >= 0 && xTRC->compareRegionEnds( xTextRange, xRedlineRange ) <= 0 ) + { + uno::Reference< beans::XPropertySet > xRedlineProps( xRedlineRange, uno::UNO_QUERY_THROW ); + mRevisionMap.push_back( xRedlineProps ); + } + } + } + +namespace { + +class RevisionsEnumeration : public EnumerationHelperImpl +{ + uno::Reference< frame::XModel > m_xModel; +public: + /// @throws uno::RuntimeException + RevisionsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, uno::Reference< frame::XModel > xModel ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel(std::move( xModel )) {} + + virtual uno::Any SAL_CALL nextElement( ) override + { + uno::Reference< beans::XPropertySet > xRevision( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< word::XRevision > ( new SwVbaRevision( m_xParent, m_xContext, m_xModel, xRevision ) ) ); + } + +}; + +} + +SwVbaRevisions::SwVbaRevisions( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextRange >& xTextRange ): SwVbaRevisions_BASE( xParent, xContext, new RevisionCollectionHelper( xModel, xTextRange ) ), mxModel( xModel ) +{ +} + +SwVbaRevisions::SwVbaRevisions( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< frame::XModel > xModel, const uno::Reference< container::XIndexAccess >& xIndexAccess ): SwVbaRevisions_BASE( xParent, xContext, xIndexAccess ), mxModel(std::move( xModel )) +{ +} + +// XEnumerationAccess +uno::Type +SwVbaRevisions::getElementType() +{ + return cppu::UnoType<word::XRevision>::get(); +} +uno::Reference< container::XEnumeration > +SwVbaRevisions::createEnumeration() +{ + uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); + return new RevisionsEnumeration( this, mxContext, xEnumAccess->createEnumeration(), mxModel ); +} + +uno::Any +SwVbaRevisions::createCollectionObject( const css::uno::Any& aSource ) +{ + uno::Reference< beans::XPropertySet > xRevision( aSource, uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< word::XRevision > ( new SwVbaRevision( this, mxContext, mxModel, xRevision ) ) ); +} + +void SAL_CALL SwVbaRevisions::AcceptAll( ) +{ + // First we need to put all the redline into a vector, because if the redline is accepted, + // it will auto delete in the document. + std::vector< uno::Reference< word::XRevision > > aRevisions; + uno::Reference< container::XEnumeration > xEnumeration = createEnumeration(); + while( xEnumeration->hasMoreElements() ) + { + uno::Reference< word::XRevision > xRevision( xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); + aRevisions.push_back( xRevision ); + } + + for( const auto& xRevision : aRevisions ) + xRevision->Accept(); +} + +void SAL_CALL SwVbaRevisions::RejectAll( ) +{ + throw uno::RuntimeException(); +} + +OUString +SwVbaRevisions::getServiceImplName() +{ + return "SwVbaRevisions"; +} + +css::uno::Sequence<OUString> +SwVbaRevisions::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.Revisions" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbarevisions.hxx b/sw/source/ui/vba/vbarevisions.hxx new file mode 100644 index 0000000000..a3fe79108a --- /dev/null +++ b/sw/source/ui/vba/vbarevisions.hxx @@ -0,0 +1,54 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAREVISIONS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAREVISIONS_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XRevisions.hpp> +#include <com/sun/star/text/XTextRange.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XRevisions > SwVbaRevisions_BASE; + +class SwVbaRevisions : public SwVbaRevisions_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + +public: + SwVbaRevisions( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextRange >& xTextRange ); + + SwVbaRevisions( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::frame::XModel > xModel, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess ); + + // Methods + virtual void SAL_CALL AcceptAll( ) override; + virtual void SAL_CALL RejectAll( ) override; + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaRevisions_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAREVISIONS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbarow.cxx b/sw/source/ui/vba/vbarow.cxx new file mode 100644 index 0000000000..aa4f7701fd --- /dev/null +++ b/sw/source/ui/vba/vbarow.cxx @@ -0,0 +1,121 @@ +/* -*- 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 "vbarow.hxx" +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <ooo/vba/word/WdRowHeightRule.hpp> +#include <ooo/vba/word/WdConstants.hpp> +#include "vbatablehelper.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaRow::SwVbaRow( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext,uno::Reference< text::XTextTable > xTextTable, sal_Int32 nIndex ) : + SwVbaRow_BASE( rParent, rContext ), mxTextTable(std::move( xTextTable )), mnIndex( nIndex ) +{ + mxTableRows = mxTextTable->getRows(); + mxRowProps.set( mxTableRows->getByIndex( mnIndex ), uno::UNO_QUERY_THROW ); +} + +SwVbaRow::~SwVbaRow() +{ +} + +uno::Any SAL_CALL SwVbaRow::getHeight() +{ + if( getHeightRule() == word::WdRowHeightRule::wdRowHeightAuto ) + return uno::Any( sal_Int32( word::WdConstants::wdUndefined ) ); + + sal_Int32 nHeight = 0; + mxRowProps->getPropertyValue("Height") >>= nHeight; + return uno::Any( static_cast<float>(Millimeter::getInPoints( nHeight )) ); +} + +void SAL_CALL SwVbaRow::setHeight( const uno::Any& _height ) +{ + float height = 0; + _height >>= height; + + sal_Int32 nHeight = Millimeter::getInHundredthsOfOneMillimeter( height ); + mxRowProps->setPropertyValue("Height", uno::Any( nHeight ) ); +} + +::sal_Int32 SAL_CALL SwVbaRow::getHeightRule() +{ + bool isAutoHeight = false; + mxRowProps->getPropertyValue("IsAutoHeight") >>= isAutoHeight; + return isAutoHeight ? word::WdRowHeightRule::wdRowHeightAuto : word::WdRowHeightRule::wdRowHeightExactly; +} + +void SAL_CALL SwVbaRow::setHeightRule( ::sal_Int32 _heightrule ) +{ + bool isAutoHeight = ( _heightrule == word::WdRowHeightRule::wdRowHeightAuto ); + mxRowProps->setPropertyValue("IsAutoHeight", uno::Any( isAutoHeight ) ); +} + +void SAL_CALL +SwVbaRow::Select( ) +{ + SelectRow( getCurrentWordDoc(mxContext), mxTextTable, mnIndex, mnIndex ); +} + +void SwVbaRow::SelectRow( const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextTable >& xTextTable, sal_Int32 nStartRow, sal_Int32 nEndRow ) +{ + OUString sRangeName = "A" + OUString::number(nStartRow + 1); + SwVbaTableHelper aTableHelper( xTextTable ); + sal_Int32 nColCount = aTableHelper.getTabColumnsCount( nEndRow ); + // FIXME: the column count > 26 + //char cCol = 'A' + nColCount - 1; + OUString sCol = SwVbaTableHelper::getColumnStr( nColCount - 1); + sRangeName += ":" + sCol + OUString::number(nEndRow + 1); + + uno::Reference< table::XCellRange > xCellRange( xTextTable, uno::UNO_QUERY_THROW ); + uno::Reference< table::XCellRange > xSelRange = xCellRange->getCellRangeByName( sRangeName ); + + uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW ); + xSelection->select( uno::Any( xSelRange ) ); +} + +void SAL_CALL SwVbaRow::SetHeight( float height, sal_Int32 heightrule ) +{ + setHeightRule( heightrule ); + setHeight( uno::Any( height ) ); +} + +OUString +SwVbaRow::getServiceImplName() +{ + return "SwVbaRow"; +} + +uno::Sequence< OUString > +SwVbaRow::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Row" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbarow.hxx b/sw/source/ui/vba/vbarow.hxx new file mode 100644 index 0000000000..40abaee2ee --- /dev/null +++ b/sw/source/ui/vba/vbarow.hxx @@ -0,0 +1,61 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAROW_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAROW_HXX + +#include <ooo/vba/word/XRow.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/table/XTableRows.hpp> +#include <com/sun/star/text/XTextTable.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XRow > SwVbaRow_BASE; + +class SwVbaRow : public SwVbaRow_BASE +{ +private: + css::uno::Reference< css::text::XTextTable > mxTextTable; + css::uno::Reference< css::table::XTableRows > mxTableRows; + css::uno::Reference< css::beans::XPropertySet > mxRowProps; + sal_Int32 mnIndex; + +public: + /// @throws css::uno::RuntimeException + SwVbaRow( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextTable > xTextTable, sal_Int32 nIndex ); + virtual ~SwVbaRow() override; + + // Attributes + virtual css::uno::Any SAL_CALL getHeight() override; + virtual void SAL_CALL setHeight( const css::uno::Any& _height ) override; + virtual ::sal_Int32 SAL_CALL getHeightRule() override; + virtual void SAL_CALL setHeightRule( ::sal_Int32 _heightrule ) override; + + // Methods + virtual void SAL_CALL Select( ) override; + virtual void SAL_CALL SetHeight( float height, sal_Int32 heightrule ) override; + + /// @throws css::uno::RuntimeException + static void SelectRow( const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextTable >& xTextTable, sal_Int32 nStartRow, sal_Int32 nEndRow ); + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAROW_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbarows.cxx b/sw/source/ui/vba/vbarows.cxx new file mode 100644 index 0000000000..2b757ff31f --- /dev/null +++ b/sw/source/ui/vba/vbarows.cxx @@ -0,0 +1,370 @@ +/* -*- 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 "vbarows.hxx" +#include "vbarow.hxx" +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <ooo/vba/word/WdRowAlignment.hpp> +#include <ooo/vba/word/WdConstants.hpp> +#include <ooo/vba/word/WdRulerStyle.hpp> +#include <basic/sberrors.hxx> +#include <utility> +#include "vbacolumns.hxx" +#include "vbatablehelper.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class RowsEnumWrapper : public EnumerationHelper_BASE +{ + uno::WeakReference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< text::XTextTable > mxTextTable; + uno::Reference< container::XIndexAccess > mxIndexAccess; + sal_Int32 m_nIndex; + +public: + RowsEnumWrapper( const uno::Reference< XHelperInterface >& xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< text::XTextTable > xTextTable ) : mxParent( xParent ), mxContext(std::move( xContext )), mxTextTable(std::move( xTextTable )), m_nIndex( 0 ) + { + mxIndexAccess = mxTextTable->getRows(); + } + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( m_nIndex < mxIndexAccess->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if( m_nIndex < mxIndexAccess->getCount() ) + { + return uno::Any( uno::Reference< word::XRow > ( new SwVbaRow( mxParent, mxContext, mxTextTable, m_nIndex++ ) ) ); + } + throw container::NoSuchElementException(); + } +}; + +} + +SwVbaRows::SwVbaRows( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< text::XTextTable > xTextTable, const uno::Reference< table::XTableRows >& xTableRows ) : SwVbaRows_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( xTableRows, uno::UNO_QUERY_THROW ) ), mxTextTable(std::move( xTextTable )), mxTableRows( xTableRows ) +{ + mnStartRowIndex = 0; + mnEndRowIndex = m_xIndexAccess->getCount() - 1; +} + +SwVbaRows::SwVbaRows( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< text::XTextTable > xTextTable, const uno::Reference< table::XTableRows >& xTableRows, sal_Int32 nStarIndex, sal_Int32 nEndIndex ) : SwVbaRows_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( xTableRows, uno::UNO_QUERY_THROW ) ), mxTextTable(std::move( xTextTable )), mxTableRows( xTableRows ), mnStartRowIndex( nStarIndex ), mnEndRowIndex( nEndIndex ) +{ + if( mnEndRowIndex < mnStartRowIndex ) + throw uno::RuntimeException(); +} + +/** + * get the alignment of the rows: SO format com.sun.star.text.HoriOrientation + * is mapped to WdRowAlignment in Word + * @return the alignment + */ +::sal_Int32 SAL_CALL SwVbaRows::getAlignment() +{ + sal_Int16 nAlignment = text::HoriOrientation::LEFT; + uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW ); + xTableProps->getPropertyValue("HoriOrient") >>= nAlignment; + sal_Int32 nRet = 0; + switch( nAlignment ) + { + case text::HoriOrientation::CENTER: + { + nRet = word::WdRowAlignment::wdAlignRowCenter; + break; + } + case text::HoriOrientation::RIGHT: + { + nRet = word::WdRowAlignment::wdAlignRowRight; + break; + } + default: + { + nRet = word::WdRowAlignment::wdAlignRowLeft; + } + } + return nRet; +} + +void SAL_CALL SwVbaRows::setAlignment( ::sal_Int32 _alignment ) +{ + sal_Int16 nAlignment = text::HoriOrientation::LEFT; + switch( _alignment ) + { + case word::WdRowAlignment::wdAlignRowCenter: + { + nAlignment = text::HoriOrientation::CENTER; + break; + } + case word::WdRowAlignment::wdAlignRowRight: + { + nAlignment = text::HoriOrientation::RIGHT; + break; + } + default: + { + nAlignment = text::HoriOrientation::LEFT; + } + } + uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW ); + xTableProps->setPropertyValue("HoriOrient", uno::Any( nAlignment ) ); +} + +uno::Any SAL_CALL SwVbaRows::getAllowBreakAcrossPages() +{ + bool bAllowBreak = false; + uno::Reference< container::XIndexAccess > xRowsAccess( mxTableRows, uno::UNO_QUERY_THROW ); + for( sal_Int32 index = mnStartRowIndex; index <= mnEndRowIndex; ++index ) + { + uno::Reference< beans::XPropertySet > xRowProps( xRowsAccess->getByIndex( index ), uno::UNO_QUERY_THROW ); + bool bSplit = false; + xRowProps->getPropertyValue("IsSplitAllowed") >>= bSplit; + if( index == 0 ) + { + bAllowBreak = bSplit; + } + if( bSplit != bAllowBreak ) + { + return uno::Any( sal_Int32(word::WdConstants::wdUndefined) ); + } + } + return uno::Any( bAllowBreak ); +} + +void SAL_CALL SwVbaRows::setAllowBreakAcrossPages( const uno::Any& _allowbreakacrosspages ) +{ + bool bAllowBreak = false; + _allowbreakacrosspages >>= bAllowBreak; + uno::Reference< container::XIndexAccess > xRowsAccess( mxTableRows, uno::UNO_QUERY_THROW ); + for( sal_Int32 index = mnStartRowIndex; index <= mnEndRowIndex; ++index ) + { + uno::Reference< beans::XPropertySet > xRowProps( xRowsAccess->getByIndex( index ), uno::UNO_QUERY_THROW ); + xRowProps->setPropertyValue("IsSplitAllowed", uno::Any( bAllowBreak ) ); + } +} + +float SAL_CALL SwVbaRows::getSpaceBetweenColumns() +{ + // just get the first spacing of the first cell + uno::Reference< table::XCellRange > xCellRange( mxTextTable, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xCellProps( xCellRange->getCellByPosition( 0, mnStartRowIndex ), uno::UNO_QUERY_THROW ); + sal_Int32 nLeftBorderDistance = 0; + sal_Int32 nRightBorderDistance = 0; + xCellProps->getPropertyValue("LeftBorderDistance") >>= nLeftBorderDistance; + xCellProps->getPropertyValue("RightBorderDistance") >>= nRightBorderDistance; + return static_cast< float >( Millimeter::getInPoints( nLeftBorderDistance + nRightBorderDistance ) ); +} + +void SAL_CALL SwVbaRows::setSpaceBetweenColumns( float _spacebetweencolumns ) +{ + sal_Int32 nSpace = Millimeter::getInHundredthsOfOneMillimeter( _spacebetweencolumns ) / 2; + uno::Reference< container::XIndexAccess > xColumnAccess( mxTextTable->getColumns(), uno::UNO_QUERY_THROW ); + uno::Reference< table::XCellRange > xCellRange( mxTextTable, uno::UNO_QUERY_THROW ); + SwVbaTableHelper aTableHelper( mxTextTable ); + for( sal_Int32 row = mnStartRowIndex; row <= mnEndRowIndex; ++row ) + { + sal_Int32 nColumns = aTableHelper.getTabColumnsCount( row ); + for( sal_Int32 column = 0; column < nColumns; ++column ) + { + uno::Reference< beans::XPropertySet > xCellProps( xCellRange->getCellByPosition( column, row ), uno::UNO_QUERY_THROW ); + xCellProps->setPropertyValue("LeftBorderDistance", uno::Any( nSpace ) ); + xCellProps->setPropertyValue("RightBorderDistance", uno::Any( nSpace ) ); + } + } +} + +void SAL_CALL SwVbaRows::Delete( ) +{ + mxTableRows->removeByIndex( mnStartRowIndex, getCount() ); +} + +void SAL_CALL SwVbaRows::SetLeftIndent( float LeftIndent, ::sal_Int32 RulerStyle ) +{ + uno::Reference< word::XColumns > xColumns( new SwVbaColumns( getParent(), mxContext, mxTextTable, mxTextTable->getColumns() ) ); + sal_Int32 nIndent = static_cast<sal_Int32>(LeftIndent); + switch( RulerStyle ) + { + case word::WdRulerStyle::wdAdjustFirstColumn: + { + setIndentWithAdjustFirstColumn( xColumns, nIndent ); + break; + } + case word::WdRulerStyle::wdAdjustNone: + { + setIndentWithAdjustNone( nIndent ); + break; + } + case word::WdRulerStyle::wdAdjustProportional: + { + setIndentWithAdjustProportional( xColumns, nIndent ); + break; + } + case word::WdRulerStyle::wdAdjustSameWidth: + { + setIndentWithAdjustSameWidth( xColumns, nIndent ); + break; + } + default: + { + DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_ARGUMENT); + } + } +} + +void SwVbaRows::setIndentWithAdjustNone( sal_Int32 indent ) +{ + uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW ); + sal_Int32 nMargin = 0; + xTableProps->getPropertyValue("LeftMargin") >>= nMargin; + nMargin += indent; + xTableProps->setPropertyValue("LeftMargin", uno::Any( nMargin ) ); +} + + void SwVbaRows::setIndentWithAdjustFirstColumn( const uno::Reference< word::XColumns >& xColumns, sal_Int32 indent ) + { + uno::Reference< XCollection > xCol( xColumns, uno::UNO_QUERY_THROW ); + uno::Reference< word::XColumn > xColumn( xCol->Item( uno::Any( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW ); + sal_Int32 nWidth = xColumn->getWidth(); + nWidth -= indent; + xColumn->setWidth( nWidth ); + setIndentWithAdjustNone( indent ); + } + + void SwVbaRows::setIndentWithAdjustProportional( + const uno::Reference< word::XColumns >& xColumns, + sal_Int32 indent +) + { + // calculate the new width and get the proportion between old and new + uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW ); + sal_Int32 nWidth = 0; + xTableProps->getPropertyValue("Width") >>= nWidth; + sal_Int32 nNewWidth = nWidth - indent; + if ((nNewWidth <= 0) || (nWidth <= 0)) + { + throw uno::RuntimeException( + "Pb with width, in SwVbaRows::setIndentWithAdjustProportional " + "(nNewWidth <= 0) || (nWidth <= 0)" + ); + } + double propFactor = static_cast<double>(nNewWidth)/static_cast<double>(nWidth); + + // get all columns, calculate and set the new width of the columns + uno::Reference< XCollection > xCol( xColumns, uno::UNO_QUERY_THROW ); + sal_Int32 nColCount = xCol->getCount(); + for( sal_Int32 i = 0; i < nColCount; i++ ) + { + uno::Reference< word::XColumn > xColumn( xCol->Item( uno::Any( i ), uno::Any() ), uno::UNO_QUERY_THROW ); + sal_Int32 nColWidth = xColumn->getWidth(); + sal_Int32 nNewColWidth = static_cast<sal_Int32>( propFactor * nColWidth ); + xColumn->setWidth( nNewColWidth ); + } + + // set the width and position of the table + setIndentWithAdjustNone( indent ); + xTableProps->setPropertyValue("Width", uno::Any( nNewWidth ) ); + } + + void SwVbaRows::setIndentWithAdjustSameWidth( const uno::Reference< word::XColumns >& xColumns, sal_Int32 indent ) + { + // calculate the new width and get the width of all columns + uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW ); + sal_Int32 nWidth = 0; + xTableProps->getPropertyValue("Width") >>= nWidth; + sal_Int32 nNewWidth = nWidth - indent; + + // get all columns, calculate and set the new width of the columns + uno::Reference< XCollection > xCol( xColumns, uno::UNO_QUERY_THROW ); + sal_Int32 nColCount = xCol->getCount(); + sal_Int32 nNewColWidth = static_cast<sal_Int32>( double( nNewWidth )/nColCount ); + for( sal_Int32 i = 0; i < nColCount; i++ ) + { + uno::Reference< word::XColumn > xColumn( xCol->Item( uno::Any( i ), uno::Any() ), uno::UNO_QUERY_THROW ); + xColumn->setWidth( nNewColWidth ); + } + + // set the width and position of the table + setIndentWithAdjustNone( indent ); + xTableProps->setPropertyValue("Width", uno::Any( nNewWidth ) ); + } + +void SAL_CALL SwVbaRows::Select( ) +{ + SwVbaRow::SelectRow( getCurrentWordDoc(mxContext), mxTextTable, mnStartRowIndex, mnEndRowIndex ); +} + +::sal_Int32 SAL_CALL SwVbaRows::getCount() +{ + return ( mnEndRowIndex - mnStartRowIndex + 1 ); +} + +uno::Any SAL_CALL SwVbaRows::Item( const uno::Any& Index1, const uno::Any& /*not processed in this base class*/ ) +{ + sal_Int32 nIndex = 0; + if( Index1 >>= nIndex ) + { + if( nIndex <= 0 || nIndex > getCount() ) + { + throw lang::IndexOutOfBoundsException("Index out of bounds" ); + } + return uno::Any( uno::Reference< word::XRow >( new SwVbaRow( this, mxContext, mxTextTable, nIndex - 1 ) ) ); + } + throw uno::RuntimeException("Index out of bounds" ); +} + +// XEnumerationAccess +uno::Type +SwVbaRows::getElementType() +{ + return cppu::UnoType<word::XRow>::get(); +} +uno::Reference< container::XEnumeration > +SwVbaRows::createEnumeration() +{ + return new RowsEnumWrapper( this, mxContext, mxTextTable ); +} + +uno::Any +SwVbaRows::createCollectionObject( const uno::Any& aSource ) +{ + return aSource; +} + +OUString +SwVbaRows::getServiceImplName() +{ + return "SwVbaRows"; +} + +uno::Sequence<OUString> +SwVbaRows::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.Rows" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbarows.hxx b/sw/source/ui/vba/vbarows.hxx new file mode 100644 index 0000000000..98a1069fa8 --- /dev/null +++ b/sw/source/ui/vba/vbarows.hxx @@ -0,0 +1,82 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAROWS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAROWS_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XRows.hpp> +#include <ooo/vba/word/XColumns.hpp> +#include <com/sun/star/table/XTableRows.hpp> +#include <com/sun/star/text/XTextTable.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XRows > SwVbaRows_BASE; + +class SwVbaRows : public SwVbaRows_BASE +{ +private: + css::uno::Reference< css::text::XTextTable > mxTextTable; + css::uno::Reference< css::table::XTableRows > mxTableRows; + sal_Int32 mnStartRowIndex; + sal_Int32 mnEndRowIndex; + +private: + /// @throws css::uno::RuntimeException + void setIndentWithAdjustNone( sal_Int32 indent ); + /// @throws css::uno::RuntimeException + void setIndentWithAdjustFirstColumn( const css::uno::Reference< ooo::vba::word::XColumns >& xColumns, sal_Int32 indent ); + /// @throws css::uno::RuntimeException + void setIndentWithAdjustProportional( const css::uno::Reference< ooo::vba::word::XColumns >& xColumns, sal_Int32 indent ); + /// @throws css::uno::RuntimeException + void setIndentWithAdjustSameWidth( const css::uno::Reference< ooo::vba::word::XColumns >& xColumns, sal_Int32 indent ); + +public: + /// @throws css::uno::RuntimeException + SwVbaRows( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::text::XTextTable > xTextTable, const css::uno::Reference< css::table::XTableRows >& xTableRows ); + /// @throws css::uno::RuntimeException + SwVbaRows( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::text::XTextTable > xTextTable, const css::uno::Reference< css::table::XTableRows >& xTableRows, sal_Int32 nStarIndex, sal_Int32 nEndIndex ); + + // Attributes + virtual ::sal_Int32 SAL_CALL getAlignment() override; + virtual void SAL_CALL setAlignment( ::sal_Int32 _alignment ) override; + virtual css::uno::Any SAL_CALL getAllowBreakAcrossPages() override; + virtual void SAL_CALL setAllowBreakAcrossPages( const css::uno::Any& _allowbreakacrosspages ) override; + virtual float SAL_CALL getSpaceBetweenColumns() override; + virtual void SAL_CALL setSpaceBetweenColumns( float _spacebetweencolumns ) override; + + // Methods + virtual void SAL_CALL Delete( ) override; + virtual void SAL_CALL SetLeftIndent( float LeftIndent, ::sal_Int32 RulerStyle ) override; + virtual void SAL_CALL Select( ) override; + + //XCollection + virtual ::sal_Int32 SAL_CALL getCount() override; + virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& /*not processed in this base class*/ ) override; + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaRows_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAROWS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbasection.cxx b/sw/source/ui/vba/vbasection.cxx new file mode 100644 index 0000000000..40ecdaabd5 --- /dev/null +++ b/sw/source/ui/vba/vbasection.cxx @@ -0,0 +1,84 @@ +/* -*- 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 "vbasection.hxx" +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include "vbapagesetup.hxx" +#include "vbaheadersfooters.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaSection::SwVbaSection( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< frame::XModel > xModel, uno::Reference< beans::XPropertySet > xProps ) : + SwVbaSection_BASE( rParent, rContext ), mxModel(std::move( xModel )), mxPageProps(std::move( xProps )) +{ +} + +SwVbaSection::~SwVbaSection() +{ +} + +sal_Bool SAL_CALL SwVbaSection::getProtectedForForms() +{ + return false; +} + +void SAL_CALL SwVbaSection::setProtectedForForms( sal_Bool /*_protectedforforms*/ ) +{ +} + +uno::Any SAL_CALL SwVbaSection::Headers( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaHeadersFooters( this, mxContext, mxModel, mxPageProps, true ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL SwVbaSection::Footers( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaHeadersFooters( this, mxContext, mxModel, mxPageProps, false ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaSection::PageSetup( ) +{ + return uno::Any( uno::Reference< word::XPageSetup >( new SwVbaPageSetup( this, mxContext, mxModel, mxPageProps ) ) ); +} + +OUString +SwVbaSection::getServiceImplName() +{ + return "SwVbaSection"; +} + +uno::Sequence< OUString > +SwVbaSection::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Section" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbasection.hxx b/sw/source/ui/vba/vbasection.hxx new file mode 100644 index 0000000000..9a1b927424 --- /dev/null +++ b/sw/source/ui/vba/vbasection.hxx @@ -0,0 +1,53 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBASECTION_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBASECTION_HXX + +#include <ooo/vba/word/XSection.hpp> +#include <vbahelper/vbahelperinterface.hxx> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XSection > SwVbaSection_BASE; + +class SwVbaSection : public SwVbaSection_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::beans::XPropertySet > mxPageProps; + +public: + /// @throws css::uno::RuntimeException + SwVbaSection( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::frame::XModel > xModel, css::uno::Reference< css::beans::XPropertySet > xProps ); + virtual ~SwVbaSection() override; + + // Attributes + virtual sal_Bool SAL_CALL getProtectedForForms() override; + virtual void SAL_CALL setProtectedForForms( sal_Bool _protectedforforms ) override; + + // Methods + virtual css::uno::Any SAL_CALL Headers( const css::uno::Any& index ) override; + virtual css::uno::Any SAL_CALL Footers( const css::uno::Any& index ) override; + virtual css::uno::Any SAL_CALL PageSetup( ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBASECTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbasections.cxx b/sw/source/ui/vba/vbasections.cxx new file mode 100644 index 0000000000..fe9315ebf6 --- /dev/null +++ b/sw/source/ui/vba/vbasections.cxx @@ -0,0 +1,195 @@ +/* -*- 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 "vbasections.hxx" +#include "vbasection.hxx" +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/style/XStyle.hpp> +#include "wordvbahelper.hxx" +#include <cppuhelper/implbase.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +typedef std::vector< uno::Reference< beans::XPropertySet > > XSectionVec; + +namespace { + +class SectionEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration > +{ + XSectionVec mxSections; + XSectionVec::iterator mIt; + +public: + explicit SectionEnumeration( XSectionVec&& rVec ) : mxSections( std::move(rVec) ), mIt( mxSections.begin() ) {} + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( mIt != mxSections.end() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( hasMoreElements() ) + return uno::Any( *mIt++ ); + throw container::NoSuchElementException(); + } +}; + +// here I regard pagestyle as section +class SectionCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess, + container::XEnumerationAccess > +{ +private: + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< frame::XModel > mxModel; + XSectionVec mxSections; + +public: + /// @throws uno::RuntimeException + SectionCollectionHelper( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxModel(std::move( xModel )) + { + uno::Reference< style::XStyleFamiliesSupplier > xSytleFamSupp( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameAccess > xSytleFamNames( xSytleFamSupp->getStyleFamilies(), uno::UNO_SET_THROW ); + uno::Reference< container::XIndexAccess > xPageStyles( xSytleFamNames->getByName("PageStyles"), uno::UNO_QUERY_THROW ); + sal_Int32 nCount = xPageStyles->getCount(); + for( sal_Int32 index = 0; index < nCount; ++index ) + { + uno::Reference< style::XStyle > xStyle( xPageStyles->getByIndex( index ), uno::UNO_QUERY_THROW ); + // only the pagestyles in using are considered + if( xStyle->isInUse( ) ) + { + uno::Reference< beans::XPropertySet > xPageProps( xStyle, uno::UNO_QUERY_THROW ); + mxSections.push_back( xPageProps ); + } + } + } + + /// @throws uno::RuntimeException + SectionCollectionHelper( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel, const uno::Reference< text::XTextRange >& xTextRange ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxModel(std::move( xModel )) + { + // Hacky implementation of Range.Sections, only support 1 section + uno::Reference< beans::XPropertySet > xRangeProps( xTextRange, uno::UNO_QUERY_THROW ); + uno::Reference< style::XStyle > xStyle = word::getCurrentPageStyle( mxModel, xRangeProps ); + uno::Reference< beans::XPropertySet > xPageProps( xStyle, uno::UNO_QUERY_THROW ); + mxSections.push_back( xPageProps ); + } + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount( ) override + { + return mxSections.size(); + } + virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override + { + if ( Index < 0 || Index >= getCount() ) + throw css::lang::IndexOutOfBoundsException(); + + uno::Reference< beans::XPropertySet > xPageProps( mxSections[ Index ], uno::UNO_SET_THROW ); + return uno::Any( uno::Reference< word::XSection >( new SwVbaSection( mxParent, mxContext, mxModel, xPageProps ) ) ); + } + virtual uno::Type SAL_CALL getElementType( ) override + { + return cppu::UnoType<word::XSection>::get(); + } + virtual sal_Bool SAL_CALL hasElements( ) override + { + return true; + } + // XEnumerationAccess + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override + { + return new SectionEnumeration( std::vector(mxSections) ); + } +}; + +class SectionsEnumWrapper : public EnumerationHelperImpl +{ + uno::Reference< frame::XModel > mxModel; +public: + /// @throws uno::RuntimeException + SectionsEnumWrapper( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, uno::Reference< frame::XModel > xModel ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mxModel(std::move( xModel )){} + + virtual uno::Any SAL_CALL nextElement( ) override + { + uno::Reference< beans::XPropertySet > xPageProps( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< word::XSection > ( new SwVbaSection( m_xParent, m_xContext, mxModel, xPageProps ) ) ); + } +}; + +} + +SwVbaSections::SwVbaSections( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel ): SwVbaSections_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new SectionCollectionHelper( xParent, xContext, xModel ) ) ), mxModel( xModel ) +{ +} + +SwVbaSections::SwVbaSections( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextRange >& xTextRange ): SwVbaSections_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new SectionCollectionHelper( xParent, xContext, xModel, xTextRange ) ) ), mxModel( xModel ) +{ +} + +uno::Any SAL_CALL +SwVbaSections::PageSetup( ) +{ + if( m_xIndexAccess->getCount() ) + { + // check if the first section is our want + uno::Reference< word::XSection > xSection( m_xIndexAccess->getByIndex( 0 ), uno::UNO_QUERY_THROW ); + return xSection->PageSetup(); + } + throw uno::RuntimeException("There is no section" ); +} + +// XEnumerationAccess +uno::Type SAL_CALL +SwVbaSections::getElementType() +{ + return cppu::UnoType<word::XSection>::get(); +} + +uno::Reference< container::XEnumeration > SAL_CALL +SwVbaSections::createEnumeration() +{ + uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); + return new SectionsEnumWrapper( this, mxContext, xEnumAccess->createEnumeration(), mxModel ); +} + +uno::Any +SwVbaSections::createCollectionObject( const css::uno::Any& aSource ) +{ + return aSource; +} + +OUString +SwVbaSections::getServiceImplName() +{ + return "SwVbaSections"; +} + +css::uno::Sequence<OUString> +SwVbaSections::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.Sections" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbasections.hxx b/sw/source/ui/vba/vbasections.hxx new file mode 100644 index 0000000000..3bf3ab4ca3 --- /dev/null +++ b/sw/source/ui/vba/vbasections.hxx @@ -0,0 +1,51 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBASECTIONS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBASECTIONS_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XSections.hpp> +#include <com/sun/star/text/XTextRange.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XSections > SwVbaSections_BASE; + +class SwVbaSections : public SwVbaSections_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + +public: + SwVbaSections( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel ); + SwVbaSections( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextRange >& xTextRange ); + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + virtual css::uno::Any SAL_CALL PageSetup( ) override; + + // SwVbaSections_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBASECTIONS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaselection.cxx b/sw/source/ui/vba/vbaselection.cxx new file mode 100644 index 0000000000..d983bd2bd2 --- /dev/null +++ b/sw/source/ui/vba/vbaselection.cxx @@ -0,0 +1,1169 @@ +/* -*- 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 "vbaselection.hxx" +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include "vbarange.hxx" +#include "vbafind.hxx" +#include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/text/XTextTable.hpp> +#include <com/sun/star/text/XTextTableCursor.hpp> +#include <com/sun/star/table/XCell.hpp> +#include <basic/sberrors.hxx> +#include <ooo/vba/word/WdUnits.hpp> +#include <ooo/vba/word/WdMovementType.hpp> +#include <ooo/vba/word/WdGoToItem.hpp> +#include <ooo/vba/word/WdGoToDirection.hpp> +#include <ooo/vba/word/XBookmark.hpp> +#include <ooo/vba/word/XApplication.hpp> +#include <ooo/vba/word/WdCollapseDirection.hpp> +#include <com/sun/star/text/XPageCursor.hpp> +#include <unotbl.hxx> +#include <unocoll.hxx> +#include "vbatable.hxx" +#include <com/sun/star/view/XViewCursor.hpp> +#include <com/sun/star/view/XLineCursor.hpp> +#include <com/sun/star/text/XWordCursor.hpp> +#include <com/sun/star/text/XParagraphCursor.hpp> +#include <ooo/vba/word/WdInformation.hpp> +#include <ooo/vba/word/WdHeaderFooterIndex.hpp> +#include <ooo/vba/word/WdSeekView.hpp> +#include "vbainformationhelper.hxx" +#include "vbafield.hxx" +#include "vbaheaderfooter.hxx" +#include "vbaheaderfooterhelper.hxx" +#include <vbahelper/vbashaperange.hxx> +#include <com/sun/star/drawing/ShapeCollection.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> +#include "vbarows.hxx" +#include "vbacolumns.hxx" +#include "vbatablehelper.hxx" +#include "vbacells.hxx" +#include "vbaview.hxx" +#include "vbaparagraph.hxx" +#include "vbastyle.hxx" +#include <docsh.hxx> +#include <tblenum.hxx> +#include <sal/log.hxx> +#include <fesh.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaSelection::SwVbaSelection( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< frame::XModel > xModel ) : SwVbaSelection_BASE( rParent, rContext ), mxModel(std::move( xModel )) +{ + mxTextViewCursor = word::getXTextViewCursor( mxModel ); +} + +SwVbaSelection::~SwVbaSelection() +{ +} + +uno::Reference< text::XTextRange > SwVbaSelection::GetSelectedRange() +{ + uno::Reference< text::XTextRange > xTextRange; + uno::Reference< lang::XServiceInfo > xServiceInfo( mxModel->getCurrentSelection(), uno::UNO_QUERY_THROW ); + if( !xServiceInfo->supportsService("com.sun.star.text.TextRanges") ) + { + throw uno::RuntimeException("Not implemented" ); + } + + uno::Reference< container::XIndexAccess > xTextRanges( xServiceInfo, uno::UNO_QUERY_THROW ); + if( xTextRanges->getCount() > 0 ) + { + // if there are multiple selection, just return the last selected Range. + xTextRange.set( xTextRanges->getByIndex( xTextRanges->getCount()-1 ), uno::UNO_QUERY_THROW ); + } + + return xTextRange; +} + +uno::Reference< word::XRange > SAL_CALL +SwVbaSelection::getRange() +{ + uno::Reference< text::XTextRange > xTextRange = GetSelectedRange(); + uno::Reference< text::XTextDocument > xDocument( mxModel, uno::UNO_QUERY_THROW ); + return uno::Reference< word::XRange >( new SwVbaRange( this, mxContext, xDocument, xTextRange->getStart(), xTextRange->getEnd(), mxTextViewCursor->getText() ) ); +} + +OUString SAL_CALL +SwVbaSelection::getText() +{ + return getRange()->getText(); +} + +void SAL_CALL +SwVbaSelection::setText( const OUString& rText ) +{ + getRange()->setText( rText ); +} + +void SAL_CALL +SwVbaSelection::TypeText( const OUString& rText ) +{ + // FIXME: handle the property Options.ReplaceSelection, the default value is true + setText( rText ); +} + +void SAL_CALL +SwVbaSelection::HomeKey( const uno::Any& _unit, const uno::Any& _extend ) +{ + sal_Int32 nUnit = word::WdUnits::wdLine; + sal_Int32 nExtend = word::WdMovementType::wdMove; + _unit >>= nUnit; + _extend >>= nExtend; + bool bExtend = nExtend == word::WdMovementType::wdExtend; + + switch( nUnit ) + { + case word::WdUnits::wdStory: + { + // go to the valid text first so that the current view cursor is valid to call gotoRange. + word::gotoSelectedObjectAnchor(mxModel); + // go to the begin of the document + uno::Reference< text::XText > xCurrentText = word::getCurrentXText( mxModel ); + uno::Reference< text::XTextRange > xFirstRange = word::getFirstObjectPosition( xCurrentText ); + mxTextViewCursor->gotoRange( xFirstRange, bExtend ); + break; + } + case word::WdUnits::wdLine: + { + // go to the begin of the Line + uno::Reference< view::XLineCursor > xLineCursor( mxTextViewCursor, uno::UNO_QUERY_THROW ); + xLineCursor->gotoStartOfLine( bExtend ); + break; + } + default: + { + throw uno::RuntimeException("Not implemented" ); + } + } +} + +void SAL_CALL +SwVbaSelection::EndKey( const uno::Any& _unit, const uno::Any& _extend ) +{ + sal_Int32 nUnit = word::WdUnits::wdLine; + sal_Int32 nExtend = word::WdMovementType::wdMove; + _unit >>= nUnit; + _extend >>= nExtend; + bool bExtend = nExtend == word::WdMovementType::wdExtend; + + switch( nUnit ) + { + case word::WdUnits::wdStory: + { + // go to the valid text first so that the current view cursor is valid to call gotoRange. + word::gotoSelectedObjectAnchor(mxModel); + // go to the end of the document + uno::Reference< text::XText > xCurrentText = word::getCurrentXText( mxModel ); + uno::Reference< text::XTextRange > xEnd = xCurrentText->getEnd(); + mxTextViewCursor->gotoRange( xEnd, bExtend ); + break; + } + case word::WdUnits::wdLine: + { + // go to the end of the Line + uno::Reference< view::XLineCursor > xLineCursor( mxTextViewCursor, uno::UNO_QUERY_THROW ); + xLineCursor->gotoEndOfLine( bExtend ); + break; + } + default: + { + throw uno::RuntimeException("Not implemented" ); + } + } +} + +void SAL_CALL +SwVbaSelection::Delete( const uno::Any& _unit, const uno::Any& _count ) +{ + sal_Int32 nUnit = word::WdUnits::wdLine; + sal_Int32 nCount = 0; + if( _count.hasValue() ) + _count >>= nCount; + if( _unit.hasValue() && ( nCount > 0 ) ) + { + _unit >>= nUnit; + switch( nUnit ) + { + case word::WdUnits::wdCharacter: + { + if( HasSelection() ) + nCount--; + mxTextViewCursor->goRight( nCount, true ); + break; + } + default: + { + throw uno::RuntimeException("Not implemented" ); + } + } + } + dispatchRequests( mxModel,".uno:Delete" ); +} + +void +SwVbaSelection::Move( const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend, word::E_DIRECTION eDirection ) +{ + sal_Int32 nUnit = word::WdUnits::wdCharacter; + sal_Int32 nCount = 1; + sal_Int32 nExtend = word::WdMovementType::wdMove; + + if( _unit.hasValue() ) + _unit >>= nUnit; + if( _count.hasValue() ) + _count >>= nCount; + if( _extend.hasValue() ) + _extend >>= nExtend; + + if( nCount == 0 ) + return; + + bool bExpand = nExtend != word::WdMovementType::wdMove; + + switch( nUnit ) + { + case word::WdUnits::wdCell: + { + if( nExtend == word::WdMovementType::wdExtend ) + { + DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {}); + return; + } + NextCell( nCount, eDirection ); + break; + } + case word::WdUnits::wdLine: + { + if( eDirection == word::MOVE_LEFT || eDirection == word::MOVE_RIGHT ) + { + throw uno::RuntimeException("Not implemented" ); + } + uno::Reference< view::XViewCursor > xViewCursor( mxTextViewCursor, uno::UNO_QUERY_THROW ); + if( eDirection == word::MOVE_UP ) + xViewCursor->goUp( nCount, bExpand ); + else if( eDirection == word::MOVE_DOWN ) + xViewCursor->goDown( nCount, bExpand ); + break; + } + case word::WdUnits::wdCharacter: + { + if( eDirection == word::MOVE_UP || eDirection == word::MOVE_DOWN ) + { + throw uno::RuntimeException("Not implemented" ); + } + if( word::gotoSelectedObjectAnchor( mxModel ) ) + { + nCount--; + } + uno::Reference< view::XViewCursor > xViewCursor( mxTextViewCursor, uno::UNO_QUERY_THROW ); + if( eDirection == word::MOVE_LEFT ) + { + // if current select is a cellrange or table, + // the first count of move should move to the first selected cell. + uno::Reference< text::XTextTableCursor > xTextTableCursor( mxModel->getCurrentSelection(), uno::UNO_QUERY ); + if ( xTextTableCursor.is() ) + { + uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextTable > xTextTable; + xCursorProps->getPropertyValue("TextTable") >>= xTextTable; + if( xTextTable.is() ) + { + uno::Reference< text::XTextRange > xRange( xTextTable->getCellByName( xTextTableCursor->getRangeName()), uno::UNO_QUERY_THROW ); + mxTextViewCursor->gotoRange( xRange->getStart(), bExpand ); + nCount--; + } + } + xViewCursor->goLeft( nCount, bExpand ); + } + else if( eDirection == word::MOVE_RIGHT ) + xViewCursor->goRight( nCount, bExpand ); + break; + } + case word::WdUnits::wdWord: + case word::WdUnits::wdParagraph: + { + uno::Reference< text::XTextRange > xRange = GetSelectedRange(); + uno::Reference< text::XText > xText = xRange->getText(); + uno::Reference< text::XTextCursor > xTextCursor = xText->createTextCursorByRange( xRange ); + if( nUnit == word::WdUnits::wdParagraph ) + { + if( eDirection == word::MOVE_LEFT || eDirection == word::MOVE_RIGHT ) + { + throw uno::RuntimeException("Not implemented" ); + } + uno::Reference< text::XParagraphCursor > xParagraphCursor( xTextCursor, uno::UNO_QUERY_THROW ); + for( sal_Int32 i=0; i<nCount; i++ ) + { + if( ( eDirection == word::MOVE_UP ) && !xParagraphCursor->gotoPreviousParagraph( bExpand ) ) + break; + else if( ( eDirection == word::MOVE_DOWN ) && !xParagraphCursor->gotoNextParagraph( bExpand ) ) + break; + } + } + else if( nUnit == word::WdUnits::wdWord ) + { + if( eDirection == word::MOVE_UP || eDirection == word::MOVE_DOWN ) + { + throw uno::RuntimeException("Not implemented" ); + } + uno::Reference< text::XWordCursor > xWordCursor( xTextCursor, uno::UNO_QUERY_THROW ); + for( sal_Int32 i=0; i<nCount; i++ ) + { + if( (eDirection == word::MOVE_LEFT ) && !xWordCursor->gotoPreviousWord( bExpand ) ) + break; + else if( ( eDirection == word::MOVE_RIGHT ) && !xWordCursor->gotoNextWord( bExpand ) ) + break; + } + } + mxTextViewCursor->gotoRange( xTextCursor->getStart(), false ); + mxTextViewCursor->gotoRange( xTextCursor->getEnd(), true ); + break; + } + default: + { + throw uno::RuntimeException("Not implemented" ); + } + } +} + +void SwVbaSelection::NextCell(sal_Int32 nCount, word::E_DIRECTION eDirection) +{ + uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextTable > xTextTable; + uno::Reference< table::XCell > xCell; + xCursorProps->getPropertyValue("TextTable") >>= xTextTable; + xCursorProps->getPropertyValue("Cell") >>= xCell; + if( !xTextTable.is() || !xCell.is() ) + { + DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {}); + return; + } + uno::Reference< beans::XPropertySet > xCellProps( xCell, uno::UNO_QUERY_THROW ); + OUString aCellName; + xCellProps->getPropertyValue("CellName") >>= aCellName; + uno::Reference< text::XTextTableCursor > xTextTableCursor = xTextTable->createCursorByCellName( aCellName ); + // move the table cursor + switch( eDirection ) + { + case word::MOVE_LEFT: + { + xTextTableCursor->goLeft( nCount, false ); + break; + } + case word::MOVE_RIGHT: + { + xTextTableCursor->goRight( nCount, false ); + break; + } + case word::MOVE_UP: + { + xTextTableCursor->goUp( nCount, false ); + break; + } + case word::MOVE_DOWN: + { + xTextTableCursor->goDown( nCount, false ); + break; + } + default: + { + DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {}); + return; + } + } + // move the view cursor + xCell = xTextTable->getCellByName( xTextTableCursor->getRangeName() ); + mxTextViewCursor->gotoRange( uno::Reference< text::XTextRange >( xCell, uno::UNO_QUERY_THROW ), false ); +} + +void SAL_CALL +SwVbaSelection::MoveRight(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend) +{ + sal_Int32 nCount = 1; + + if( _count.hasValue() ) + _count >>= nCount; + + if( nCount == 0 ) + return; + + if( nCount < 0 ) + { + MoveLeft( _unit, uno::Any( -nCount ), _extend ); + return; + } + + Move( _unit, _count, _extend, word::MOVE_RIGHT ); +} + +void SAL_CALL +SwVbaSelection::MoveLeft(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend) +{ + sal_Int32 nCount = 1; + if( _count.hasValue() ) + _count >>= nCount; + + if( nCount == 0 ) + return; + + if( nCount < 0 ) + { + MoveRight( _unit, uno::Any( -nCount ), _extend ); + return; + } + + Move( _unit, _count, _extend, word::MOVE_LEFT ); +} + +void SAL_CALL +SwVbaSelection::MoveDown(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend) +{ + sal_Int32 nCount = 1; + + if( _count.hasValue() ) + _count >>= nCount; + + if( nCount == 0 ) + return; + + if( nCount < 0 ) + { + MoveUp( _unit, uno::Any( -nCount ), _extend ); + return; + } + + Move( _unit, _count, _extend, word::MOVE_DOWN ); +} + +void SAL_CALL +SwVbaSelection::MoveUp(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend) +{ + sal_Int32 nCount = 1; + + if( _count.hasValue() ) + _count >>= nCount; + + if( nCount == 0 ) + return; + + if( nCount < 0 ) + { + MoveDown( _unit, uno::Any( -nCount ), _extend ); + return; + } + + Move( _unit, _count, _extend, word::MOVE_UP ); +} + +void SAL_CALL +SwVbaSelection::TypeParagraph() +{ + // #FIXME: if the selection is an entire paragraph, it's replaced + // by the new paragraph + bool isCollapsed = mxTextViewCursor->isCollapsed(); + InsertParagraph(); + if( isCollapsed ) + mxTextViewCursor->collapseToStart(); +} + +void SAL_CALL +SwVbaSelection::InsertParagraph() +{ + // #FIXME: the selection should include the new paragraph. + getRange()->InsertParagraph(); +} + +void SAL_CALL +SwVbaSelection::InsertParagraphBefore() +{ + getRange()->InsertParagraphBefore(); +} + +void SAL_CALL +SwVbaSelection::InsertParagraphAfter() +{ + getRange()->InsertParagraphAfter(); +} + +uno::Reference< word::XParagraphFormat > SAL_CALL +SwVbaSelection::getParagraphFormat() +{ + return getRange()->getParagraphFormat(); +} + +void SAL_CALL +SwVbaSelection::setParagraphFormat( const uno::Reference< word::XParagraphFormat >& rParagraphFormat ) +{ + return getRange()->setParagraphFormat( rParagraphFormat ); +} + +uno::Reference< word::XFind > SAL_CALL +SwVbaSelection::getFind() +{ + uno::Reference< text::XTextRange > xTextRange = GetSelectedRange(); + uno::Reference< text::XTextRange > xStart = xTextRange->getStart(); + uno::Reference< text::XTextRange > xEnd = xTextRange->getEnd(); + uno::Reference< text::XTextRangeCompare > xTRC( xTextRange->getText(), uno::UNO_QUERY_THROW ); + int n = xTRC->compareRegionStarts( xStart, xEnd); + if( n == 0 ) + { + WholeStory(); + xTextRange = GetSelectedRange(); + } + return SwVbaFind::GetOrCreateFind(this, mxContext, mxModel, xTextRange); +} + +uno::Any SAL_CALL +SwVbaSelection::getStyle() +{ + return getRange()->getStyle(); +} + +void SAL_CALL +SwVbaSelection::setStyle( const uno::Any& rStyle ) +{ + uno::Reference< beans::XPropertySet > xParaProps( mxTextViewCursor, uno::UNO_QUERY_THROW ); + return SwVbaStyle::setStyle( xParaProps, rStyle ); +} + +uno::Reference< word::XFont > SAL_CALL +SwVbaSelection::getFont() +{ + return getRange()->getFont(); +} + +void SAL_CALL +SwVbaSelection::TypeBackspace() +{ + dispatchRequests( mxModel,".uno:SwBackspace" ); +} + +uno::Reference< word::XRange > SAL_CALL SwVbaSelection::GoTo( const uno::Any& _what, const uno::Any& _which, const uno::Any& _count, const uno::Any& _name ) +{ + sal_Int32 nWhat = 0; + if( !( _what >>= nWhat ) ) + DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {}); + switch( nWhat ) + { + case word::WdGoToItem::wdGoToBookmark: + { + uno::Reference< word::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW ); + uno::Reference< word::XBookmark > xBookmark( xApplication->getActiveDocument()->Bookmarks(_name), uno::UNO_QUERY_THROW ); + xBookmark->Select(); + break; + } + case word::WdGoToItem::wdGoToPage: + { + uno::Reference< text::XPageCursor > xPageCursor( mxTextViewCursor, uno::UNO_QUERY_THROW ); + sal_Int32 nCurrPage = xPageCursor->getPage(); + sal_Int32 nLastPage = word::getPageCount( mxModel ); + sal_Int32 nCount = 0; + if( _count.hasValue() ) + _count >>= nCount; + sal_Int32 nWhich = 0; + if( _which.hasValue() ) + _which >>= nWhich; + sal_Int32 nPage = 0; + switch( nWhich ) + { + case word::WdGoToDirection::wdGoToLast: + { + nPage = nLastPage; + break; + } + case word::WdGoToDirection::wdGoToNext: + { + if( nCount !=0 ) + nPage = nCurrPage + nCount; + else + nPage = nCurrPage + 1; + break; + } + case word::WdGoToDirection::wdGoToPrevious: + { + if( nCount !=0 ) + nPage = nCurrPage - nCount; + else + nPage = nCurrPage - 1; + break; + } + default: + { + nPage = nCount; + } + } + if( _name.hasValue() ) + { + OUString sName; + _name >>= sName; + sal_Int32 nName = sName.toInt32(); + if( nName !=0 ) + nPage = nName; + } + if( nPage <= 0 ) + nPage = 1; + if( nPage > nLastPage ) + nPage = nLastPage; + xPageCursor->jumpToPage( static_cast<sal_Int16>(nPage) ); + break; + } + case word::WdGoToItem::wdGoToSection: + { + uno::Reference< text::XPageCursor > xPageCursor( mxTextViewCursor, uno::UNO_QUERY_THROW ); + sal_Int32 nCount = 0; + if( _count.hasValue() ) + _count >>= nCount; + sal_Int32 nWhich = 0; + if( _which.hasValue() ) + _which >>= nWhich; + sal_Int32 nPage = 0; + switch( nWhich ) + { + case word::WdGoToDirection::wdGoToAbsolute: + { + // currently only support this type + if( nCount == 1 ) + nPage = 1; + break; + } + default: + { + nPage = 0; + } + } + if( nPage == 0 ) + throw uno::RuntimeException("Not implemented" ); + xPageCursor->jumpToPage( static_cast<sal_Int16>(nPage) ); + break; + } + default: + throw uno::RuntimeException("Not implemented" ); + } + return getRange(); +} + +::sal_Int32 SAL_CALL SwVbaSelection::getLanguageID() +{ + return getRange()->getLanguageID(); +} + +void SAL_CALL SwVbaSelection::setLanguageID( ::sal_Int32 _languageid ) +{ + getRange()->setLanguageID( _languageid ); +} + +uno::Any SAL_CALL SwVbaSelection::Information( sal_Int32 _type ) +{ + uno::Any result; + switch( _type ) + { + case word::WdInformation::wdActiveEndPageNumber: + { + result <<= SwVbaInformationHelper::handleWdActiveEndPageNumber( mxTextViewCursor ); + break; + } + case word::WdInformation::wdNumberOfPagesInDocument: + { + result <<= SwVbaInformationHelper::handleWdNumberOfPagesInDocument( mxModel ); + break; + } + case word::WdInformation::wdVerticalPositionRelativeToPage: + { + result <<= SwVbaInformationHelper::handleWdVerticalPositionRelativeToPage( mxModel, mxTextViewCursor ); + break; + } + case word::WdInformation::wdWithInTable: + { + uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextTable > xTextTable; + xCursorProps->getPropertyValue("TextTable") >>= xTextTable; + result <<= xTextTable.is(); + break; + } + case word::WdInformation::wdHeaderFooterType: + { + uno::Reference< word::XView > xView( new SwVbaView( this, mxContext, mxModel ) ); + sal_Int32 nView = xView->getSeekView(); + sal_Int32 nHeaderFooterType = 0; + switch( nView ) + { + case word::WdSeekView::wdSeekMainDocument: + { + nHeaderFooterType = -1; // not in a header or footer + break; + } + case word::WdSeekView::wdSeekEvenPagesHeader: + { + nHeaderFooterType = 0; // even page header + break; + } + case word::WdSeekView::wdSeekPrimaryHeader: + { + nHeaderFooterType = 1; // odd page header + break; + } + case word::WdSeekView::wdSeekEvenPagesFooter: + { + nHeaderFooterType = 2; // even page footer + break; + } + case word::WdSeekView::wdSeekPrimaryFooter: + { + nHeaderFooterType = 3; // odd page footer + break; + } + case word::WdSeekView::wdSeekFirstPageHeader: + case word::WdSeekView::wdSeekFirstPageFooter: + { + uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW ); + OUString aPageStyleName; + xCursorProps->getPropertyValue("PageStyleName") >>= aPageStyleName; + bool bFirstPage = false; + if ( aPageStyleName == "First Page" ) + bFirstPage = true; + if( nView == word::WdSeekView::wdSeekFirstPageHeader ) + { + if( bFirstPage ) + nHeaderFooterType = 4; + else + nHeaderFooterType = 1; + } + else + { + if( bFirstPage ) + nHeaderFooterType = 5; + else + nHeaderFooterType = 3; + } + break; + } + default: + { + nHeaderFooterType = -1; + } + } + result <<= nHeaderFooterType; + break; + } + default: + throw uno::RuntimeException("Not implemented" ); + } + return result; +} + +void SAL_CALL SwVbaSelection::InsertBreak( const uno::Any& _breakType ) +{ + getRange()->InsertBreak( _breakType ); +} + +uno::Any SAL_CALL +SwVbaSelection::Tables( const uno::Any& aIndex ) +{ + // Hacky implementation due to missing api ( and lack of knowledge ) + // we can only support a selection that is a single table + if ( !aIndex.hasValue() ) // currently we can't support multiple tables in a selection + throw uno::RuntimeException(); + + sal_Int32 nIndex = 0; + aIndex >>= nIndex; + + uno::Any aRet; + + if ( nIndex != 1 ) + throw uno::RuntimeException(); + + uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextTable > xTextTable; + xCursorProps->getPropertyValue("TextTable") >>= xTextTable; + if( xTextTable.is() ) + { + uno::Reference< css::text::XTextDocument > xTextDoc( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< word::XTable > xVBATable = new SwVbaTable( mxParent, mxContext, xTextDoc, xTextTable ); + aRet <<= xVBATable; + return aRet; + } + + // if the current selection is a XTextTableCursor and the index is 1 then we can service this request, otherwise we just have to throw + uno::Reference< text::XTextTableCursor > xTextTableCursor( mxModel->getCurrentSelection(), uno::UNO_QUERY_THROW ); + SwXTextTableCursor* pTTCursor = dynamic_cast< SwXTextTableCursor* >( xTextTableCursor.get() ); + if ( pTTCursor ) + { + SwFrameFormat* pFormat = pTTCursor->GetFrameFormat(); + if ( pFormat ) + { + uno::Reference< text::XTextTable > xTable = SwXTextTables::GetObject(*pFormat); + uno::Reference< css::text::XTextDocument > xTextDoc( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< word::XTable > xVBATable = new SwVbaTable( mxParent, mxContext, xTextDoc, xTable ); + aRet <<= xVBATable; + } + } + return aRet; + +} + +uno::Any SAL_CALL +SwVbaSelection::Fields( const uno::Any& index ) +{ + uno::Reference< XCollection > xCol( new SwVbaFields( mxParent, mxContext, mxModel ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Reference< word::XHeaderFooter > SAL_CALL +SwVbaSelection::getHeaderFooter() +{ + if( HeaderFooterHelper::isHeaderFooter( mxModel ) ) + { + uno::Reference< beans::XPropertySet > xPageStyleProps( word::getCurrentPageStyle( mxModel ), uno::UNO_QUERY_THROW ); + sal_Int32 nIndex = word::WdHeaderFooterIndex::wdHeaderFooterPrimary; + bool isHeader = HeaderFooterHelper::isHeader( mxModel ); + if( HeaderFooterHelper::isEvenPagesHeader( mxModel ) || HeaderFooterHelper::isEvenPagesFooter( mxModel ) ) + nIndex = word::WdHeaderFooterIndex::wdHeaderFooterEvenPages; + else if( HeaderFooterHelper::isFirstPageHeader( mxModel ) || HeaderFooterHelper::isFirstPageFooter( mxModel ) ) + nIndex = word::WdHeaderFooterIndex::wdHeaderFooterFirstPage; + + return uno::Reference< word::XHeaderFooter >( new SwVbaHeaderFooter( this, mxContext, mxModel, xPageStyleProps, isHeader, nIndex ) ); + + } + return uno::Reference< word::XHeaderFooter >(); +} + +uno::Any SAL_CALL +SwVbaSelection::ShapeRange( ) +{ + uno::Reference< drawing::XShapes > xShapes( mxModel->getCurrentSelection(), uno::UNO_QUERY ); + if ( !xShapes.is() ) + { + uno::Reference< drawing::XShape > xShape( mxModel->getCurrentSelection(), uno::UNO_QUERY_THROW ); + xShapes.set( drawing::ShapeCollection::create(mxContext) ); + xShapes->add( xShape ); + } + + uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< drawing::XDrawPage > xDrawPage = xDrawPageSupplier->getDrawPage(); + uno::Reference< container::XIndexAccess > xShapesAccess( xShapes, uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< msforms::XShapeRange >( new ScVbaShapeRange( this, mxContext, xShapesAccess, xDrawPage, mxModel ) ) ); +} + +::sal_Int32 SAL_CALL SwVbaSelection::getStart() +{ + return getRange()->getStart(); +} + +void SAL_CALL SwVbaSelection::setStart( ::sal_Int32 _start ) +{ + getRange()->setStart( _start ); +} +::sal_Int32 SAL_CALL SwVbaSelection::getEnd() +{ + return getRange()->getEnd(); +} + +void SAL_CALL SwVbaSelection::setEnd( ::sal_Int32 _end ) +{ + getRange()->setEnd( _end ); +} + +void SAL_CALL SwVbaSelection::SelectRow() +{ + uno::Reference< word::XRows > xRows( Rows( uno::Any() ), uno::UNO_QUERY_THROW ); + xRows->Select(); +} + +void SAL_CALL SwVbaSelection::SelectColumn() +{ + uno::Reference< word::XColumns > xColumns( Columns( uno::Any() ), uno::UNO_QUERY_THROW ); + xColumns->Select(); +} + +uno::Any SAL_CALL SwVbaSelection::Rows( const uno::Any& index ) +{ + OUString sTLName; + OUString sBRName; + GetSelectedCellRange( sTLName, sBRName ); + + sal_Int32 nStartRow = 0; + sal_Int32 nEndRow = 0; + uno::Reference< text::XTextTable > xTextTable = GetXTextTable(); + SwVbaTableHelper aTableHelper( xTextTable ); + nStartRow = aTableHelper.getTabRowIndex( sTLName ); + if( !sBRName.isEmpty() ) + { + nEndRow = aTableHelper.getTabRowIndex( sBRName ); + } + else + { + nEndRow = nStartRow; + } + + uno::Reference< XCollection > xCol( new SwVbaRows( this, mxContext, xTextTable, xTextTable->getRows(), nStartRow, nEndRow ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL SwVbaSelection::Columns( const uno::Any& index ) +{ + OUString sTLName; + OUString sBRName; + GetSelectedCellRange( sTLName, sBRName ); + sal_Int32 nStartColumn = 0; + sal_Int32 nEndColumn = 0; + + uno::Reference< text::XTextTable > xTextTable = GetXTextTable(); + SwVbaTableHelper aTableHelper( xTextTable ); + nStartColumn = aTableHelper.getTabColIndex( sTLName ); + if( !sBRName.isEmpty() ) + { + nEndColumn = aTableHelper.getTabColIndex( sBRName ); + } + else + { + nEndColumn = nStartColumn; + } + + uno::Reference< XCollection > xCol( new SwVbaColumns( this, mxContext, xTextTable, xTextTable->getColumns(), nStartColumn, nEndColumn ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Reference< text::XTextTable > SwVbaSelection::GetXTextTable() const +{ + uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextTable > xTextTable; + xCursorProps->getPropertyValue("TextTable") >>= xTextTable; + return xTextTable; +} + +bool SwVbaSelection::IsInTable() const +{ + uno::Reference< text::XTextTable > xTextTable = GetXTextTable(); + return xTextTable.is(); +} + +bool SwVbaSelection::HasSelection() +{ + uno::Reference< text::XTextRange > xStart = mxTextViewCursor->getStart(); + uno::Reference< text::XTextRange > xEnd = mxTextViewCursor->getEnd(); + uno::Reference< text::XTextRangeCompare > xTRC( mxTextViewCursor->getText(), uno::UNO_QUERY_THROW ); + return xTRC->compareRegionStarts( xStart, xEnd ) != 0 || xTRC->compareRegionEnds( xStart, xEnd ) != 0; +} + +void SwVbaSelection::GetSelectedCellRange( OUString& sTLName, OUString& sBRName ) +{ + uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextTable > xTextTable; + xCursorProps->getPropertyValue("TextTable") >>= xTextTable; + if( !xTextTable.is() ) + throw uno::RuntimeException( ); + + uno::Reference< text::XTextTableCursor > xTextTableCursor( mxModel->getCurrentSelection(), uno::UNO_QUERY ); + if( xTextTableCursor.is() ) + { + const OUString sRange( xTextTableCursor->getRangeName() ); + if (!sRange.isEmpty()) + { + sal_Int32 nIdx{0}; + sTLName = sRange.getToken(0, ':', nIdx); + sBRName = sRange.getToken(0, ':', nIdx); + } + } + if( sTLName.isEmpty() ) + { + uno::Reference< table::XCell > xCell; + xCursorProps->getPropertyValue("Cell") >>= xCell; + if( !xCell.is() ) + { + throw uno::RuntimeException( ); + } + uno::Reference< beans::XPropertySet > xCellProps( xCell, uno::UNO_QUERY_THROW ); + xCellProps->getPropertyValue("CellName") >>= sTLName; + } +} + +uno::Any SAL_CALL SwVbaSelection::Cells( const uno::Any& index ) +{ + OUString sTLName; + OUString sBRName; + GetSelectedCellRange( sTLName, sBRName ); + sal_Int32 nLeft = 0; + sal_Int32 nTop = 0; + sal_Int32 nRight = 0; + sal_Int32 nBottom = 0; + + uno::Reference< text::XTextTable > xTextTable = GetXTextTable(); + SwVbaTableHelper aTableHelper( xTextTable ); + nLeft = aTableHelper.getTabColIndex( sTLName ); + nTop = aTableHelper.getTabRowIndex( sTLName ); + if( !sBRName.isEmpty() ) + { + nRight = aTableHelper.getTabColIndex( sBRName ); + nBottom = aTableHelper.getTabRowIndex( sBRName ); + } + else + { + nRight = nLeft; + nBottom = nTop; + } + + uno::Reference< XCollection > xCol( new SwVbaCells( this, mxContext, xTextTable, nLeft, nTop, nRight, nBottom ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +void SAL_CALL SwVbaSelection::Copy( ) +{ + dispatchRequests( mxModel,".uno:Copy" ); +} + +void SAL_CALL SwVbaSelection::CopyAsPicture( ) +{ + // seems not support in Writer + Copy(); +} + +void SAL_CALL SwVbaSelection::Paste( ) +{ + dispatchRequests( mxModel,".uno:Paste" ); +} + +void SAL_CALL SwVbaSelection::Collapse( const uno::Any& Direction ) +{ + if( word::gotoSelectedObjectAnchor( mxModel ) ) + return; + + sal_Int32 nDirection = word::WdCollapseDirection::wdCollapseStart; + if( Direction.hasValue() ) + Direction >>= nDirection; + + uno::Reference< text::XTextViewCursor > xTextViewCursor = word::getXTextViewCursor( mxModel ); + if( nDirection == word::WdCollapseDirection::wdCollapseStart ) + { + // it is inaccurate if current selection is multiple cells, so it needs to go to start + uno::Reference< text::XTextRange > xTextRange = mxTextViewCursor->getStart(); + xTextViewCursor->gotoRange( xTextRange, false ); + xTextViewCursor->collapseToStart(); + } + else if( nDirection == word::WdCollapseDirection::wdCollapseEnd ) + { + uno::Reference< text::XTextRange > xTextRange = mxTextViewCursor->getEnd(); + xTextViewCursor->gotoRange( xTextRange, false ); + xTextViewCursor->collapseToEnd(); + } + else + { + throw uno::RuntimeException(); + } +} + +void SAL_CALL SwVbaSelection::WholeStory( ) +{ + uno::Reference< text::XText > xText = word::getCurrentXText( mxModel ); + // FIXME: for i#7747,if the first line is a table, it fails to select all the contents in the story. + // Temporary solution, insert an empty line before the table so that it could select all the contents. + uno::Reference< container::XEnumerationAccess > xParaAccess( xText, uno::UNO_QUERY_THROW ); + uno::Reference< container::XEnumeration> xParaEnum = xParaAccess->createEnumeration(); + if( xParaEnum->hasMoreElements() ) + { + uno::Reference< text::XTextTable > xTextTable( xParaEnum->nextElement(), uno::UNO_QUERY ); + if( xTextTable.is() ) + { + // insert an empty line + uno::Reference< text::XTextRange > xFirstCellRange = word::getFirstObjectPosition( xText ); + mxTextViewCursor->gotoRange( xFirstCellRange, false ); + dispatchRequests( mxModel,".uno:InsertPara" ); + } + } + uno::Reference< text::XTextRange > xStart = xText->getStart(); + uno::Reference< text::XTextRange > xEnd = xText->getEnd(); + mxTextViewCursor->gotoRange( xStart, false ); + mxTextViewCursor->gotoRange( xEnd, true ); +} + +sal_Bool SAL_CALL SwVbaSelection::InRange( const uno::Reference< ::ooo::vba::word::XRange >& Range ) +{ + return getRange()->InRange( Range ); +} + +void SAL_CALL SwVbaSelection::SplitTable() +{ + if( !IsInTable() ) + throw uno::RuntimeException(); + + SwDocShell* pDocShell = word::getDocShell( mxModel ); + if( pDocShell ) + { + if (SwFEShell* pFEShell = pDocShell->GetFEShell()) + pFEShell->SplitTable( SplitTable_HeadlineOption::ContentCopy ); + } +} + +uno::Any SAL_CALL +SwVbaSelection::Paragraphs( const uno::Any& aIndex ) +{ + // Hacky implementation due to missing api ( and lack of knowledge ) + // we can only support a selection that is a single paragraph + if ( !aIndex.hasValue() ) // currently we can't support multiple paragraphs in a selection + throw uno::RuntimeException(); + + sal_Int32 nIndex = 0; + aIndex >>= nIndex; + + uno::Any aRet; + + if ( nIndex != 1 ) + throw uno::RuntimeException(); + + uno::Reference< text::XTextRange > xTextRange = mxTextViewCursor->getStart(); + uno::Reference< text::XText > xText = xTextRange->getText(); + uno::Reference< text::XParagraphCursor > xParaCursor( xText->createTextCursor(), uno::UNO_QUERY_THROW ); + xParaCursor->gotoStartOfParagraph( false ); + xParaCursor->gotoStartOfParagraph( true ); + + uno::Reference< text::XTextDocument > xTextDoc( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextRange > xParaRange( xParaCursor, uno::UNO_QUERY_THROW ); + uno::Reference< word::XParagraph > xParagraph = new SwVbaParagraph( mxParent, mxContext, xTextDoc, xParaRange ); + + aRet <<= xParagraph; + return aRet; +} + +OUString +SwVbaSelection::getServiceImplName() +{ + return "SwVbaSelection"; +} + +uno::Sequence< OUString > +SwVbaSelection::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Selection" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaselection.hxx b/sw/source/ui/vba/vbaselection.hxx new file mode 100644 index 0000000000..0dba75b729 --- /dev/null +++ b/sw/source/ui/vba/vbaselection.hxx @@ -0,0 +1,120 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBASELECTION_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBASELECTION_HXX + +#include <ooo/vba/word/XSelection.hpp> +#include <ooo/vba/word/XRange.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextViewCursor.hpp> +#include <com/sun/star/text/XTextTable.hpp> +#include <ooo/vba/word/XParagraphFormat.hpp> +#include <ooo/vba/word/XFind.hpp> +#include <ooo/vba/word/XFont.hpp> +#include <ooo/vba/word/XHeaderFooter.hpp> +#include "wordvbahelper.hxx" + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XSelection > SwVbaSelection_BASE; + +class SwVbaSelection : public SwVbaSelection_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::text::XTextViewCursor > mxTextViewCursor; + +private: + /// @throws css::script::BasicErrorException + /// @throws css::uno::RuntimeException + void Move( const css::uno::Any& _unit, const css::uno::Any& _count, const css::uno::Any& _extend, ooo::vba::word::E_DIRECTION eDirection ); + /// @throws css::script::BasicErrorException + /// @throws css::uno::RuntimeException + void NextCell( sal_Int32 nCount, ooo::vba::word::E_DIRECTION eDirection ); + /// @throws css::uno::RuntimeException + css::uno::Reference< css::text::XTextRange > GetSelectedRange(); + /// @throws css::uno::RuntimeException + void GetSelectedCellRange( OUString& sTLName, OUString& sBRName ); + /// @throws css::uno::RuntimeException + css::uno::Reference< css::text::XTextTable > GetXTextTable() const; + /// @throws css::uno::RuntimeException + bool IsInTable() const; + /// @throws css::uno::RuntimeException + bool HasSelection(); + +public: + /// @throws css::uno::RuntimeException + SwVbaSelection( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::frame::XModel > xModel ); + virtual ~SwVbaSelection() override; + + // Attribute + virtual OUString SAL_CALL getText() override; + virtual void SAL_CALL setText( const OUString& rText ) override; + virtual css::uno::Reference< ooo::vba::word::XRange > SAL_CALL getRange() override; + virtual void SAL_CALL HomeKey( const css::uno::Any& _unit, const css::uno::Any& _extend ) override; + virtual void SAL_CALL EndKey( const css::uno::Any& _unit, const css::uno::Any& _extend ) override; + virtual void SAL_CALL TypeText( const OUString& rText ) override; + virtual void SAL_CALL Delete( const css::uno::Any& _unit, const css::uno::Any& _count ) override; + virtual void SAL_CALL MoveRight( const css::uno::Any& _unit, const css::uno::Any& _count, const css::uno::Any& _extend ) override; + virtual void SAL_CALL MoveLeft( const css::uno::Any& _unit, const css::uno::Any& _count, const css::uno::Any& _extend ) override; + virtual void SAL_CALL MoveDown( const css::uno::Any& _unit, const css::uno::Any& _count, const css::uno::Any& _extend ) override; + virtual void SAL_CALL MoveUp( const css::uno::Any& _unit, const css::uno::Any& _count, const css::uno::Any& _extend ) override; + virtual void SAL_CALL TypeParagraph() override; + virtual void SAL_CALL InsertParagraph() override; + virtual void SAL_CALL InsertParagraphBefore() override; + virtual void SAL_CALL InsertParagraphAfter() override; + virtual css::uno::Reference< ooo::vba::word::XParagraphFormat > SAL_CALL getParagraphFormat() override; + virtual void SAL_CALL setParagraphFormat( const css::uno::Reference< ooo::vba::word::XParagraphFormat >& rParagraphFormat ) override; + virtual css::uno::Reference< ooo::vba::word::XFind > SAL_CALL getFind() override; + virtual css::uno::Any SAL_CALL getStyle() override; + virtual void SAL_CALL setStyle( const css::uno::Any& _xStyle ) override; + virtual css::uno::Reference< ooo::vba::word::XFont > SAL_CALL getFont() override; + virtual void SAL_CALL TypeBackspace() override; + virtual css::uno::Reference< ooo::vba::word::XRange > SAL_CALL GoTo( const css::uno::Any& _what, const css::uno::Any& _which, const css::uno::Any& _count, const css::uno::Any& _name ) override; + virtual ::sal_Int32 SAL_CALL getLanguageID( ) override; + virtual void SAL_CALL setLanguageID( ::sal_Int32 _languageid ) override; + virtual css::uno::Any SAL_CALL Information( sal_Int32 _type ) override; + virtual void SAL_CALL InsertBreak( const css::uno::Any& _breakType ) override; + virtual css::uno::Any SAL_CALL Tables( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL Fields( const css::uno::Any& aIndex ) override; + virtual css::uno::Reference< ooo::vba::word::XHeaderFooter > SAL_CALL getHeaderFooter() override; + virtual css::uno::Any SAL_CALL ShapeRange( ) override; + virtual ::sal_Int32 SAL_CALL getStart() override; + virtual void SAL_CALL setStart( ::sal_Int32 _start ) override; + virtual ::sal_Int32 SAL_CALL getEnd() override; + virtual void SAL_CALL setEnd( ::sal_Int32 _end ) override; + virtual void SAL_CALL SelectRow() override; + virtual void SAL_CALL SelectColumn() override; + virtual css::uno::Any SAL_CALL Rows( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL Columns( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL Cells( const css::uno::Any& aIndex ) override; + virtual void SAL_CALL Copy( ) override; + virtual void SAL_CALL CopyAsPicture( ) override; + virtual void SAL_CALL Paste( ) override; + virtual void SAL_CALL Collapse( const css::uno::Any& Direction ) override; + virtual void SAL_CALL WholeStory( ) override; + virtual sal_Bool SAL_CALL InRange( const css::uno::Reference< ::ooo::vba::word::XRange >& Range ) override; + virtual void SAL_CALL SplitTable() override; + virtual css::uno::Any SAL_CALL Paragraphs( const css::uno::Any& aIndex ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBASELECTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbastyle.cxx b/sw/source/ui/vba/vbastyle.cxx new file mode 100644 index 0000000000..771e03ae33 --- /dev/null +++ b/sw/source/ui/vba/vbastyle.cxx @@ -0,0 +1,228 @@ +/* -*- 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 "vbastyle.hxx" +#include <ooo/vba/word/WdStyleType.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <i18nlangtag/languagetag.hxx> +#include <utility> +#include "vbafont.hxx" +#include "vbapalette.hxx" +#include "vbaparagraphformat.hxx" +#include "vbastyles.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaStyle::SwVbaStyle( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< frame::XModel> xModel, const uno::Reference< beans::XPropertySet >& _xPropertySet ) : SwVbaStyle_BASE( xParent, xContext ) , mxModel(std::move( xModel )), mxStyleProps( _xPropertySet ) +{ + mxStyle.set( _xPropertySet, uno::UNO_QUERY_THROW ); +} + +void SAL_CALL +SwVbaStyle::setName( const OUString& Name ) +{ + mxStyle->setName(Name); +} + +OUString SAL_CALL +SwVbaStyle::getName() +{ + return mxStyle->getName(); +} + +LanguageType SwVbaStyle::getLanguageID( const uno::Reference< beans::XPropertySet >& xTCProps ) +{ + lang::Locale aLocale; + xTCProps->getPropertyValue("CharLocale") >>= aLocale; + return LanguageTag::convertToLanguageType( aLocale, false); +} + +void SwVbaStyle::setLanguageID( const uno::Reference< beans::XPropertySet >& xTCProps, LanguageType _languageid ) +{ + lang::Locale aLocale = LanguageTag( _languageid ).getLocale(); + xTCProps->setPropertyValue("CharLocale", uno::Any( aLocale ) ) ; +} + +::sal_Int32 SAL_CALL SwVbaStyle::getLanguageID() +{ + return static_cast<sal_uInt16>(getLanguageID( mxStyleProps )); +} + +void SAL_CALL SwVbaStyle::setLanguageID( ::sal_Int32 _languageid ) +{ + setLanguageID( mxStyleProps, LanguageType(_languageid) ); +} + +::sal_Int32 SAL_CALL SwVbaStyle::getType() +{ + sal_Int32 nType = word::WdStyleType::wdStyleTypeParagraph; + uno::Reference< lang::XServiceInfo > xServiceInfo( mxStyle, uno::UNO_QUERY_THROW ); + if( xServiceInfo->supportsService("com.sun.star.style.ParagraphStyle") ) + nType = word::WdStyleType::wdStyleTypeParagraph; + else if( xServiceInfo->supportsService("com.sun.star.style.CharacterStyle") ) + nType = word::WdStyleType::wdStyleTypeCharacter; + else + nType = word::WdStyleType::wdStyleTypeList; + return nType; +} + +uno::Reference< word::XFont > SAL_CALL +SwVbaStyle::getFont() +{ + VbaPalette aColors; + return new SwVbaFont( mxParent, mxContext, aColors.getPalette(), mxStyleProps ); +} + +void SwVbaStyle::setStyle( const uno::Reference< beans::XPropertySet >& xParaProps, const uno::Any& rStyle ) +{ + OUString sStyle; + uno::Reference< word::XStyle > xStyle; + if( rStyle >>= xStyle ) + { + sStyle = xStyle->getName(); + } + else + { + rStyle >>= sStyle; + } + + if( !sStyle.isEmpty() ) + { + xParaProps->setPropertyValue("ParaStyleName", uno::Any( sStyle ) ); + return; + } + + throw uno::RuntimeException(); +} + +OUString SAL_CALL SwVbaStyle::getNameLocal() +{ + OUString sNameLocal; + mxStyleProps->getPropertyValue("DisplayName") >>= sNameLocal; + return sNameLocal; +} + +void SAL_CALL SwVbaStyle::setNameLocal( const OUString& _namelocal ) +{ + mxStyleProps->setPropertyValue("DisplayName", uno::Any( _namelocal ) ); +} + +uno::Reference< word::XParagraphFormat > SAL_CALL SwVbaStyle::getParagraphFormat() +{ + if( word::WdStyleType::wdStyleTypeParagraph != getType() ) + { + throw uno::RuntimeException(); + } + + uno::Reference< text::XTextDocument > xTextDocument( mxModel, uno::UNO_QUERY_THROW ); + return uno::Reference< word::XParagraphFormat >( new SwVbaParagraphFormat( this, mxContext, mxStyleProps ) ); +} + +sal_Bool SAL_CALL SwVbaStyle::getAutomaticallyUpdate() +{ + bool isAutoUpdate = false; + mxStyleProps->getPropertyValue("IsAutoUpdate") >>= isAutoUpdate; + return isAutoUpdate; +} + +void SAL_CALL SwVbaStyle::setAutomaticallyUpdate( sal_Bool _automaticallyupdate ) +{ + mxStyleProps->setPropertyValue("IsAutoUpdate", uno::Any( _automaticallyupdate ) ); +} + +uno::Any SAL_CALL SwVbaStyle::getBaseStyle() +{ + // ParentStyle + OUString sBaseStyle; + mxStyleProps->getPropertyValue("ParentStyle") >>= sBaseStyle; + if( sBaseStyle.isEmpty() ) + { + throw uno::RuntimeException(); + } + + uno::Reference< XCollection > xCol( new SwVbaStyles( this, mxContext, mxModel ) ); + return xCol->Item( uno::Any( sBaseStyle ), uno::Any() ); +} + +void SAL_CALL SwVbaStyle::setBaseStyle( const uno::Any& _basestyle ) +{ + uno::Reference< word::XStyle > xStyle; + _basestyle >>= xStyle; + if( !xStyle.is() ) + { + throw uno::RuntimeException(); + } + + OUString sBaseStyle = xStyle->getName(); + mxStyleProps->setPropertyValue("ParentStyle", uno::Any( sBaseStyle ) ); +} + +uno::Any SAL_CALL SwVbaStyle::getNextParagraphStyle() +{ + //FollowStyle + OUString sFollowStyle; + mxStyleProps->getPropertyValue("FollowStyle") >>= sFollowStyle; + if( sFollowStyle.isEmpty() ) + { + throw uno::RuntimeException(); + } + + uno::Reference< XCollection > xCol( new SwVbaStyles( this, mxContext, mxModel ) ); + return xCol->Item( uno::Any( sFollowStyle ), uno::Any() ); +} + +void SAL_CALL SwVbaStyle::setNextParagraphStyle( const uno::Any& _nextparagraphstyle ) +{ + uno::Reference< word::XStyle > xStyle; + _nextparagraphstyle >>= xStyle; + if( !xStyle.is() ) + { + throw uno::RuntimeException(); + } + + OUString sFollowStyle = xStyle->getName(); + mxStyleProps->setPropertyValue("FollowStyle", uno::Any( sFollowStyle ) ); +} + +::sal_Int32 SAL_CALL SwVbaStyle::getListLevelNumber() +{ + sal_Int16 nNumberingLevel = 0; + mxStyleProps->getPropertyValue("NumberingLevel") >>= nNumberingLevel; + return nNumberingLevel; +} + +OUString +SwVbaStyle::getServiceImplName() +{ + return "SwVbaStyle"; +} + +uno::Sequence< OUString > +SwVbaStyle::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.XStyle" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbastyle.hxx b/sw/source/ui/vba/vbastyle.hxx new file mode 100644 index 0000000000..dc7ae051f1 --- /dev/null +++ b/sw/source/ui/vba/vbastyle.hxx @@ -0,0 +1,78 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBASTYLE_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBASTYLE_HXX + +#include <ooo/vba/word/XStyle.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <i18nlangtag/lang.h> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/style/XStyle.hpp> +#include <ooo/vba/word/XFont.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XStyle > SwVbaStyle_BASE; + +class SwVbaStyle : public SwVbaStyle_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::beans::XPropertySet > mxStyleProps; + css::uno::Reference< css::style::XStyle > mxStyle; +public: + /// @throws css::script::BasicErrorException + /// @throws css::uno::RuntimeException + SwVbaStyle( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::frame::XModel > xModel, const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet ); + + /// @throws css::uno::RuntimeException + static void setStyle( const css::uno::Reference< css::beans::XPropertySet >& xParaProps, const css::uno::Any& xStyle ); + /// @throws css::uno::RuntimeException + static LanguageType getLanguageID( const css::uno::Reference< css::beans::XPropertySet >& xTCProps ); + /// @throws css::uno::RuntimeException + static void setLanguageID( const css::uno::Reference< css::beans::XPropertySet >& xTCProps, LanguageType _languageid ); + + // Attributes + virtual OUString SAL_CALL getName() override; + virtual void SAL_CALL setName( const OUString& Name ) override; + virtual ::sal_Int32 SAL_CALL getLanguageID( ) override; + virtual void SAL_CALL setLanguageID( ::sal_Int32 _languageid ) override; + virtual ::sal_Int32 SAL_CALL getType() override; + virtual css::uno::Reference< ooo::vba::word::XFont > SAL_CALL getFont() override; + virtual OUString SAL_CALL getNameLocal() override; + virtual void SAL_CALL setNameLocal( const OUString& _namelocal ) override; + virtual css::uno::Reference< ::ooo::vba::word::XParagraphFormat > SAL_CALL getParagraphFormat() override; + virtual sal_Bool SAL_CALL getAutomaticallyUpdate() override; + virtual void SAL_CALL setAutomaticallyUpdate( sal_Bool _automaticallyupdate ) override; + virtual css::uno::Any SAL_CALL getBaseStyle() override; + virtual void SAL_CALL setBaseStyle( const css::uno::Any& _basestyle ) override; + virtual css::uno::Any SAL_CALL getNextParagraphStyle() override; + virtual void SAL_CALL setNextParagraphStyle( const css::uno::Any& _nextparagraphstyle ) override; + virtual ::sal_Int32 SAL_CALL getListLevelNumber() override; + + //XDefaultProperty + virtual OUString SAL_CALL getDefaultPropertyName( ) override { return "Name"; } + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif //SW_VBA_AXIS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbastyles.cxx b/sw/source/ui/vba/vbastyles.cxx new file mode 100644 index 0000000000..5e9ce270ff --- /dev/null +++ b/sw/source/ui/vba/vbastyles.cxx @@ -0,0 +1,378 @@ +/* -*- 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 "vbastyles.hxx" +#include "vbastyle.hxx" +#include <basic/sberrors.hxx> +#include <cppuhelper/implbase.hxx> +#include <sal/log.hxx> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/style/XStyle.hpp> +#include <ooo/vba/word/WdBuiltinStyle.hpp> +#include <ooo/vba/word/WdStyleType.hpp> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +struct BuiltinStyleTable +{ + sal_Int32 wdBuiltinStyle; + const char* pOOoStyleName; + sal_Int32 wdStyleType; +}; + +} + +const BuiltinStyleTable aBuiltinStyleTable[] = +{ + { word::WdBuiltinStyle::wdStyleBlockQuotation, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleBodyText, "Text body", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleBodyText2, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleBodyText3, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleBodyTextFirstIndent, "First line indent", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleBodyTextFirstIndent2, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleBodyTextIndent, "Text body indent", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleBodyTextIndent2, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleBodyTextIndent3, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleCaption, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleClosing, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleCommentReference, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleCommentText, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleDate, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleDefaultParagraphFont, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleEmphasis, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleEndnoteReference, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleEndnoteText, "Endnote", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleEnvelopeAddress, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleEnvelopeReturn, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleFooter, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleFootnoteReference, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleFootnoteText, "Footnote", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHeader, "Header", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHeading1, "Heading 1", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHeading2, "Heading 2", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHeading3, "Heading 3", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHeading4, "Heading 4", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHeading5, "Heading 5", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHeading6, "Heading 6", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHeading7, "Heading 7", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHeading8, "Heading 8", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHeading9, "Heading 9", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHtmlAcronym, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHtmlAddress, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHtmlCite, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHtmlCode, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHtmlDfn, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHtmlKbd, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHtmlNormal, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHtmlPre, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHtmlSamp, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHtmlTt, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHtmlVar, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHyperlink, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleHyperlinkFollowed, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleIndex1, "Index 1", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleIndex2, "Index 2", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleIndex3, "Index 3", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleIndex4, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleIndex5, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleIndex6, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleIndex7, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleIndex8, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleIndex9, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleIndexHeading, "Index Heading", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleLineNumber, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleList, "List", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleList2, "List 2", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleList3, "List 3", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleList4, "List 4", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleList5, "List 5", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleListBullet, "List 1", word::WdStyleType::wdStyleTypeList }, + { word::WdBuiltinStyle::wdStyleListBullet2, "List 2", word::WdStyleType::wdStyleTypeList }, + { word::WdBuiltinStyle::wdStyleListBullet3, "List 3", word::WdStyleType::wdStyleTypeList }, + { word::WdBuiltinStyle::wdStyleListBullet4, "List 4", word::WdStyleType::wdStyleTypeList }, + { word::WdBuiltinStyle::wdStyleListBullet5, "List 5", word::WdStyleType::wdStyleTypeList }, + { word::WdBuiltinStyle::wdStyleListContinue, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleListContinue2, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleListContinue3, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleListContinue4, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleListContinue5, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleListNumber, "Numbering 123", word::WdStyleType::wdStyleTypeList }, + { word::WdBuiltinStyle::wdStyleListNumber2, "Numbering ABC", word::WdStyleType::wdStyleTypeList }, + { word::WdBuiltinStyle::wdStyleListNumber3, "Numbering abc", word::WdStyleType::wdStyleTypeList }, + { word::WdBuiltinStyle::wdStyleListNumber4, "Numbering IVX", word::WdStyleType::wdStyleTypeList }, + { word::WdBuiltinStyle::wdStyleListNumber5, "Numbering ivx", word::WdStyleType::wdStyleTypeList }, + { word::WdBuiltinStyle::wdStyleMacroText, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleMessageHeader, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleNavPane, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleNormal, "Default", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleNormalIndent, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleNormalTable, "Table", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleNoteHeading, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStylePageNumber, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStylePlainText, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleSalutation, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleSignature, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleStrong, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleSubtitle, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTableOfAuthorities, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTableOfFigures, "", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTitle, "Title", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTOAHeading, "Contents Heading", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTOC1, "Contents 1", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTOC2, "Contents 2", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTOC3, "Contents 3", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTOC4, "Contents 4", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTOC5, "Contents 5", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTOC6, "Contents 6", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTOC7, "Contents 7", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTOC8, "Contents 8", word::WdStyleType::wdStyleTypeParagraph }, + { word::WdBuiltinStyle::wdStyleTOC9, "Contents 9", word::WdStyleType::wdStyleTypeParagraph }, + { 0, nullptr, 0 } +}; + +namespace { + +struct MSOStyleNameTable +{ + const char* pMSOStyleName; + const char* pOOoStyleName; +}; + +} + +const MSOStyleNameTable aMSOStyleNameTable[] = +{ + { "Normal", "Default" }, + { nullptr, nullptr } +}; + +namespace { + +class StyleCollectionHelper : public ::cppu::WeakImplHelper< container::XNameAccess, + container::XIndexAccess, + container::XEnumerationAccess > +{ +private: + uno::Reference< container::XNameAccess > mxParaStyles; + uno::Any m_cachePos; +public: + explicit StyleCollectionHelper( const uno::Reference< frame::XModel >& _xModel ) + { + // we only concern about the Paragraph styles + uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( _xModel, uno::UNO_QUERY_THROW); + uno::Reference< container::XNameAccess > xStyleFamilies = xStyleSupplier->getStyleFamilies(); + mxParaStyles.set( xStyleFamilies->getByName("ParagraphStyles"), uno::UNO_QUERY_THROW ); + } + // XElementAccess + virtual uno::Type SAL_CALL getElementType( ) override { return cppu::UnoType<style::XStyle>::get(); } + virtual sal_Bool SAL_CALL hasElements( ) override { return getCount() > 0; } + // XNameAccess + virtual uno::Any SAL_CALL getByName( const OUString& aName ) override + { + if ( !hasByName(aName) ) + throw container::NoSuchElementException(); + return m_cachePos; + } + virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override + { + return mxParaStyles->getElementNames(); + } + virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override + { + // search in the MSOStyleName table first + for( const MSOStyleNameTable* pTable = aMSOStyleNameTable; pTable->pMSOStyleName != nullptr; pTable++ ) + { + if( aName.equalsIgnoreAsciiCaseAscii( pTable->pMSOStyleName ) ) + { + //Found it + OUString sStyleName = OUString::createFromAscii( pTable->pOOoStyleName ); + if( mxParaStyles->hasByName( sStyleName ) ) + { + m_cachePos = mxParaStyles->getByName( sStyleName ); + return true; + } + return false; + } + } + + if( mxParaStyles->hasByName( aName ) ) + { + m_cachePos = mxParaStyles->getByName( aName ); + return true; + } + else + { + const uno::Sequence< OUString > sElementNames = mxParaStyles->getElementNames(); + auto pStyleName = std::find_if(sElementNames.begin(), sElementNames.end(), + [&aName](const OUString& rStyleName) { return rStyleName.equalsIgnoreAsciiCase( aName ); }); + if (pStyleName != sElementNames.end()) + { + m_cachePos = mxParaStyles->getByName( *pStyleName ); + return true; + } + } + return false; + } + + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override + { + uno::Reference< container::XIndexAccess > xIndexAccess( mxParaStyles, uno::UNO_QUERY_THROW ); + return xIndexAccess->getCount(); + } + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override + { + if ( Index < 0 || Index >= getCount() ) + throw lang::IndexOutOfBoundsException(); + + uno::Reference< container::XIndexAccess > xIndexAccess( mxParaStyles, uno::UNO_QUERY_THROW ); + return xIndexAccess->getByIndex( Index ); + } + // XEnumerationAccess + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override + { + throw uno::RuntimeException("Not implemented" ); + } +}; + +class StylesEnumWrapper : public EnumerationHelper_BASE +{ + SwVbaStyles* m_pStyles; + sal_Int32 m_nIndex; +public: + explicit StylesEnumWrapper( SwVbaStyles* _pStyles ) : m_pStyles( _pStyles ), m_nIndex( 1 ) {} + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( m_nIndex <= m_pStyles->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( m_nIndex <= m_pStyles->getCount() ) + return m_pStyles->Item( uno::Any( m_nIndex++ ), uno::Any() ); + throw container::NoSuchElementException(); + } +}; + +} + +SwVbaStyles::SwVbaStyles( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel ) + : SwVbaStyles_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new StyleCollectionHelper( xModel ) ) ), mxModel( xModel ) +{ + mxMSF.set( mxModel, uno::UNO_QUERY_THROW ); +} + +uno::Any +SwVbaStyles::createCollectionObject(const uno::Any& aObject) +{ + uno::Reference< beans::XPropertySet > xStyleProp( aObject, uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< word::XStyle >( new SwVbaStyle( this, mxContext, mxModel, xStyleProp ) ) ); +} + +uno::Type SAL_CALL +SwVbaStyles::getElementType() +{ + return cppu::UnoType<word::XStyle>::get(); +} + +uno::Reference< container::XEnumeration > SAL_CALL +SwVbaStyles::createEnumeration() +{ + return new StylesEnumWrapper( this ); +} + +uno::Any SAL_CALL +SwVbaStyles::Item( const uno::Any& Index1, const uno::Any& Index2 ) +{ + //handle WdBuiltinStyle + sal_Int32 nIndex = 0; + if( ( Index1 >>= nIndex ) && ( nIndex < 0 ) ) + { + for( const BuiltinStyleTable* pTable = aBuiltinStyleTable; pTable != nullptr; pTable++ ) + { + if( nIndex == pTable->wdBuiltinStyle ) + { + OUString aStyleName = OUString::createFromAscii( pTable->pOOoStyleName ); + if( !aStyleName.isEmpty() ) + { + OUString aStyleType; + switch( pTable->wdStyleType ) + { + case word::WdStyleType::wdStyleTypeParagraph: + case word::WdStyleType::wdStyleTypeTable: + { + aStyleType = "ParagraphStyles"; + break; + } + case word::WdStyleType::wdStyleTypeCharacter: + { + aStyleType = "CharacterStyles"; + break; + } + case word::WdStyleType::wdStyleTypeList: + { + // should use Paragraph style and set the property "NumberingStyleName" + aStyleType = "ParagraphStyles"; + break; + } + default: + DebugHelper::basicexception( ERRCODE_BASIC_INTERNAL_ERROR, {} ); + } + uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( mxModel, uno::UNO_QUERY_THROW); + uno::Reference< container::XNameAccess > xStylesAccess( xStyleSupplier->getStyleFamilies()->getByName( aStyleType ), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xStyleProps( xStylesAccess->getByName( aStyleName ), uno::UNO_QUERY_THROW ); + // set the property "NumberingStyleName" if it is a listbullet + if( pTable->wdStyleType == word::WdStyleType::wdStyleTypeList ) + { + xStyleProps->setPropertyValue("NumberingStyleName", uno::Any( aStyleName ) ); + } + return uno::Any( uno::Reference< word::XStyle >( new SwVbaStyle( this, mxContext, mxModel, xStyleProps ) ) ); + } + else + { + SAL_WARN("sw.vba", "the builtin style type is not implemented"); + throw uno::RuntimeException("Not implemented" ); + } + } + } + } + return SwVbaStyles_BASE::Item( Index1, Index2 ); +} + +OUString +SwVbaStyles::getServiceImplName() +{ + return "SwVbaStyles"; +} + +uno::Sequence< OUString > +SwVbaStyles::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.XStyles" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbastyles.hxx b/sw/source/ui/vba/vbastyles.hxx new file mode 100644 index 0000000000..390225cd08 --- /dev/null +++ b/sw/source/ui/vba/vbastyles.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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBASTYLES_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBASTYLES_HXX + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <ooo/vba/word/XStyles.hpp> +#include <vbahelper/vbacollectionimpl.hxx> + +typedef CollTestImplHelper< ooo::vba::word::XStyles > SwVbaStyles_BASE; +class SwVbaStyles: public SwVbaStyles_BASE +{ + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::lang::XMultiServiceFactory > mxMSF; +public: + /// @throws css::script::BasicErrorException + /// @throws css::uno::RuntimeException + SwVbaStyles( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel ); + + virtual css::uno::Any SAL_CALL Item(const css::uno::Any& Index1, const css::uno::Any& Index2) override; + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + virtual css::uno::Any createCollectionObject(const css::uno::Any&) override; + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbasystem.cxx b/sw/source/ui/vba/vbasystem.cxx new file mode 100644 index 0000000000..e09c89554e --- /dev/null +++ b/sw/source/ui/vba/vbasystem.cxx @@ -0,0 +1,275 @@ +/* -*- 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 "vbasystem.hxx" + +#include <ooo/vba/word/WdCursorType.hpp> +#include <tools/config.hxx> +#include <osl/file.hxx> +#include <tools/urlobj.hxx> +#include <o3tl/char16_t2wchar_t.hxx> + +#ifdef _WIN32 +#include <cstddef> +#include <string_view> +#if !defined WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#endif + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +PrivateProfileStringListener::~PrivateProfileStringListener() +{ +} + +void PrivateProfileStringListener::Initialize( const OUString& rFileName, const OString& rGroupName, const OString& rKey ) +{ + maFileName = rFileName; + maGroupName = rGroupName; + maKey = rKey; +} +#ifdef _WIN32 +static void lcl_getRegKeyInfo( std::string_view sKeyInfo, HKEY& hBaseKey, OString& sSubKey ) +{ + std::size_t nBaseKeyIndex = sKeyInfo.find('\\'); + if( nBaseKeyIndex != std::string_view::npos ) + { + std::string_view sBaseKey = sKeyInfo.substr( 0, nBaseKeyIndex ); + sSubKey = OString(sKeyInfo.substr( nBaseKeyIndex + 1 )); + if( sBaseKey == "HKEY_CURRENT_USER" ) + { + hBaseKey = HKEY_CURRENT_USER; + } + else if( sBaseKey == "HKEY_LOCAL_MACHINE" ) + { + hBaseKey = HKEY_LOCAL_MACHINE; + } + else if( sBaseKey == "HKEY_CLASSES_ROOT" ) + { + hBaseKey = HKEY_CLASSES_ROOT; + } + else if( sBaseKey == "HKEY_USERS" ) + { + hBaseKey = HKEY_USERS; + } + else if( sBaseKey == "HKEY_CURRENT_CONFIG" ) + { + hBaseKey = HKEY_CURRENT_CONFIG; + } + } +} +#endif + +uno::Any PrivateProfileStringListener::getValueEvent() +{ + // get the private profile string + OUString sValue; + if(maFileName.isEmpty()) + { + // get key/value from Windows registry +#ifdef _WIN32 + HKEY hBaseKey = nullptr; + OString sSubKey; + lcl_getRegKeyInfo( maGroupName, hBaseKey, sSubKey ); + if( hBaseKey != nullptr ) + { + HKEY hKey = nullptr; + LPCSTR lpSubKey = sSubKey.getStr(); + // We use RegOpenKeyExA here for convenience, because we already have subkey name as 8-bit string + LONG lResult = RegOpenKeyExA( hBaseKey, lpSubKey, 0, KEY_QUERY_VALUE, &hKey ); + if( ERROR_SUCCESS == lResult ) + { + OUString sUValName = OStringToOUString(maKey, RTL_TEXTENCODING_DONTKNOW); + LPCWSTR lpValueName = o3tl::toW(sUValName.getStr()); + WCHAR szBuffer[1024]; + DWORD cbData = sizeof(szBuffer); + lResult = RegQueryValueExW( hKey, lpValueName, nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &cbData ); + RegCloseKey( hKey ); + // https://msdn.microsoft.com/en-us/ms724911 mentions that + // "the string may not have been stored with the proper terminating null characters" + szBuffer[std::min(size_t(cbData / sizeof(szBuffer[0])), SAL_N_ELEMENTS(szBuffer)-1)] = 0; + sValue = o3tl::toU(szBuffer); + } + } +#else + throw uno::RuntimeException("Only support on Windows" ); +#endif + } + + // get key/value from a file + Config aCfg( maFileName ); + aCfg.SetGroup( maGroupName ); + sValue = OStringToOUString(aCfg.ReadKey(maKey), RTL_TEXTENCODING_DONTKNOW); + + + return uno::Any( sValue ); +} + +void PrivateProfileStringListener::setValueEvent( const css::uno::Any& value ) +{ + // set the private profile string + OUString aValue; + value >>= aValue; + if(maFileName.isEmpty()) + { + //set value into Windows registry +#ifdef _WIN32 + HKEY hBaseKey = nullptr; + OString sSubKey; + lcl_getRegKeyInfo( maGroupName, hBaseKey, sSubKey ); + if( hBaseKey != nullptr ) + { + HKEY hKey = nullptr; + LPCSTR lpSubKey = sSubKey.getStr(); + // We use RegCreateKeyExA here for convenience, because we already have subkey name as 8-bit string + LONG lResult = RegCreateKeyExA( hBaseKey, lpSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, nullptr, &hKey, nullptr ); + if( ERROR_SUCCESS == lResult ) + { + DWORD cbData = sizeof(WCHAR) * (aValue.getLength() + 1); + OUString sUValName = OStringToOUString(maKey, RTL_TEXTENCODING_DONTKNOW); + LPCWSTR lpValueName = o3tl::toW(sUValName.getStr()); + lResult = RegSetValueExW( hKey, lpValueName, 0 /* Reserved */, REG_SZ, reinterpret_cast<BYTE const *>(aValue.getStr()), cbData ); + RegCloseKey( hKey ); + } + } + return; +#else + throw uno::RuntimeException("Not implemented" ); +#endif + } + + // set value into a file + Config aCfg( maFileName ); + aCfg.SetGroup( maGroupName ); + aCfg.WriteKey( maKey, OUStringToOString(aValue, RTL_TEXTENCODING_DONTKNOW) ); + + +} + +SwVbaSystem::SwVbaSystem( uno::Reference<uno::XComponentContext > const & xContext ): SwVbaSystem_BASE( uno::Reference< XHelperInterface >(), xContext ) +{ +} + +SwVbaSystem::~SwVbaSystem() +{ +} + +sal_Int32 SAL_CALL +SwVbaSystem::getCursor() +{ + PointerStyle nPointerStyle = getPointerStyle( getCurrentWordDoc(mxContext) ); + + switch( nPointerStyle ) + { + case PointerStyle::Arrow: + return word::WdCursorType::wdCursorNorthwestArrow; + case PointerStyle::Null: + return word::WdCursorType::wdCursorNormal; + case PointerStyle::Wait: + return word::WdCursorType::wdCursorWait; + case PointerStyle::Text: + return word::WdCursorType::wdCursorIBeam; + default: + return word::WdCursorType::wdCursorNormal; + } +} + +void SAL_CALL +SwVbaSystem::setCursor( sal_Int32 _cursor ) +{ + try + { + switch( _cursor ) + { + case word::WdCursorType::wdCursorNorthwestArrow: + { + setCursorHelper( getCurrentWordDoc(mxContext), PointerStyle::Arrow, false ); + break; + } + case word::WdCursorType::wdCursorWait: + { + //It will set the edit window, toobar and statusbar's mouse pointer. + setCursorHelper( getCurrentWordDoc(mxContext), PointerStyle::Wait, true ); + break; + } + case word::WdCursorType::wdCursorIBeam: + { + //It will set the edit window, toobar and statusbar's mouse pointer. + setCursorHelper( getCurrentWordDoc( mxContext ), PointerStyle::Text, true ); + break; + } + case word::WdCursorType::wdCursorNormal: + { + setCursorHelper( getCurrentWordDoc( mxContext ), PointerStyle::Null, false ); + break; + } + default: + throw uno::RuntimeException("Unknown value for Cursor pointer" ); + // TODO: isn't this a flaw in the API? It should be allowed to throw an + // IllegalArgumentException, or so + } + } + catch( const uno::Exception& ) + { + } +} + +uno::Any SAL_CALL +SwVbaSystem::PrivateProfileString( const OUString& rFilename, const OUString& rSection, const OUString& rKey ) +{ + // FIXME: need to detect whether it is a relative file path + // we need to detect if this is a URL, if not then assume it's a file path + OUString sFileUrl; + if( !rFilename.isEmpty() ) + { + INetURLObject aObj; + aObj.SetURL( rFilename ); + bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid; + if ( bIsURL ) + sFileUrl = rFilename; + else + osl::FileBase::getFileURLFromSystemPath( rFilename, sFileUrl); + } + + OString aGroupName(OUStringToOString(rSection, RTL_TEXTENCODING_DONTKNOW)); + OString aKey(OUStringToOString(rKey, RTL_TEXTENCODING_DONTKNOW)); + maPrivateProfileStringListener.Initialize( sFileUrl, aGroupName, aKey ); + + return uno::Any( uno::Reference< XPropValue > ( new ScVbaPropValue( &maPrivateProfileStringListener ) ) ); +} + +OUString +SwVbaSystem::getServiceImplName() +{ + return "SwVbaSystem"; +} + +uno::Sequence< OUString > +SwVbaSystem::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.System" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbasystem.hxx b/sw/source/ui/vba/vbasystem.hxx new file mode 100644 index 0000000000..c0acb2ad49 --- /dev/null +++ b/sw/source/ui/vba/vbasystem.hxx @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBASYSTEM_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBASYSTEM_HXX + +#include <ooo/vba/word/XSystem.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <vbahelper/vbapropvalue.hxx> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XSystem > SwVbaSystem_BASE; + +class PrivateProfileStringListener : public PropListener +{ +private: + OUString maFileName; + OString maGroupName; + OString maKey; +public: + PrivateProfileStringListener(){}; + virtual ~PrivateProfileStringListener(); + void Initialize( const OUString& rFileName, const OString& rGroupName, const OString& rKey ); + + //PropListener + virtual void setValueEvent( const css::uno::Any& value ) override; + virtual css::uno::Any getValueEvent() override; +}; + +class SwVbaSystem : public SwVbaSystem_BASE +{ +private: + PrivateProfileStringListener maPrivateProfileStringListener; + +public: + explicit SwVbaSystem( css::uno::Reference< css::uno::XComponentContext > const & m_xContext ); + virtual ~SwVbaSystem() override; + + // XSystem + virtual sal_Int32 SAL_CALL getCursor() override; + virtual void SAL_CALL setCursor( sal_Int32 _cursor ) override; + virtual css::uno::Any SAL_CALL PrivateProfileString( const OUString& rFilename, const OUString& rSection, const OUString& rKey ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBASYSTEM_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatable.cxx b/sw/source/ui/vba/vbatable.cxx new file mode 100644 index 0000000000..25e370a1c5 --- /dev/null +++ b/sw/source/ui/vba/vbatable.cxx @@ -0,0 +1,211 @@ +/* -*- 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 "vbatable.hxx" +#include "vbarange.hxx" +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/text/XTextViewCursorSupplier.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/text/XTextTable.hpp> +#include <com/sun/star/table/XTableRows.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/table/TableBorderDistances.hpp> +#include <utility> +#include "vbaborders.hxx" +#include "vbapalette.hxx" +#include "vbarows.hxx" +#include "vbacolumns.hxx" +#include "vbaapplication.hxx" + +#include <tools/UnitConversion.hxx> + +#include <sal/log.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaTable::SwVbaTable( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xDocument, const uno::Reference< text::XTextTable >& xTextTable) : SwVbaTable_BASE( rParent, rContext ), mxTextDocument(std::move( xDocument )) +{ + mxTextTable.set( xTextTable, uno::UNO_SET_THROW ); +} + +uno::Reference< word::XRange > SAL_CALL +SwVbaTable::Range( ) +{ + return new SwVbaRange( mxParent, mxContext, mxTextDocument, mxTextTable->getAnchor() ); +} + +void SAL_CALL +SwVbaTable::Select( ) +{ + uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< frame::XController > xController = xModel->getCurrentController(); + + uno::Reference< text::XTextViewCursorSupplier > xViewCursorSupplier( xController, uno::UNO_QUERY_THROW ); + uno::Reference< view::XSelectionSupplier > xSelectionSupplier( xController, uno::UNO_QUERY_THROW ); + + // set the view cursor to the start of the table. + xSelectionSupplier->select( uno::Any( mxTextTable ) ); + + // go to the end of the table and span the view + uno::Reference< text::XTextViewCursor > xCursor = xViewCursorSupplier->getViewCursor(); + xCursor->gotoEnd(true); + +} + +void SAL_CALL +SwVbaTable::Delete( ) +{ + uno::Reference< table::XTableRows > xRows( mxTextTable->getRows() ); + xRows->removeByIndex( 0, xRows->getCount() ); +} + +OUString SAL_CALL +SwVbaTable::getName( ) +{ + uno::Reference< container::XNamed > xNamed( mxTextTable, uno::UNO_QUERY_THROW ); + return xNamed->getName(); +} + +uno::Any SAL_CALL +SwVbaTable::Borders( const uno::Any& index ) +{ + uno::Reference< table::XCellRange > aCellRange( mxTextTable, uno::UNO_QUERY_THROW ); + VbaPalette aPalette; + uno::Reference< XCollection > xCol( new SwVbaBorders( this, mxContext, aCellRange, aPalette ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +double SAL_CALL +SwVbaTable::getBottomPadding() +{ + uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW); + table::TableBorderDistances aTableBorderDistances; + xPropertySet->getPropertyValue("TableBorderDistances") >>= aTableBorderDistances; + return convertMm100ToPoint(aTableBorderDistances.BottomDistance); +} + +void SAL_CALL +SwVbaTable::setBottomPadding( double fValue ) +{ + uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW); + table::TableBorderDistances aTableBorderDistances; + aTableBorderDistances.IsBottomDistanceValid = true; + aTableBorderDistances.BottomDistance = convertPointToMm100(fValue); + xPropertySet->setPropertyValue( "TableBorderDistances", uno::Any( aTableBorderDistances ) ); +} + +double SAL_CALL +SwVbaTable::getLeftPadding() +{ + uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW); + table::TableBorderDistances aTableBorderDistances; + xPropertySet->getPropertyValue("TableBorderDistances") >>= aTableBorderDistances; + return convertMm100ToPoint(aTableBorderDistances.LeftDistance); +} + +void SAL_CALL +SwVbaTable::setLeftPadding( double fValue ) +{ + uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW); + table::TableBorderDistances aTableBorderDistances; + aTableBorderDistances.IsLeftDistanceValid = true; + aTableBorderDistances.LeftDistance = convertPointToMm100(fValue); + xPropertySet->setPropertyValue( "TableBorderDistances", uno::Any( aTableBorderDistances ) ); +} + +double SAL_CALL +SwVbaTable::getRightPadding() +{ + uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW); + table::TableBorderDistances aTableBorderDistances; + xPropertySet->getPropertyValue("TableBorderDistances") >>= aTableBorderDistances; + return convertMm100ToPoint(aTableBorderDistances.RightDistance); +} + +void SAL_CALL +SwVbaTable::setRightPadding( double fValue ) +{ + uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW); + table::TableBorderDistances aTableBorderDistances; + aTableBorderDistances.IsRightDistanceValid = true; + aTableBorderDistances.RightDistance = convertPointToMm100(fValue); + xPropertySet->setPropertyValue( "TableBorderDistances", uno::Any( aTableBorderDistances ) ); +} + +double SAL_CALL +SwVbaTable::getTopPadding() +{ + uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW); + table::TableBorderDistances aTableBorderDistances; + xPropertySet->getPropertyValue("TableBorderDistances") >>= aTableBorderDistances; + return convertMm100ToPoint(aTableBorderDistances.TopDistance); +} + +void SAL_CALL +SwVbaTable::setTopPadding( double fValue ) +{ + uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW); + table::TableBorderDistances aTableBorderDistances; + aTableBorderDistances.IsTopDistanceValid = true; + aTableBorderDistances.TopDistance = convertPointToMm100(fValue); + xPropertySet->setPropertyValue( "TableBorderDistances", uno::Any( aTableBorderDistances ) ); +} + +uno::Any SAL_CALL +SwVbaTable::Rows( const uno::Any& index ) +{ + uno::Reference< table::XTableRows > xTableRows( mxTextTable->getRows(), uno::UNO_SET_THROW ); + uno::Reference< XCollection > xCol( new SwVbaRows( this, mxContext, mxTextTable, xTableRows ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +uno::Any SAL_CALL +SwVbaTable::Columns( const uno::Any& index ) +{ + uno::Reference< table::XTableColumns > xTableColumns( mxTextTable->getColumns(), uno::UNO_SET_THROW ); + uno::Reference< XCollection > xCol( new SwVbaColumns( this, mxContext, mxTextTable, xTableColumns ) ); + if ( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +// XHelperInterface +OUString +SwVbaTable::getServiceImplName() +{ + return "SwVbaTable"; +} + +uno::Sequence<OUString> +SwVbaTable::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Table" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatable.hxx b/sw/source/ui/vba/vbatable.hxx new file mode 100644 index 0000000000..2bb802b5c6 --- /dev/null +++ b/sw/source/ui/vba/vbatable.hxx @@ -0,0 +1,59 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABLE_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBATABLE_HXX +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XTextTable.hpp> +#include <ooo/vba/word/XRange.hpp> +#include <ooo/vba/word/XTable.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XTable > SwVbaTable_BASE; + +class SwVbaTable : public SwVbaTable_BASE +{ + css::uno::Reference< css::text::XTextDocument > mxTextDocument; + css::uno::Reference< css::text::XTextTable > mxTextTable; +public: + /// @throws css::uno::RuntimeException + SwVbaTable( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xDocument, const css::uno::Reference< css::text::XTextTable >& xTextTable); + virtual css::uno::Reference< ::ooo::vba::word::XRange > SAL_CALL Range( ) override; + virtual void SAL_CALL Select( ) override; + virtual void SAL_CALL Delete( ) override; + virtual OUString SAL_CALL getName( ) override; + virtual css::uno::Any SAL_CALL Borders( const css::uno::Any& aIndex ) override; + virtual double SAL_CALL getBottomPadding( ) override; + virtual void SAL_CALL setBottomPadding( double fValue ) override; + virtual double SAL_CALL getLeftPadding( ) override; + virtual void SAL_CALL setLeftPadding( double fValue ) override; + virtual double SAL_CALL getRightPadding( ) override; + virtual void SAL_CALL setRightPadding( double fValue ) override; + virtual double SAL_CALL getTopPadding( ) override; + virtual void SAL_CALL setTopPadding( double fValue ) override; + virtual css::uno::Any SAL_CALL Rows( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL Columns( const css::uno::Any& aIndex ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatablehelper.cxx b/sw/source/ui/vba/vbatablehelper.cxx new file mode 100644 index 0000000000..2d7a1b393e --- /dev/null +++ b/sw/source/ui/vba/vbatablehelper.cxx @@ -0,0 +1,276 @@ +/* -*- 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 <comphelper/servicehelper.hxx> +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include "vbatablehelper.hxx" +#include <swtable.hxx> +#include <unotbl.hxx> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +#define UNO_TABLE_COLUMN_SUM 10000 + +SwVbaTableHelper::SwVbaTableHelper( uno::Reference< text::XTextTable > xTextTable ) : mxTextTable(std::move( xTextTable )) +{ + m_pTable = GetSwTable( mxTextTable ); +} + +SwTable* SwVbaTableHelper::GetSwTable( const uno::Reference< text::XTextTable >& xTextTable ) +{ + SwXTextTable* pXTextTable = dynamic_cast<SwXTextTable*>(xTextTable.get()); + if( !pXTextTable ) + throw uno::RuntimeException(); + + SwFrameFormat* pFrameFormat = pXTextTable->GetFrameFormat(); + if( !pFrameFormat ) + throw uno::RuntimeException(); + + SwTable* pTable = SwTable::FindTable( pFrameFormat ); + return pTable; +} + +sal_Int32 SwVbaTableHelper::getTabColumnsCount( sal_Int32 nRowIndex ) +{ + sal_Int32 nRet = 0; + if(!m_pTable->IsTableComplex()) + { + SwTableLines& rLines = m_pTable->GetTabLines(); + SwTableLine* pLine = rLines[ nRowIndex ]; + nRet = pLine->GetTabBoxes().size(); + } + return nRet; +} + +sal_Int32 SwVbaTableHelper::getTabColumnsMaxCount( ) +{ + sal_Int32 nRet = 0; + sal_Int32 nRowCount = m_pTable->GetTabLines().size(); + for( sal_Int32 index = 0; index < nRowCount; index++ ) + { + sal_Int32 nColCount = getTabColumnsCount( index ); + if( nRet < nColCount ) + nRet = nColCount; + } + return nRet; +} + +sal_Int32 SwVbaTableHelper::getTabRowIndex( const OUString& rCellName ) +{ + sal_Int32 nRet = 0; + SwTableBox* pBox = const_cast<SwTableBox*>(m_pTable->GetTableBox( rCellName )); + if( !pBox ) + throw uno::RuntimeException(); + + const SwTableLine* pLine = pBox->GetUpper(); + const SwTableLines* pLines = pLine->GetUpper() + ? &pLine->GetUpper()->GetTabLines() : &m_pTable->GetTabLines(); + nRet = pLines->GetPos( pLine ); + return nRet; +} + +sal_Int32 SwVbaTableHelper::getTabColIndex( const OUString& rCellName ) +{ + const SwTableBox* pBox = m_pTable->GetTableBox( rCellName ); + if( !pBox ) + throw uno::RuntimeException(); + return pBox->GetUpper()->GetBoxPos( pBox ); +} + +OUString SwVbaTableHelper::getColumnStr( sal_Int32 nCol ) +{ + const sal_Int32 coDiff = 52; // 'A'-'Z' 'a' - 'z' + sal_Int32 nCalc = 0; + + OUString sRet; + do{ + nCalc = nCol % coDiff; + if( nCalc >= 26 ) + sRet = OUStringChar( sal_Unicode('a' - 26 + nCalc) ) + sRet; + else + sRet = OUStringChar( sal_Unicode('A' + nCalc) ) + sRet; + + nCol = nCol - nCalc; + if( 0 == nCol ) + break; + nCol /= coDiff; + --nCol; + }while(true); + return sRet; +} + +sal_Int32 SwVbaTableHelper::getTableWidth( ) const +{ + sal_Int32 nWidth = 0; + bool isWidthRelatvie = false; + uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW ); + xTableProps->getPropertyValue("IsWidthRelative") >>= isWidthRelatvie; + if( isWidthRelatvie ) + { + xTableProps->getPropertyValue("RelativeWidth") >>= nWidth; + } + else + { + xTableProps->getPropertyValue("Width") >>= nWidth; + } + return nWidth; +} + +SwTableBox* SwVbaTableHelper::GetTabBox( sal_Int32 nCol, sal_Int32 nRow ) +{ + SwTableLines& rLines = m_pTable->GetTabLines(); + sal_Int32 nRowCount = rLines.size(); + if (nRow < 0 || nRow >= nRowCount) + throw uno::RuntimeException(); + + SwTableLine* pLine = rLines[ nRow ]; + sal_Int32 nColCount = pLine->GetTabBoxes().size(); + if (nCol < 0 || nCol >= nColCount) + throw uno::RuntimeException(); + + SwTableBox* pStart = pLine->GetTabBoxes()[ nCol ]; + + if( !pStart ) + throw uno::RuntimeException(); + + return pStart; +} + +void SwVbaTableHelper::InitTabCols( SwTabCols& rCols, const SwTableBox *pStart ) +{ + rCols.SetLeftMin ( 0 ); + rCols.SetLeft ( 0 ); + rCols.SetRight ( UNO_TABLE_COLUMN_SUM ); + rCols.SetRightMax( UNO_TABLE_COLUMN_SUM ); + m_pTable->GetTabCols( rCols, pStart ); +} + +sal_Int32 SwVbaTableHelper::GetColCount( SwTabCols const & rCols ) +{ + sal_Int32 nCount = 0; + for( size_t i = 0; i < rCols.Count(); ++i ) + if(rCols.IsHidden(i)) + nCount ++; + return rCols.Count() - nCount; +} + +sal_Int32 SwVbaTableHelper::GetRightSeparator( SwTabCols const & rCols, sal_Int32 nNum) +{ + OSL_ENSURE( nNum < GetColCount( rCols ) ,"Index out of range"); + sal_Int32 i = 0; + while( nNum >= 0 ) + { + if( !rCols.IsHidden(i) ) + nNum--; + i++; + } + return i - 1; +} + +sal_Int32 SwVbaTableHelper::GetColWidth( sal_Int32 nCol, sal_Int32 nRow ) +{ + SwTableBox* pStart = GetTabBox( nCol, nRow ); + SwTabCols aCols; + InitTabCols( aCols, pStart ); + sal_Int32 nWidth = GetColWidth( aCols, nCol ); + + sal_Int32 nTableWidth = getTableWidth( ); + double dAbsWidth = ( static_cast<double>(nWidth) / UNO_TABLE_COLUMN_SUM ) * static_cast<double>(nTableWidth); + return static_cast<sal_Int32>(Millimeter::getInPoints( static_cast<int>(dAbsWidth) )); +} + +sal_Int32 SwVbaTableHelper::GetColWidth( SwTabCols& rCols, sal_Int32 nNum ) +{ + SwTwips nWidth = 0; + + if( rCols.Count() > 0 ) + { + if(rCols.Count() == static_cast<size_t>(GetColCount( rCols ))) + { + if(static_cast<size_t>(nNum) == rCols.Count()) + nWidth = rCols.GetRight() - rCols[nNum-1]; + else + { + nWidth = rCols[nNum]; + if(nNum == 0) + nWidth -= rCols.GetLeft(); + else + nWidth -= rCols[nNum-1]; + } + } + else + { + SwTwips nRValid = nNum < GetColCount( rCols ) ? + rCols[GetRightSeparator( rCols, nNum )]: + rCols.GetRight(); + SwTwips nLValid = nNum ? + rCols[GetRightSeparator( rCols, nNum - 1 )]: + rCols.GetLeft(); + nWidth = nRValid - nLValid; + } + } + else + nWidth = rCols.GetRight(); + + return nWidth; +} + +void SwVbaTableHelper::SetColWidth( sal_Int32 _width, sal_Int32 nCol, sal_Int32 nRow, bool bCurRowOnly ) +{ + double dAbsWidth = Millimeter::getInHundredthsOfOneMillimeter( _width ); + sal_Int32 nTableWidth = getTableWidth( ); + if (!nTableWidth) + throw uno::RuntimeException(); + sal_Int32 nNewWidth = dAbsWidth/nTableWidth * UNO_TABLE_COLUMN_SUM; + + SwTableBox* pStart = GetTabBox( nCol, nRow ); + SwTabCols aOldCols; + InitTabCols( aOldCols, pStart ); + + SwTabCols aCols( aOldCols ); + if ( aCols.Count() > 0 ) + { + SwTwips nWidth = GetColWidth( aCols, nCol); + + int nDiff = nNewWidth - nWidth; + if( !nCol ) + aCols[ GetRightSeparator(aCols, 0) ] += nDiff; + else if( nCol < GetColCount( aCols ) ) + { + if(nDiff < GetColWidth( aCols, nCol + 1) - MINLAY) + aCols[ GetRightSeparator( aCols, nCol ) ] += nDiff; + else + { + int nDiffLeft = nDiff - static_cast<int>(GetColWidth( aCols, nCol + 1)) + int(MINLAY); + aCols[ GetRightSeparator( aCols, nCol ) ] += (nDiff - nDiffLeft); + aCols[ GetRightSeparator( aCols, nCol - 1 ) ] -= nDiffLeft; + } + } + else + aCols[ GetRightSeparator( aCols, nCol-1 ) ] -= nDiff; + } + else + aCols.SetRight( std::min( static_cast<tools::Long>(nNewWidth), aCols.GetRightMax()) ); + + m_pTable->SetTabCols(aCols, aOldCols, pStart, bCurRowOnly ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatablehelper.hxx b/sw/source/ui/vba/vbatablehelper.hxx new file mode 100644 index 0000000000..b3b48dc005 --- /dev/null +++ b/sw/source/ui/vba/vbatablehelper.hxx @@ -0,0 +1,67 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABLEHELPER_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBATABLEHELPER_HXX + +#include <com/sun/star/text/XTextTable.hpp> +#include <swtable.hxx> +#include <tabcol.hxx> + +class SwVbaTableHelper +{ +private: + css::uno::Reference< css::text::XTextTable > mxTextTable; + SwTable* m_pTable; + +private: + /// @throws css::uno::RuntimeException + SwTableBox* GetTabBox( sal_Int32 nCol, sal_Int32 nRow ); + void InitTabCols( SwTabCols& rCols, const SwTableBox *pStart ); + static sal_Int32 GetRightSeparator( SwTabCols const & rCols, sal_Int32 nNum); + static sal_Int32 GetColCount( SwTabCols const & rCols ); + /// @throws css::uno::RuntimeException + static sal_Int32 GetColWidth( SwTabCols& rCols, sal_Int32 nNum ); + +public: + /// @throws css::uno::RuntimeException + explicit SwVbaTableHelper( css::uno::Reference< css::text::XTextTable > xTextTable ); + /// @throws css::uno::RuntimeException + sal_Int32 getTabColumnsCount( sal_Int32 nRowIndex ); + /// @throws css::uno::RuntimeException + sal_Int32 getTabColumnsMaxCount( ); + /// @throws css::uno::RuntimeException + sal_Int32 getTabRowIndex( const OUString& sCellName ); + /// @throws css::uno::RuntimeException + sal_Int32 getTabColIndex( const OUString& sCellName ); + /// @throws css::uno::RuntimeException + sal_Int32 getTableWidth( ) const; + + /// @throws css::uno::RuntimeException + sal_Int32 GetColWidth( sal_Int32 nCol, sal_Int32 nRow = 0 ); + /// @throws css::uno::RuntimeException + void SetColWidth( sal_Int32 _width, sal_Int32 nCol, sal_Int32 nRow = 0, bool bCurRowOnly = false ); + + /// @throws css::uno::RuntimeException + static SwTable* GetSwTable( const css::uno::Reference< css::text::XTextTable >& xTextTable ); + static OUString getColumnStr( sal_Int32 nCol ); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatableofcontents.cxx b/sw/source/ui/vba/vbatableofcontents.cxx new file mode 100644 index 0000000000..e0d80cfb1c --- /dev/null +++ b/sw/source/ui/vba/vbatableofcontents.cxx @@ -0,0 +1,111 @@ +/* -*- 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 "vbatableofcontents.hxx" +#include <com/sun/star/beans/XPropertySet.hpp> +#include <ooo/vba/word/WdTabLeader.hpp> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaTableOfContents::SwVbaTableOfContents( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xDoc, uno::Reference< text::XDocumentIndex > xDocumentIndex ) : + SwVbaTableOfContents_BASE( rParent, rContext ), mxTextDocument(std::move( xDoc )), mxDocumentIndex(std::move( xDocumentIndex )) +{ + mxTocProps.set( mxDocumentIndex, uno::UNO_QUERY_THROW ); +} + +SwVbaTableOfContents::~SwVbaTableOfContents() +{ +} + +::sal_Int32 SAL_CALL SwVbaTableOfContents::getLowerHeadingLevel() +{ + sal_Int16 nLevel = 0; + mxTocProps->getPropertyValue("Level") >>= nLevel; + return nLevel; +} + +void SAL_CALL SwVbaTableOfContents::setLowerHeadingLevel( ::sal_Int32 _lowerheadinglevel ) +{ + mxTocProps->setPropertyValue("Level", uno::Any( sal_Int8( _lowerheadinglevel ) ) ); +} + +::sal_Int32 SAL_CALL SwVbaTableOfContents::getTabLeader() +{ + // not support in Writer + return word::WdTabLeader::wdTabLeaderDots; +} + +void SAL_CALL SwVbaTableOfContents::setTabLeader( ::sal_Int32 /*_tableader*/ ) +{ + // not support in Writer +} + +sal_Bool SAL_CALL SwVbaTableOfContents::getUseFields() +{ + bool bUseFields = false; + mxTocProps->getPropertyValue("CreateFromMarks") >>= bUseFields; + return bUseFields; +} + +void SAL_CALL SwVbaTableOfContents::setUseFields( sal_Bool _useFields ) +{ + mxTocProps->setPropertyValue("CreateFromMarks", uno::Any( _useFields ) ); +} + +sal_Bool SAL_CALL SwVbaTableOfContents::getUseOutlineLevels() +{ + bool bUseOutlineLevels = false; + mxTocProps->getPropertyValue("CreateFromOutline") >>= bUseOutlineLevels; + return bUseOutlineLevels; +} + +void SAL_CALL SwVbaTableOfContents::setUseOutlineLevels( sal_Bool _useOutlineLevels ) +{ + mxTocProps->setPropertyValue("CreateFromOutline", uno::Any( _useOutlineLevels ) ); +} + +void SAL_CALL SwVbaTableOfContents::Delete( ) +{ + uno::Reference< text::XTextContent > xTextContent( mxDocumentIndex, uno::UNO_QUERY_THROW ); + mxTextDocument->getText()->removeTextContent( xTextContent ); +} + +void SAL_CALL SwVbaTableOfContents::Update( ) +{ + mxDocumentIndex->update(); +} + +OUString +SwVbaTableOfContents::getServiceImplName() +{ + return "SwVbaTableOfContents"; +} + +uno::Sequence< OUString > +SwVbaTableOfContents::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.TableOfContents" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatableofcontents.hxx b/sw/source/ui/vba/vbatableofcontents.hxx new file mode 100644 index 0000000000..69ccd9394f --- /dev/null +++ b/sw/source/ui/vba/vbatableofcontents.hxx @@ -0,0 +1,61 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABLEOFCONTENTS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBATABLEOFCONTENTS_HXX + +#include <ooo/vba/word/XTableOfContents.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XDocumentIndex.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XTableOfContents > SwVbaTableOfContents_BASE; + +class SwVbaTableOfContents : public SwVbaTableOfContents_BASE +{ +private: + css::uno::Reference< css::text::XTextDocument > mxTextDocument; + css::uno::Reference< css::text::XDocumentIndex > mxDocumentIndex; + css::uno::Reference< css::beans::XPropertySet > mxTocProps; + +public: + /// @throws css::uno::RuntimeException + SwVbaTableOfContents( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xDoc, css::uno::Reference< css::text::XDocumentIndex > xDocumentIndex ); + virtual ~SwVbaTableOfContents() override; + + // Attributes + virtual ::sal_Int32 SAL_CALL getLowerHeadingLevel() override; + virtual void SAL_CALL setLowerHeadingLevel( ::sal_Int32 _lowerheadinglevel ) override; + virtual ::sal_Int32 SAL_CALL getTabLeader() override; + virtual void SAL_CALL setTabLeader( ::sal_Int32 _tableader ) override; + virtual sal_Bool SAL_CALL getUseFields() override; + virtual void SAL_CALL setUseFields( sal_Bool _useFields ) override; + virtual sal_Bool SAL_CALL getUseOutlineLevels() override; + virtual void SAL_CALL setUseOutlineLevels( sal_Bool _useOutlineLevels ) override; + + // Methods + virtual void SAL_CALL Delete( ) override; + virtual void SAL_CALL Update( ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBATABLEOFCONTENTS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatables.cxx b/sw/source/ui/vba/vbatables.cxx new file mode 100644 index 0000000000..b7aa4cadda --- /dev/null +++ b/sw/source/ui/vba/vbatables.cxx @@ -0,0 +1,239 @@ +/* -*- 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 "vbatables.hxx" +#include "vbatable.hxx" +#include "vbarange.hxx" +#include "wordvbahelper.hxx" +#include <com/sun/star/text/XTextTable.hpp> +#include <com/sun/star/text/XTextTablesSupplier.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <cppuhelper/implbase.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace css; + +static uno::Reference< container::XIndexAccess > lcl_getTables( const uno::Reference< frame::XModel >& xDoc ) +{ + uno::Reference< container::XIndexAccess > xTables; + uno::Reference< text::XTextTablesSupplier > xSupp( xDoc, uno::UNO_QUERY ); + if ( xSupp.is() ) + xTables.set( xSupp->getTextTables(), uno::UNO_QUERY_THROW ); + return xTables; +} + +static uno::Any lcl_createTable( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xDocument, const uno::Any& aSource ) +{ + uno::Reference< text::XTextTable > xTextTable( aSource, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextDocument > xTextDocument( xDocument, uno::UNO_QUERY_THROW ); + uno::Reference< word::XTable > xTable( new SwVbaTable( xParent, xContext, xTextDocument, xTextTable ) ); + return uno::Any( xTable ); +} + +static bool lcl_isInHeaderFooter( const uno::Reference< text::XTextTable >& xTable ) +{ + uno::Reference< text::XTextContent > xTextContent( xTable, uno::UNO_QUERY_THROW ); + uno::Reference< text::XText > xText = xTextContent->getAnchor()->getText(); + uno::Reference< lang::XServiceInfo > xServiceInfo( xText, uno::UNO_QUERY ); + if ( !xServiceInfo ) + return false; + OUString aImplName = xServiceInfo->getImplementationName(); + return aImplName == "SwXHeadFootText"; +} + +typedef std::vector< uno::Reference< text::XTextTable > > XTextTableVec; + +namespace { + +class TableCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess, + container::XNameAccess > +{ + XTextTableVec mxTables; + XTextTableVec::iterator m_cachePos; + +public: + explicit TableCollectionHelper( const uno::Reference< frame::XModel >& xDocument ) + { + // only count the tables in the body text, not in the header/footer + uno::Reference< container::XIndexAccess > xTables = lcl_getTables( xDocument ); + sal_Int32 nCount = xTables->getCount(); + for( sal_Int32 i = 0; i < nCount; i++ ) + { + uno::Reference< text::XTextTable > xTable( xTables->getByIndex( i ) , uno::UNO_QUERY_THROW ); + if( !lcl_isInHeaderFooter( xTable ) ) + mxTables.push_back( xTable ); + } + m_cachePos = mxTables.begin(); + } + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount( ) override + { + return mxTables.size(); + } + virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override + { + if ( Index < 0 || Index >= getCount() ) + throw lang::IndexOutOfBoundsException(); + uno::Reference< text::XTextTable > xTable( mxTables[ Index ], uno::UNO_SET_THROW ); + return uno::Any( xTable ); + } + // XElementAccess + virtual uno::Type SAL_CALL getElementType( ) override { return cppu::UnoType<text::XTextTable>::get(); } + virtual sal_Bool SAL_CALL hasElements( ) override { return getCount() > 0 ; } + // XNameAccess + virtual uno::Any SAL_CALL getByName( const OUString& aName ) override + { + if ( !hasByName(aName) ) + throw container::NoSuchElementException(); + uno::Reference< text::XTextTable > xTable( *m_cachePos, uno::UNO_SET_THROW ); + return uno::Any( xTable ); + } + virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override + { + uno::Sequence< OUString > sNames( mxTables.size() ); + OUString* pString = sNames.getArray(); + for ( const auto& rxTable : mxTables ) + { + uno::Reference< container::XNamed > xName( rxTable, uno::UNO_QUERY_THROW ); + *pString = xName->getName(); + ++pString; + } + return sNames; + } + virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override + { + m_cachePos = mxTables.begin(); + XTextTableVec::iterator it_end = mxTables.end(); + for ( ; m_cachePos != it_end; ++m_cachePos ) + { + uno::Reference< container::XNamed > xName( *m_cachePos, uno::UNO_QUERY_THROW ); + if ( aName.equalsIgnoreAsciiCase( xName->getName() ) ) + break; + } + return ( m_cachePos != it_end ); + } +}; + +class TableEnumerationImpl : public ::cppu::WeakImplHelper< css::container::XEnumeration > +{ + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< frame::XModel > mxDocument; + uno::Reference< container::XIndexAccess > mxIndexAccess; + sal_Int32 mnCurIndex; +public: + TableEnumerationImpl( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xDocument, uno::Reference< container::XIndexAccess > xIndexAccess ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxDocument(std::move( xDocument )), mxIndexAccess(std::move( xIndexAccess )), mnCurIndex(0) + { + } + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( mnCurIndex < mxIndexAccess->getCount() ); + } + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( !hasMoreElements() ) + throw container::NoSuchElementException(); + return lcl_createTable( mxParent, mxContext, mxDocument, mxIndexAccess->getByIndex( mnCurIndex++ ) ); + } + +}; + +} + +SwVbaTables::SwVbaTables( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xDocument ) : SwVbaTables_BASE( xParent, xContext , uno::Reference< container::XIndexAccess >( new TableCollectionHelper( xDocument ) ) ), mxDocument( xDocument ) +{ +} + +uno::Reference< word::XTable > SAL_CALL +SwVbaTables::Add( const uno::Reference< word::XRange >& Range, const uno::Any& NumRows, const uno::Any& NumColumns, const uno::Any& /*DefaultTableBehavior*/, const uno::Any& /*AutoFitBehavior*/ ) +{ + sal_Int32 nCols = 0; + sal_Int32 nRows = 0; + SwVbaRange* pVbaRange = dynamic_cast< SwVbaRange* >( Range.get() ); + // Preconditions + if ( !( pVbaRange && ( NumRows >>= nRows ) && ( NumColumns >>= nCols ) ) ) + throw uno::RuntimeException(); // #FIXME better exception?? + if ( nCols <= 0 || nRows <= 0 ) + throw uno::RuntimeException(); // #FIXME better exception?? + + uno::Reference< frame::XModel > xModel( pVbaRange->getDocument(), uno::UNO_QUERY_THROW ); + uno::Reference< lang::XMultiServiceFactory > xMsf( xModel, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextRange > xTextRange = pVbaRange->getXTextRange(); + + uno::Reference< text::XTextTable > xTable; + xTable.set( xMsf->createInstance("com.sun.star.text.TextTable"), uno::UNO_QUERY_THROW ); + + xTable->initialize( nRows, nCols ); + uno::Reference< text::XText > xText = xTextRange->getText(); + uno::Reference< text::XTextContent > xContext( xTable, uno::UNO_QUERY_THROW ); + + xText->insertTextContent( xTextRange, xContext, true ); + + // move the current cursor to the first table cell + uno::Reference< table::XCellRange > xCellRange( xTable, uno::UNO_QUERY_THROW ); + uno::Reference< text::XText> xFirstCellText( xCellRange->getCellByPosition(0, 0), uno::UNO_QUERY_THROW ); + word::getXTextViewCursor( mxDocument )->gotoRange( xFirstCellText->getStart(), false ); + + uno::Reference< word::XTable > xVBATable( new SwVbaTable( mxParent, mxContext, pVbaRange->getDocument(), xTable ) ); + return xVBATable; +} + +uno::Reference< container::XEnumeration > SAL_CALL +SwVbaTables::createEnumeration() +{ + return new TableEnumerationImpl( mxParent, mxContext, mxDocument, m_xIndexAccess ); +} + +// ScVbaCollectionBaseImpl +uno::Any +SwVbaTables::createCollectionObject( const uno::Any& aSource ) +{ + return lcl_createTable( mxParent, mxContext, mxDocument, aSource ); +} + +// XHelperInterface +OUString +SwVbaTables::getServiceImplName() +{ + return "SwVbaTables"; +} + +// XEnumerationAccess +uno::Type SAL_CALL +SwVbaTables::getElementType() +{ + return cppu::UnoType<word::XTable>::get(); +} + +uno::Sequence<OUString> +SwVbaTables::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Tables" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatables.hxx b/sw/source/ui/vba/vbatables.hxx new file mode 100644 index 0000000000..ae7de0b00c --- /dev/null +++ b/sw/source/ui/vba/vbatables.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 . + */ + +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABLES_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBATABLES_HXX + +#include <ooo/vba/word/XTables.hpp> +#include <vbahelper/vbacollectionimpl.hxx> + +typedef CollTestImplHelper< ov::word::XTables > SwVbaTables_BASE; + +class SwVbaTables : public SwVbaTables_BASE +{ + css::uno::Reference< css::frame::XModel > mxDocument; +public: + SwVbaTables( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xDocument ); + // XTables + virtual css::uno::Reference< ov::word::XTable > SAL_CALL Add( const css::uno::Reference< ::ooo::vba::word::XRange >& Range, const css::uno::Any& NumRows, const css::uno::Any& NumColumns, const css::uno::Any& DefaultTableBehavior, const css::uno::Any& AutoFitBehavior ) override; + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + // ScVbaCollectionBaseImpl + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatablesofcontents.cxx b/sw/source/ui/vba/vbatablesofcontents.cxx new file mode 100644 index 0000000000..8df156fecf --- /dev/null +++ b/sw/source/ui/vba/vbatablesofcontents.cxx @@ -0,0 +1,186 @@ +/* -*- 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 "vbatablesofcontents.hxx" +#include "vbatableofcontents.hxx" +#include "vbarange.hxx" +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/text/XDocumentIndexesSupplier.hpp> +#include <cppuhelper/implbase.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class TablesOfContentsEnumWrapper : public EnumerationHelper_BASE +{ + uno::Reference< container::XIndexAccess > mxIndexAccess; + sal_Int32 m_nIndex; + +public: + explicit TablesOfContentsEnumWrapper( uno::Reference< container::XIndexAccess > xIndexAccess ) : mxIndexAccess(std::move( xIndexAccess )), m_nIndex( 0 ) + { + } + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( m_nIndex < mxIndexAccess->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if( m_nIndex < mxIndexAccess->getCount() ) + { + return mxIndexAccess->getByIndex( m_nIndex++ ); + } + throw container::NoSuchElementException(); + } +}; + +class TableOfContentsCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess, + container::XEnumerationAccess > +{ +private: + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< text::XTextDocument > mxTextDocument; + std::vector< uno::Reference< text::XDocumentIndex > > maToc; + +public: + /// @throws uno::RuntimeException + TableOfContentsCollectionHelper( uno::Reference< ov::XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< text::XTextDocument > xDoc ): mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxTextDocument(std::move( xDoc )) + { + uno::Reference< text::XDocumentIndexesSupplier > xDocIndexSupp( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xDocIndexes = xDocIndexSupp->getDocumentIndexes(); + sal_Int32 nCount = xDocIndexes->getCount(); + for( sal_Int32 i = 0; i < nCount; i++ ) + { + uno::Reference< text::XDocumentIndex > xToc( xDocIndexes->getByIndex(i), uno::UNO_QUERY_THROW ); + if( xToc->getServiceName() == "com.sun.star.text.ContentIndex" ) + { + maToc.push_back( xToc ); + } + } + } + + virtual sal_Int32 SAL_CALL getCount( ) override + { + return maToc.size(); + } + virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override + { + if ( Index < 0 || Index >= getCount() ) + throw lang::IndexOutOfBoundsException(); + + uno::Reference< text::XDocumentIndex > xToc( maToc[Index], uno::UNO_SET_THROW ); + return uno::Any( uno::Reference< word::XTableOfContents >( new SwVbaTableOfContents( mxParent, mxContext, mxTextDocument, xToc ) ) ); + } + virtual uno::Type SAL_CALL getElementType( ) override + { + return cppu::UnoType<word::XTableOfContents>::get(); + } + virtual sal_Bool SAL_CALL hasElements( ) override + { + return true; + } + // XEnumerationAccess + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override + { + return new TablesOfContentsEnumWrapper( this ); + } +}; + +} + +SwVbaTablesOfContents::SwVbaTablesOfContents( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< text::XTextDocument >& xDoc ) : SwVbaTablesOfContents_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new TableOfContentsCollectionHelper( xParent, xContext, xDoc ) ) ), mxTextDocument( xDoc ) +{ +} + +uno::Reference< word::XTableOfContents > SAL_CALL +SwVbaTablesOfContents::Add( const uno::Reference< word::XRange >& Range, const uno::Any& /*UseHeadingStyles*/, const uno::Any& /*UpperHeadingLevel*/, const uno::Any& LowerHeadingLevel, const uno::Any& UseFields, const uno::Any& /*TableID*/, const uno::Any& /*RightAlignPageNumbers*/, const uno::Any& /*IncludePageNumbers*/, const uno::Any& /*AddedStyles*/, const uno::Any& /*UseHyperlinks*/, const uno::Any& /*HidePageNumbersInWeb*/, const uno::Any& /*UseOutlineLevels*/ ) +{ + uno::Reference< lang::XMultiServiceFactory > xDocMSF( mxTextDocument, uno::UNO_QUERY_THROW ); + uno::Reference< text::XDocumentIndex > xDocumentIndex( xDocMSF->createInstance("com.sun.star.text.ContentIndex"), uno::UNO_QUERY_THROW ); + + uno::Reference< beans::XPropertySet > xTocProps( xDocumentIndex, uno::UNO_QUERY_THROW ); + xTocProps->setPropertyValue("IsProtected", uno::Any( false ) ); + + uno::Reference< word::XTableOfContents > xToc( new SwVbaTableOfContents( this, mxContext, mxTextDocument, xDocumentIndex ) ); + + sal_Int32 nLowerHeadingLevel = 9; + if( LowerHeadingLevel.hasValue() ) + LowerHeadingLevel >>= nLowerHeadingLevel; + xToc->setLowerHeadingLevel( nLowerHeadingLevel ); + + bool bUseFields = false; + if( UseFields.hasValue() ) + UseFields >>= bUseFields; + xToc->setUseFields( bUseFields ); + + xToc->setUseOutlineLevels( true ); + + SwVbaRange* pVbaRange = dynamic_cast<SwVbaRange*>( Range.get() ); + if( !pVbaRange ) + throw uno::RuntimeException(); + + uno::Reference< text::XTextRange > xTextRange = pVbaRange->getXTextRange(); + uno::Reference< text::XText > xText = pVbaRange->getXText(); + uno::Reference< text::XTextContent > xTextContent( xDocumentIndex, uno::UNO_QUERY_THROW ); + xText->insertTextContent( xTextRange, xTextContent, false ); + xToc->Update(); + + return xToc; +} + +// XEnumerationAccess +uno::Type +SwVbaTablesOfContents::getElementType() +{ + return cppu::UnoType<word::XTableOfContents>::get(); +} +uno::Reference< container::XEnumeration > +SwVbaTablesOfContents::createEnumeration() +{ + return new TablesOfContentsEnumWrapper( m_xIndexAccess ); +} + +uno::Any +SwVbaTablesOfContents::createCollectionObject( const uno::Any& aSource ) +{ + return aSource; +} + +OUString +SwVbaTablesOfContents::getServiceImplName() +{ + return "SwVbaTablesOfContents"; +} + +uno::Sequence<OUString> +SwVbaTablesOfContents::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.TablesOfContents" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatablesofcontents.hxx b/sw/source/ui/vba/vbatablesofcontents.hxx new file mode 100644 index 0000000000..37048ae1bc --- /dev/null +++ b/sw/source/ui/vba/vbatablesofcontents.hxx @@ -0,0 +1,54 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABLESOFCONTENTS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBATABLESOFCONTENTS_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XTablesOfContents.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <ooo/vba/word/XTableOfContents.hpp> +#include <ooo/vba/word/XRange.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XTablesOfContents > SwVbaTablesOfContents_BASE; + +class SwVbaTablesOfContents : public SwVbaTablesOfContents_BASE +{ +private: + css::uno::Reference< css::text::XTextDocument > mxTextDocument; + +public: + /// @throws css::uno::RuntimeException + SwVbaTablesOfContents( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::text::XTextDocument >& xDoc ); + + // Methods + virtual css::uno::Reference< ::ooo::vba::word::XTableOfContents > SAL_CALL Add( const css::uno::Reference< ::ooo::vba::word::XRange >& Range, const css::uno::Any& UseHeadingStyles, const css::uno::Any& UpperHeadingLevel, const css::uno::Any& LowerHeadingLevel, const css::uno::Any& UseFields, const css::uno::Any& TableID, const css::uno::Any& RightAlignPageNumbers, const css::uno::Any& IncludePageNumbers, const css::uno::Any& AddedStyles, const css::uno::Any& UseHyperlinks, const css::uno::Any& HidePageNumbersInWeb, const css::uno::Any& UseOutlineLevels ) override; + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaTablesOfContents_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBATABLESOFCONTENTS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatabstop.cxx b/sw/source/ui/vba/vbatabstop.cxx new file mode 100644 index 0000000000..8ebfdfa421 --- /dev/null +++ b/sw/source/ui/vba/vbatabstop.cxx @@ -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 . + */ +#include "vbatabstop.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaTabStop::SwVbaTabStop( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext ) : SwVbaTabStop_BASE( rParent, rContext ) +{ +} + +SwVbaTabStop::~SwVbaTabStop() +{ +} + +OUString +SwVbaTabStop::getServiceImplName() +{ + return "SwVbaTabStop"; +} + +uno::Sequence< OUString > +SwVbaTabStop::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.TabStop" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatabstop.hxx b/sw/source/ui/vba/vbatabstop.hxx new file mode 100644 index 0000000000..3be2c29e47 --- /dev/null +++ b/sw/source/ui/vba/vbatabstop.hxx @@ -0,0 +1,41 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABSTOP_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBATABSTOP_HXX + +#include <ooo/vba/word/XTabStop.hpp> +#include <vbahelper/vbahelperinterface.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XTabStop> SwVbaTabStop_BASE; + +class SwVbaTabStop : public SwVbaTabStop_BASE +{ +public: + /// @throws css::uno::RuntimeException + SwVbaTabStop(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext); + virtual ~SwVbaTabStop() override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBATABSTOP_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatabstops.cxx b/sw/source/ui/vba/vbatabstops.cxx new file mode 100644 index 0000000000..7d2d86824a --- /dev/null +++ b/sw/source/ui/vba/vbatabstops.cxx @@ -0,0 +1,270 @@ +/* -*- 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 "vbatabstops.hxx" +#include "vbatabstop.hxx" +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/style/TabAlign.hpp> +#include <com/sun/star/style/TabStop.hpp> +#include <ooo/vba/word/WdTabLeader.hpp> +#include <ooo/vba/word/WdTabAlignment.hpp> +#include <basic/sberrors.hxx> +#include <cppuhelper/implbase.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +/// @throws uno::RuntimeException +static uno::Sequence< style::TabStop > lcl_getTabStops( const uno::Reference< beans::XPropertySet >& xParaProps ) +{ + uno::Sequence< style::TabStop > aSeq; + xParaProps->getPropertyValue("ParaTabStops") >>= aSeq; + return aSeq; +} + +/// @throws uno::RuntimeException +static void lcl_setTabStops( const uno::Reference< beans::XPropertySet >& xParaProps, const uno::Sequence< style::TabStop >& aSeq ) +{ + xParaProps->setPropertyValue("ParaTabStops", uno::Any( aSeq ) ); +} + +namespace { + +class TabStopsEnumWrapper : public EnumerationHelper_BASE +{ + uno::Reference< container::XIndexAccess > mxIndexAccess; + sal_Int32 m_nIndex; + +public: + explicit TabStopsEnumWrapper( uno::Reference< container::XIndexAccess > xIndexAccess ) : mxIndexAccess(std::move( xIndexAccess )), m_nIndex( 0 ) + { + } + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( m_nIndex < mxIndexAccess->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if( m_nIndex < mxIndexAccess->getCount() ) + { + return mxIndexAccess->getByIndex( m_nIndex++ ); + } + throw container::NoSuchElementException(); + } +}; + +class TabStopCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess, + container::XEnumerationAccess > +{ +private: + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + sal_Int32 mnTabStops; + +public: + /// @throws css::uno::RuntimeException + TabStopCollectionHelper( css::uno::Reference< ov::XHelperInterface > xParent, css::uno::Reference< css::uno::XComponentContext > xContext, const css::uno::Reference< css::beans::XPropertySet >& xParaProps ): mxParent(std::move( xParent )), mxContext(std::move( xContext )), mnTabStops(lcl_getTabStops( xParaProps ).getLength()) + { + } + + virtual sal_Int32 SAL_CALL getCount( ) override + { + return mnTabStops; + } + virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override + { + if ( Index < 0 || Index >= getCount() ) + throw css::lang::IndexOutOfBoundsException(); + + return uno::Any( uno::Reference< word::XTabStop >( new SwVbaTabStop( mxParent, mxContext ) ) ); + } + virtual uno::Type SAL_CALL getElementType( ) override + { + return cppu::UnoType<word::XTabStop>::get(); + } + virtual sal_Bool SAL_CALL hasElements( ) override + { + return true; + } + // XEnumerationAccess + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override + { + return new TabStopsEnumWrapper( this ); + } +}; + +} + +SwVbaTabStops::SwVbaTabStops( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< beans::XPropertySet >& xParaProps ) : SwVbaTabStops_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new TabStopCollectionHelper( xParent, xContext, xParaProps ) ) ), mxParaProps( xParaProps ) +{ +} + +uno::Reference< word::XTabStop > SAL_CALL SwVbaTabStops::Add( float Position, const uno::Any& Alignment, const uno::Any& Leader ) +{ + sal_Int32 nPosition = Millimeter::getInHundredthsOfOneMillimeter( Position ); + + style::TabAlign nAlign = style::TabAlign_LEFT; + if( Alignment.hasValue() ) + { + sal_Int32 wdAlign = word::WdTabAlignment::wdAlignTabLeft; + Alignment >>= wdAlign; + switch( wdAlign ) + { + case word::WdTabAlignment::wdAlignTabLeft: + { + nAlign = style::TabAlign_LEFT; + break; + } + case word::WdTabAlignment::wdAlignTabRight: + { + nAlign = style::TabAlign_RIGHT; + break; + } + case word::WdTabAlignment::wdAlignTabCenter: + { + nAlign = style::TabAlign_CENTER; + break; + } + case word::WdTabAlignment::wdAlignTabDecimal: + { + nAlign = style::TabAlign_DECIMAL; + break; + } + case word::WdTabAlignment::wdAlignTabBar: + case word::WdTabAlignment::wdAlignTabList: + { + DebugHelper::basicexception( ERRCODE_BASIC_NOT_IMPLEMENTED, {} ); + break; + } + default: + { + //left + } + } + } + + sal_Unicode cLeader = ' '; // default is space + if( Leader.hasValue() ) + { + sal_Int32 wdLeader = word::WdTabLeader::wdTabLeaderSpaces; + Leader >>= wdLeader; + switch( wdLeader ) + { + case word::WdTabLeader::wdTabLeaderSpaces: + { + cLeader = ' '; + break; + } + case word::WdTabLeader::wdTabLeaderMiddleDot: + { + cLeader = 183; // U+00B7 MIDDLE DOT + break; + } + case word::WdTabLeader::wdTabLeaderDots: + { + cLeader = '.'; + break; + } + case word::WdTabLeader::wdTabLeaderDashes: + case word::WdTabLeader::wdTabLeaderHeavy: + case word::WdTabLeader::wdTabLeaderLines: + { + cLeader = '_'; + break; + } + default: + { + //left + } + } + } + + style::TabStop aTab; + aTab.Position = nPosition; + aTab.Alignment = nAlign; + aTab.DecimalChar = '.'; // default value + aTab.FillChar = cLeader; + + uno::Sequence< style::TabStop > aOldTabs = lcl_getTabStops( mxParaProps ); + auto [begin, end] = asNonConstRange(aOldTabs); + + style::TabStop* pOldTab = std::find_if(begin, end, + [nPosition](const style::TabStop& rTab) { return rTab.Position == nPosition; }); + bool bOverWriter = pOldTab != end; + if( bOverWriter ) + { + *pOldTab = aTab; + lcl_setTabStops( mxParaProps, aOldTabs ); + } + else + { + sal_Int32 nTabs = aOldTabs.getLength(); + uno::Sequence< style::TabStop > aNewTabs( nTabs + 1 ); + + auto it = aNewTabs.getArray(); + *it = aTab; + std::copy(begin, end, std::next(it)); + lcl_setTabStops( mxParaProps, aNewTabs ); + } + + return uno::Reference< word::XTabStop >( new SwVbaTabStop( this, mxContext ) ); +} + +void SAL_CALL SwVbaTabStops::ClearAll() +{ + uno::Sequence< style::TabStop > aSeq; + lcl_setTabStops( mxParaProps, aSeq ); +} + +// XEnumerationAccess +uno::Type +SwVbaTabStops::getElementType() +{ + return cppu::UnoType<word::XTabStop>::get(); +} +uno::Reference< container::XEnumeration > +SwVbaTabStops::createEnumeration() +{ + return new TabStopsEnumWrapper( m_xIndexAccess ); +} + +uno::Any +SwVbaTabStops::createCollectionObject( const css::uno::Any& aSource ) +{ + return aSource; +} + +OUString +SwVbaTabStops::getServiceImplName() +{ + return "SwVbaTabStops"; +} + +css::uno::Sequence<OUString> +SwVbaTabStops::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.TabStops" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatabstops.hxx b/sw/source/ui/vba/vbatabstops.hxx new file mode 100644 index 0000000000..66a163d492 --- /dev/null +++ b/sw/source/ui/vba/vbatabstops.hxx @@ -0,0 +1,53 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABSTOPS_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBATABSTOPS_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XTabStops.hpp> +#include <ooo/vba/word/XTabStop.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XTabStops > SwVbaTabStops_BASE; + +class SwVbaTabStops : public SwVbaTabStops_BASE +{ +private: + css::uno::Reference< css::beans::XPropertySet > mxParaProps; + +public: + /// @throws css::uno::RuntimeException + SwVbaTabStops( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertySet >& xParaProps ); + + // Methods + virtual css::uno::Reference< ::ooo::vba::word::XTabStop > SAL_CALL Add( float Position, const css::uno::Any& Alignment, const css::uno::Any& Leader ) override; + virtual void SAL_CALL ClearAll( ) override; + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaTabStops_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBATABSTOPS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatemplate.cxx b/sw/source/ui/vba/vbatemplate.cxx new file mode 100644 index 0000000000..f05b699187 --- /dev/null +++ b/sw/source/ui/vba/vbatemplate.cxx @@ -0,0 +1,129 @@ +/* -*- 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 "vbatemplate.hxx" +#include "vbaautotextentry.hxx" +#include <com/sun/star/text/AutoTextContainer.hpp> +#include <comphelper/processfactory.hxx> +#include <tools/urlobj.hxx> +#include <rtl/character.hxx> +#include <osl/file.hxx> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +static OUString lcl_CheckGroupName( std::u16string_view aGroupName ) +{ + OUStringBuffer sRet(aGroupName.size()); + //group name should contain only A-Z and a-z and spaces + for( size_t i = 0; i < aGroupName.size(); i++ ) + { + sal_Unicode cChar = aGroupName[i]; + if (rtl::isAsciiAlphanumeric(cChar) || + cChar == '_' || cChar == 0x20) + { + sRet.append(cChar); + } + } + sRet.strip(' '); + return sRet.makeStringAndClear(); +} + +SwVbaTemplate::SwVbaTemplate( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, OUString aFullUrl ) + : SwVbaTemplate_BASE( rParent, rContext ), msFullUrl(std::move( aFullUrl )) +{ +} + +SwVbaTemplate::~SwVbaTemplate() +{ +} + +OUString +SwVbaTemplate::getName() +{ + OUString sName; + if( !msFullUrl.isEmpty() ) + { + INetURLObject aURL( msFullUrl ); + ::osl::File::getSystemPathFromFileURL( aURL.GetLastName(), sName ); + } + return sName; +} + +OUString +SwVbaTemplate::getPath() +{ + OUString sPath; + if( !msFullUrl.isEmpty() ) + { + INetURLObject aURL( msFullUrl ); + OUString sURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ) ); + sURL = sURL.copy( 0, sURL.getLength() - aURL.GetLastName().getLength() - 1 ); + ::osl::File::getSystemPathFromFileURL( sURL, sPath ); + } + return sPath; +} + +uno::Any SAL_CALL +SwVbaTemplate::AutoTextEntries( const uno::Any& index ) +{ + uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext(); + uno::Reference< text::XAutoTextContainer2 > xAutoTextContainer = text::AutoTextContainer::create( xContext ); + + // the default template is "Normal.dot" in Word. + OUString sGroup("Normal"); + OUString sName = getName(); + sal_Int32 nIndex = sName.lastIndexOf( '.' ); + if( nIndex > 0 ) + { + sGroup = sName.copy( 0, sName.lastIndexOf( '.' ) ); + } + OUString sNewGroup = lcl_CheckGroupName( sGroup ); + + uno::Reference< container::XIndexAccess > xGroup; + if( !xAutoTextContainer->hasByName( sNewGroup ) ) + { + throw uno::RuntimeException("Auto Text Entry doesn't exist" ); + } + + xGroup.set( xAutoTextContainer->getByName( sNewGroup ), uno::UNO_QUERY_THROW ); + + uno::Reference< XCollection > xCol( new SwVbaAutoTextEntries( this, mxContext, xGroup ) ); + if( index.hasValue() ) + return xCol->Item( index, uno::Any() ); + return uno::Any( xCol ); +} + +OUString +SwVbaTemplate::getServiceImplName() +{ + return "SwVbaTemplate"; +} + +uno::Sequence< OUString > +SwVbaTemplate::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Template" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbatemplate.hxx b/sw/source/ui/vba/vbatemplate.hxx new file mode 100644 index 0000000000..146684b18c --- /dev/null +++ b/sw/source/ui/vba/vbatemplate.hxx @@ -0,0 +1,46 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATEMPLATE_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBATEMPLATE_HXX + +#include <ooo/vba/word/XTemplate.hpp> +#include <vbahelper/vbahelperinterface.hxx> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XTemplate > SwVbaTemplate_BASE; + +class SwVbaTemplate : public SwVbaTemplate_BASE +{ +private: + OUString msFullUrl; +public: + SwVbaTemplate( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, + OUString ); + virtual ~SwVbaTemplate() override; + + // XTemplate + virtual OUString SAL_CALL getName() override; + virtual OUString SAL_CALL getPath() override; + virtual css::uno::Any SAL_CALL AutoTextEntries( const css::uno::Any& index ) override; + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBATEMPLATE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbavariable.cxx b/sw/source/ui/vba/vbavariable.cxx new file mode 100644 index 0000000000..dea82686e1 --- /dev/null +++ b/sw/source/ui/vba/vbavariable.cxx @@ -0,0 +1,92 @@ +/* -*- 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 "vbavariable.hxx" +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <utility> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwVbaVariable::SwVbaVariable( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, + uno::Reference< beans::XPropertyAccess > xUserDefined, OUString aVariableName ) : + SwVbaVariable_BASE( rParent, rContext ), mxUserDefined(std::move( xUserDefined )), maVariableName(std::move( aVariableName )) +{ +} + +SwVbaVariable::~SwVbaVariable() +{ +} + +OUString SAL_CALL +SwVbaVariable::getName() +{ + return maVariableName; +} + +void SAL_CALL +SwVbaVariable::setName( const OUString& ) +{ + throw uno::RuntimeException(" Fail to set name" ); +} + +uno::Any SAL_CALL +SwVbaVariable::getValue() +{ + uno::Reference< beans::XPropertySet > xProp( mxUserDefined, uno::UNO_QUERY_THROW ); + return xProp->getPropertyValue( maVariableName ); +} + +void SAL_CALL +SwVbaVariable::setValue( const uno::Any& rValue ) +{ + // FIXME: fail to set the value if the new type of value is different from the original one. + uno::Reference< beans::XPropertySet > xProp( mxUserDefined, uno::UNO_QUERY_THROW ); + xProp->setPropertyValue( maVariableName, rValue ); +} + +sal_Int32 SAL_CALL +SwVbaVariable::getIndex() +{ + const uno::Sequence< beans::PropertyValue > props = mxUserDefined->getPropertyValues(); + auto pProp = std::find_if(props.begin(), props.end(), + [this](const beans::PropertyValue& rProp) { return rProp.Name == maVariableName; }); + if (pProp != props.end()) + return static_cast<sal_Int32>(std::distance(props.begin(), pProp)) + 1; + + return 0; +} + +OUString +SwVbaVariable::getServiceImplName() +{ + return "SwVbaVariable"; +} + +uno::Sequence< OUString > +SwVbaVariable::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Variable" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbavariable.hxx b/sw/source/ui/vba/vbavariable.hxx new file mode 100644 index 0000000000..6b3ab37c78 --- /dev/null +++ b/sw/source/ui/vba/vbavariable.hxx @@ -0,0 +1,53 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAVARIABLE_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAVARIABLE_HXX + +#include <ooo/vba/word/XVariable.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/beans/XPropertyAccess.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XVariable > SwVbaVariable_BASE; + +class SwVbaVariable : public SwVbaVariable_BASE +{ +private: + css::uno::Reference< css::beans::XPropertyAccess > mxUserDefined; + OUString maVariableName; + +public: + /// @throws css::uno::RuntimeException + SwVbaVariable( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, + css::uno::Reference< css::beans::XPropertyAccess > xUserDefined, OUString aName ); + virtual ~SwVbaVariable() override; + + // XVariable + virtual OUString SAL_CALL getName() override; + virtual void SAL_CALL setName( const OUString& ) override; + virtual css::uno::Any SAL_CALL getValue() override; + virtual void SAL_CALL setValue( const css::uno::Any& rValue ) override; + virtual sal_Int32 SAL_CALL getIndex() override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAVARIABLE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbavariables.cxx b/sw/source/ui/vba/vbavariables.cxx new file mode 100644 index 0000000000..6505eb23e0 --- /dev/null +++ b/sw/source/ui/vba/vbavariables.cxx @@ -0,0 +1,95 @@ +/* -*- 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 "vbavariables.hxx" +#include "vbavariable.hxx" +#include <com/sun/star/beans/XPropertyContainer.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +/// @throws uno::RuntimeException +static uno::Reference< container::XIndexAccess > createVariablesAccess( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< beans::XPropertyAccess >& xUserDefined ) +{ + // FIXME: the performance is poor? + XNamedObjectCollectionHelper< word::XVariable >::XNamedVec aVariables; + const uno::Sequence< beans::PropertyValue > props = xUserDefined->getPropertyValues(); + sal_Int32 nCount = props.getLength(); + aVariables.reserve( nCount ); + std::transform(props.begin(), props.end(), std::back_inserter(aVariables), + [&xParent, &xContext, &xUserDefined](const beans::PropertyValue& rProp) -> uno::Reference< word::XVariable > { + return uno::Reference< word::XVariable > ( new SwVbaVariable( xParent, xContext, xUserDefined, rProp.Name ) ); }); + + uno::Reference< container::XIndexAccess > xVariables( new XNamedObjectCollectionHelper< word::XVariable >( std::move(aVariables) ) ); + return xVariables; +} + +SwVbaVariables::SwVbaVariables( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< beans::XPropertyAccess >& rUserDefined ): SwVbaVariables_BASE( xParent, xContext, createVariablesAccess( xParent, xContext, rUserDefined ) ), mxUserDefined( rUserDefined ) +{ +} +// XEnumerationAccess +uno::Type +SwVbaVariables::getElementType() +{ + return cppu::UnoType<word::XVariable>::get(); +} +uno::Reference< container::XEnumeration > +SwVbaVariables::createEnumeration() +{ + uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); + return xEnumerationAccess->createEnumeration(); +} + +uno::Any +SwVbaVariables::createCollectionObject( const css::uno::Any& aSource ) +{ + return aSource; +} + +uno::Any SAL_CALL +SwVbaVariables::Add( const OUString& rName, const uno::Any& rValue ) +{ + uno::Any aValue; + if( rValue.hasValue() ) + aValue = rValue; + else + aValue <<= OUString(); + uno::Reference< beans::XPropertyContainer > xPropertyContainer( mxUserDefined, uno::UNO_QUERY_THROW ); + xPropertyContainer->addProperty( rName, beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::REMOVABLE, aValue ); + + return uno::Any( uno::Reference< word::XVariable >( new SwVbaVariable( getParent(), mxContext, mxUserDefined, rName ) ) ); +} + +OUString +SwVbaVariables::getServiceImplName() +{ + return "SwVbaVariables"; +} + +css::uno::Sequence<OUString> +SwVbaVariables::getServiceNames() +{ + static uno::Sequence< OUString > const sNames + { + "ooo.vba.word.Variables" + }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbavariables.hxx b/sw/source/ui/vba/vbavariables.hxx new file mode 100644 index 0000000000..639c54a33e --- /dev/null +++ b/sw/source/ui/vba/vbavariables.hxx @@ -0,0 +1,51 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAVARIABLES_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAVARIABLES_HXX + +#include <vbahelper/vbacollectionimpl.hxx> +#include <ooo/vba/word/XVariables.hpp> +#include <com/sun/star/beans/XPropertyAccess.hpp> + +typedef CollTestImplHelper< ooo::vba::word::XVariables > SwVbaVariables_BASE; + +class SwVbaVariables : public SwVbaVariables_BASE +{ +private: + css::uno::Reference< css::beans::XPropertyAccess > mxUserDefined; + +public: + SwVbaVariables( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertyAccess >& rUserDefined ); + + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + + // SwVbaVariables_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + + // XVariables + virtual css::uno::Any SAL_CALL Add( const OUString& rName, const css::uno::Any& rValue ) override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAVARIABLES_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaview.cxx b/sw/source/ui/vba/vbaview.cxx new file mode 100644 index 0000000000..822c4f93e5 --- /dev/null +++ b/sw/source/ui/vba/vbaview.cxx @@ -0,0 +1,399 @@ +/* -*- 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 "vbaview.hxx" +#include <utility> +#include <vbahelper/vbahelper.hxx> +#include <basic/sberrors.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/view/XViewSettingsSupplier.hpp> +#include <com/sun/star/text/XTextViewCursorSupplier.hpp> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XFootnotesSupplier.hpp> +#include <com/sun/star/text/XEndnotesSupplier.hpp> +#include <com/sun/star/text/XPageCursor.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <ooo/vba/word/WdSpecialPane.hpp> +#include <ooo/vba/word/WdViewType.hpp> +#include <ooo/vba/word/WdSeekView.hpp> + +#include "wordvbahelper.hxx" +#include "vbaheaderfooterhelper.hxx" +#include <view.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +const sal_Int32 DEFAULT_BODY_DISTANCE = 500; + +SwVbaView::SwVbaView( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, + uno::Reference< frame::XModel > xModel ) : + SwVbaView_BASE( rParent, rContext ), mxModel(std::move( xModel )) +{ + uno::Reference< frame::XController > xController = mxModel->getCurrentController(); + + uno::Reference< text::XTextViewCursorSupplier > xTextViewCursorSupp( xController, uno::UNO_QUERY_THROW ); + mxViewCursor = xTextViewCursorSupp->getViewCursor(); + + uno::Reference< view::XViewSettingsSupplier > xViewSettingSupp( xController, uno::UNO_QUERY_THROW ); + mxViewSettings.set( xViewSettingSupp->getViewSettings(), uno::UNO_SET_THROW ); +} + +SwVbaView::~SwVbaView() +{ +} + +sal_Bool SwVbaView::getShowAll() +{ + bool bShowFormattingMarks = false; + mxViewSettings->getPropertyValue("ShowNonprintingCharacters") >>= bShowFormattingMarks; + return bShowFormattingMarks; +} + +void SwVbaView::setShowAll(sal_Bool bSet) +{ + mxViewSettings->setPropertyValue("ShowNonprintingCharacters", uno::Any(bSet)); +} + +::sal_Int32 SAL_CALL +SwVbaView::getSeekView() +{ + // FIXME: if the view cursor is in table, field, section and frame + // handle if the cursor is in table + uno::Reference< text::XText > xCurrentText = mxViewCursor->getText(); + uno::Reference< beans::XPropertySet > xCursorProps( mxViewCursor, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextContent > xTextContent; + while( xCursorProps->getPropertyValue("TextTable") >>= xTextContent ) + { + xCurrentText = xTextContent->getAnchor()->getText(); + xCursorProps.set( xCurrentText->createTextCursor(), uno::UNO_QUERY_THROW ); + } + uno::Reference< lang::XServiceInfo > xServiceInfo( xCurrentText, uno::UNO_QUERY_THROW ); + OUString aImplName = xServiceInfo->getImplementationName(); + if ( aImplName == "SwXBodyText" ) + { + return word::WdSeekView::wdSeekMainDocument; + } + else if ( aImplName == "SwXHeadFootText" ) + { + if( HeaderFooterHelper::isHeader( mxModel ) ) + { + if( HeaderFooterHelper::isFirstPageHeader( mxModel ) ) + return word::WdSeekView::wdSeekFirstPageHeader; + else if( HeaderFooterHelper::isEvenPagesHeader( mxModel ) ) + return word::WdSeekView::wdSeekEvenPagesHeader; + else + return word::WdSeekView::wdSeekPrimaryHeader; + } + else + { + if( HeaderFooterHelper::isFirstPageFooter( mxModel ) ) + return word::WdSeekView::wdSeekFirstPageFooter; + else if( HeaderFooterHelper::isEvenPagesFooter( mxModel ) ) + return word::WdSeekView::wdSeekEvenPagesFooter; + else + return word::WdSeekView::wdSeekPrimaryFooter; + } + } + else if ( aImplName == "SwXFootnote" ) + { + if( xServiceInfo->supportsService("com.sun.star.text.Endnote") ) + return word::WdSeekView::wdSeekEndnotes; + else + return word::WdSeekView::wdSeekFootnotes; + } + + return word::WdSeekView::wdSeekMainDocument; +} + +void SAL_CALL +SwVbaView::setSeekView( ::sal_Int32 _seekview ) +{ + // FIXME: save the current cursor position, if the cursor is in the main + // document, so we can jump back to this position, if the macro sets + // the ViewMode back to wdSeekMainDocument + + word::gotoSelectedObjectAnchor( mxModel ); + switch( _seekview ) + { + case word::WdSeekView::wdSeekFirstPageFooter: + case word::WdSeekView::wdSeekFirstPageHeader: + case word::WdSeekView::wdSeekCurrentPageFooter: + case word::WdSeekView::wdSeekCurrentPageHeader: + case word::WdSeekView::wdSeekPrimaryFooter: + case word::WdSeekView::wdSeekPrimaryHeader: + case word::WdSeekView::wdSeekEvenPagesFooter: + case word::WdSeekView::wdSeekEvenPagesHeader: + { + // need to test + mxViewCursor->gotoRange( getHFTextRange( _seekview ), false ); + break; + } + case word::WdSeekView::wdSeekFootnotes: + { + uno::Reference< text::XFootnotesSupplier > xFootnotesSupp( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xFootnotes( xFootnotesSupp->getFootnotes(), uno::UNO_SET_THROW ); + if( xFootnotes->getCount() > 0 ) + { + uno::Reference< text::XText > xText( xFootnotes->getByIndex(0), uno::UNO_QUERY_THROW ); + mxViewCursor->gotoRange( xText->getStart(), false ); + } + else + { + DebugHelper::runtimeexception( ERRCODE_BASIC_NO_ACTIVE_OBJECT ); + } + break; + } + case word::WdSeekView::wdSeekEndnotes: + { + uno::Reference< text::XEndnotesSupplier > xEndnotesSupp( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xEndnotes( xEndnotesSupp->getEndnotes(), uno::UNO_SET_THROW ); + if( xEndnotes->getCount() > 0 ) + { + uno::Reference< text::XText > xText( xEndnotes->getByIndex(0), uno::UNO_QUERY_THROW ); + mxViewCursor->gotoRange( xText->getStart(), false ); + } + else + { + DebugHelper::runtimeexception( ERRCODE_BASIC_NO_ACTIVE_OBJECT ); + } + break; + } + case word::WdSeekView::wdSeekMainDocument: + { + uno::Reference< text::XTextDocument > xTextDocument( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< text::XText > xText = xTextDocument->getText(); + mxViewCursor->gotoRange( word::getFirstObjectPosition( xText ), false ); + break; + } + } +} + +::sal_Int32 SAL_CALL +SwVbaView::getSplitSpecial() +{ + return word::WdSpecialPane::wdPaneNone; +} + +void SAL_CALL +SwVbaView::setSplitSpecial( ::sal_Int32/* _splitspecial */) +{ + // not support in Writer +} + +sal_Bool SAL_CALL +SwVbaView::getTableGridLines() +{ + bool bShowTableGridLine = false; + mxViewSettings->getPropertyValue("ShowTableBoundaries") >>= bShowTableGridLine; + return bShowTableGridLine; +} + +void SAL_CALL +SwVbaView::setTableGridLines( sal_Bool _tablegridlines ) +{ + mxViewSettings->setPropertyValue("ShowTableBoundaries", uno::Any( _tablegridlines ) ); +} + +::sal_Int32 SAL_CALL +SwVbaView::getType() +{ + // FIXME: handle wdPrintPreview type + bool bOnlineLayout = false; + mxViewSettings->getPropertyValue("ShowOnlineLayout") >>= bOnlineLayout; + return bOnlineLayout ? word::WdViewType::wdWebView : word::WdViewType::wdPrintView; +} + +void SAL_CALL +SwVbaView::setType( ::sal_Int32 _type ) +{ + // FIXME: handle wdPrintPreview type + switch( _type ) + { + case word::WdViewType::wdPrintView: + case word::WdViewType::wdNormalView: + { + mxViewSettings->setPropertyValue("ShowOnlineLayout", uno::Any( false ) ); + break; + } + case word::WdViewType::wdWebView: + { + mxViewSettings->setPropertyValue("ShowOnlineLayout", uno::Any( true ) ); + break; + } + case word::WdViewType::wdPrintPreview: + { + PrintPreviewHelper( uno::Any(),word::getView( mxModel ) ); + break; + } + default: + DebugHelper::runtimeexception( ERRCODE_BASIC_NOT_IMPLEMENTED ); + + } +} + +uno::Reference< text::XTextRange > SwVbaView::getHFTextRange( sal_Int32 nType ) +{ + mxModel->lockControllers(); + + OUString aPropIsOn; + OUString aPropIsShared; + OUString aPropBodyDistance; + OUString aPropText; + + switch( nType ) + { + case word::WdSeekView::wdSeekCurrentPageFooter: + case word::WdSeekView::wdSeekFirstPageFooter: + case word::WdSeekView::wdSeekPrimaryFooter: + case word::WdSeekView::wdSeekEvenPagesFooter: + { + aPropIsOn = "FooterIsOn"; + aPropIsShared = "FooterIsShared"; + aPropBodyDistance = "FooterBodyDistance"; + aPropText = "FooterText"; + break; + } + case word::WdSeekView::wdSeekCurrentPageHeader: + case word::WdSeekView::wdSeekFirstPageHeader: + case word::WdSeekView::wdSeekPrimaryHeader: + case word::WdSeekView::wdSeekEvenPagesHeader: + { + aPropIsOn = "HeaderIsOn"; + aPropIsShared = "HeaderIsShared"; + aPropBodyDistance = "HeaderBodyDistance"; + aPropText = "HeaderText"; + break; + } + } + + uno::Reference< text::XPageCursor > xPageCursor( mxViewCursor, uno::UNO_QUERY_THROW ); + + if( nType == word::WdSeekView::wdSeekFirstPageFooter + || nType == word::WdSeekView::wdSeekFirstPageHeader ) + { + xPageCursor->jumpToFirstPage(); + } + + uno::Reference< style::XStyle > xStyle; + uno::Reference< text::XText > xText; + switch( nType ) + { + case word::WdSeekView::wdSeekPrimaryFooter: + case word::WdSeekView::wdSeekPrimaryHeader: + case word::WdSeekView::wdSeekEvenPagesFooter: + case word::WdSeekView::wdSeekEvenPagesHeader: + { + // The primary header is the first header of the section. + // If the header is not shared between odd and even pages + // the odd page's header is the primary header. If the + // first page's header is different from the rest of the + // document, it is NOT the primary header ( the next primary + // header would be on page 3 ) + // The even pages' header is only available if the header is + // not shared and the current style is applied to a page with + // an even page number + uno::Reference< beans::XPropertySet > xCursorProps( mxViewCursor, uno::UNO_QUERY_THROW ); + OUString aPageStyleName; + xCursorProps->getPropertyValue("PageStyleName") >>= aPageStyleName; + if ( aPageStyleName == "First Page" ) + { + // go to the beginning of where the next style is used + bool hasNextPage = false; + xStyle = word::getCurrentPageStyle( mxModel ); + do + { + hasNextPage = xPageCursor->jumpToNextPage(); + } + while( hasNextPage && ( xStyle == word::getCurrentPageStyle( mxModel ) ) ); + + if( !hasNextPage ) + DebugHelper::basicexception( ERRCODE_BASIC_BAD_ACTION, {} ); + } + break; + } + default: + { + break; + } + } + + xStyle = word::getCurrentPageStyle( mxModel ); + uno::Reference< beans::XPropertySet > xPageProps( xStyle, uno::UNO_QUERY_THROW ); + bool isOn = false; + xPageProps->getPropertyValue( aPropIsOn ) >>= isOn; + bool isShared = false; + xPageProps->getPropertyValue( aPropIsShared ) >>= isShared; + if( !isOn ) + { + xPageProps->setPropertyValue( aPropIsOn, uno::Any( true ) ); + xPageProps->setPropertyValue( aPropBodyDistance, uno::Any( DEFAULT_BODY_DISTANCE ) ); + } + if( !isShared ) + { + OUString aTempPropText = aPropText; + if( nType == word::WdSeekView::wdSeekEvenPagesFooter + || nType == word::WdSeekView::wdSeekEvenPagesHeader ) + { + aTempPropText += "Left"; + } + else + { + aTempPropText += "Right"; + } + xText.set( xPageProps->getPropertyValue( aTempPropText), uno::UNO_QUERY_THROW ); + } + else + { + if( nType == word::WdSeekView::wdSeekEvenPagesFooter + || nType == word::WdSeekView::wdSeekEvenPagesHeader ) + { + DebugHelper::basicexception( ERRCODE_BASIC_BAD_ACTION, {} ); + } + xText.set( xPageProps->getPropertyValue( aPropText ), uno::UNO_QUERY_THROW ); + } + + mxModel->unlockControllers(); + if( !xText.is() ) + { + DebugHelper::basicexception( ERRCODE_BASIC_INTERNAL_ERROR, {} ); + } + uno::Reference< text::XTextRange > xTextRange = word::getFirstObjectPosition( xText ); + return xTextRange; +} + +OUString +SwVbaView::getServiceImplName() +{ + return "SwVbaView"; +} + +uno::Sequence< OUString > +SwVbaView::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.View" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaview.hxx b/sw/source/ui/vba/vbaview.hxx new file mode 100644 index 0000000000..66cd0db612 --- /dev/null +++ b/sw/source/ui/vba/vbaview.hxx @@ -0,0 +1,63 @@ +/* -*- 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 <ooo/vba/word/XView.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include <com/sun/star/text/XTextViewCursor.hpp> +#include <com/sun/star/text/XTextRange.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XView > SwVbaView_BASE; + +class SwVbaView : public SwVbaView_BASE +{ +private: + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::text::XTextViewCursor > mxViewCursor; + css::uno::Reference< css::beans::XPropertySet > mxViewSettings; + + /// @throws css::uno::RuntimeException + /// @throws css::script::BasicErrorException + css::uno::Reference< css::text::XTextRange > getHFTextRange( sal_Int32 nType ); + +public: + /// @throws css::uno::RuntimeException + SwVbaView( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, + css::uno::Reference< css::frame::XModel > xModel ); + virtual ~SwVbaView() override; + + // XView + sal_Bool SAL_CALL getShowAll() override; + void SAL_CALL setShowAll(sal_Bool bSet) override; + virtual ::sal_Int32 SAL_CALL getSeekView() override; + virtual void SAL_CALL setSeekView( ::sal_Int32 _seekview ) override; + virtual ::sal_Int32 SAL_CALL getSplitSpecial() override; + virtual void SAL_CALL setSplitSpecial( ::sal_Int32 _splitspecial ) override; + virtual sal_Bool SAL_CALL getTableGridLines() override; + virtual void SAL_CALL setTableGridLines( sal_Bool _tablegridlines ) override; + virtual ::sal_Int32 SAL_CALL getType() override; + virtual void SAL_CALL setType( ::sal_Int32 _type ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbawindow.cxx b/sw/source/ui/vba/vbawindow.cxx new file mode 100644 index 0000000000..9114f4b8d4 --- /dev/null +++ b/sw/source/ui/vba/vbawindow.cxx @@ -0,0 +1,179 @@ +/* -*- 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 <ooo/vba/word/WdWindowState.hpp> +#include <sal/log.hxx> +#include <sfx2/viewfrm.hxx> +#include <vcl/wrkwin.hxx> + +#include "vbawindow.hxx" +#include "vbadocument.hxx" +#include "vbaview.hxx" +#include "vbapanes.hxx" +#include "vbapane.hxx" +#include "wordvbahelper.hxx" +#include <view.hxx> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +SwVbaWindow::SwVbaWindow( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< frame::XController >& xController ) : + WindowImpl_BASE( xParent, xContext, xModel, xController ) +{ +} + +void +SwVbaWindow::Activate() +{ + rtl::Reference<SwVbaDocument> document( new SwVbaDocument(uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), mxContext, m_xModel) ); + + document->Activate(); +} + +void +SwVbaWindow::Close( const uno::Any& SaveChanges, const uno::Any& RouteDocument ) +{ + // FIXME: it is incorrect when there are more than 1 windows + rtl::Reference<SwVbaDocument> document( new SwVbaDocument(uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), mxContext, m_xModel) ); + uno::Any FileName; + document->Close(SaveChanges, FileName, RouteDocument ); +} + +uno::Any SAL_CALL +SwVbaWindow::getView() +{ + return uno::Any( uno::Reference< word::XView >( new SwVbaView( this, mxContext, m_xModel ) ) ); +} + +void SAL_CALL SwVbaWindow::setView( const uno::Any& _view ) +{ + sal_Int32 nType = 0; + if( _view >>= nType ) + { + rtl::Reference<SwVbaView> view( new SwVbaView(this, mxContext, m_xModel) ); + view->setType( nType ); + } +} + +uno::Any SAL_CALL +SwVbaWindow::getWindowState() +{ + sal_Int32 nwindowState = word::WdWindowState::wdWindowStateNormal; + SwView* pView = word::getView( m_xModel ); + SfxViewFrame& rViewFrame = pView->GetViewFrame(); + WorkWindow* pWork = static_cast<WorkWindow*>( rViewFrame.GetFrame().GetSystemWindow() ); + if ( pWork ) + { + if ( pWork -> IsMaximized()) + nwindowState = word::WdWindowState::wdWindowStateMaximize; + else if (pWork -> IsMinimized()) + nwindowState = word::WdWindowState::wdWindowStateMinimize; + } + return uno::Any( nwindowState ); +} + +void SAL_CALL +SwVbaWindow::setWindowState( const uno::Any& _windowstate ) +{ + sal_Int32 nwindowState = word::WdWindowState::wdWindowStateMaximize; + _windowstate >>= nwindowState; + SwView* pView = word::getView( m_xModel ); + SfxViewFrame& rViewFrame = pView->GetViewFrame(); + WorkWindow* pWork = static_cast<WorkWindow*>( rViewFrame.GetFrame().GetSystemWindow() ); + if ( pWork ) + { + if ( nwindowState == word::WdWindowState::wdWindowStateMaximize ) + pWork -> Maximize(); + else if (nwindowState == word::WdWindowState::wdWindowStateMinimize) + pWork -> Minimize(); + else if (nwindowState == word::WdWindowState::wdWindowStateNormal) + pWork -> Restore(); + else + SAL_WARN("sw.vba", "Unhandled window state " << nwindowState); + } +} + +OUString SAL_CALL +SwVbaWindow::getCaption() +{ + SwView* pView = word::getView( m_xModel ); + if( !pView ) + return ""; + + uno::Reference< css::beans::XPropertySet > xFrameProps( pView->GetViewFrame().GetFrame().GetFrameInterface()->getController()->getFrame(), uno::UNO_QUERY ); + if( !xFrameProps.is() ) + return ""; + + OUString sTitle; + xFrameProps->getPropertyValue( "Title" ) >>= sTitle; + + return sTitle; +} + +void SAL_CALL +SwVbaWindow::setCaption( const OUString& _caption ) +{ + SwView* pView = word::getView( m_xModel ); + if( !pView ) + return; + + uno::Reference< css::beans::XPropertySet > xFrameProps( pView->GetViewFrame().GetFrame().GetFrameInterface()->getController()->getFrame(), uno::UNO_QUERY ); + if( !xFrameProps.is() ) + return; + + xFrameProps->setPropertyValue( "Title", uno::Any( _caption ) ); +} + +uno::Any SAL_CALL +SwVbaWindow::Panes( const uno::Any& aIndex ) +{ + uno::Reference< XCollection > xPanes( new SwVbaPanes( this, mxContext, m_xModel ) ); + if( aIndex.getValueTypeClass() == uno::TypeClass_VOID ) + return uno::Any( xPanes ); + + return xPanes->Item( aIndex, uno::Any() ); +} + +uno::Any SAL_CALL +SwVbaWindow::ActivePane() +{ + return uno::Any( uno::Reference< word::XPane >( new SwVbaPane( this, mxContext, m_xModel ) ) ); +} + +OUString +SwVbaWindow::getServiceImplName() +{ + return "SwVbaWindow"; +} + +uno::Sequence< OUString > +SwVbaWindow::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.Window" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbawindow.hxx b/sw/source/ui/vba/vbawindow.hxx new file mode 100644 index 0000000000..ee435b1505 --- /dev/null +++ b/sw/source/ui/vba/vbawindow.hxx @@ -0,0 +1,59 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAWINDOW_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAWINDOW_HXX +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/word/XWindow.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + +#include <vbahelper/vbahelperinterface.hxx> +#include <vbahelper/vbawindowbase.hxx> + +typedef cppu::ImplInheritanceHelper< VbaWindowBase, ov::word::XWindow > WindowImpl_BASE; + +class SwVbaWindow : public WindowImpl_BASE +{ +public: + /// @throws css::uno::RuntimeException + SwVbaWindow( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::frame::XController >& xController ); + + // Attributes + virtual css::uno::Any SAL_CALL getView() override; + virtual void SAL_CALL setView( const css::uno::Any& _view ) override; + virtual css::uno::Any SAL_CALL getWindowState() override; + virtual void SAL_CALL setWindowState( const css::uno::Any& _windowstate ) override; + virtual OUString SAL_CALL getCaption() override; + virtual void SAL_CALL setCaption( const OUString& _caption ) override; + // Methods + virtual void SAL_CALL Activate( ) override; + virtual void SAL_CALL Close( const css::uno::Any& SaveChanges, const css::uno::Any& RouteDocument ) override; + virtual css::uno::Any SAL_CALL Panes( const css::uno::Any& aIndex ) override; + virtual css::uno::Any SAL_CALL ActivePane() override; + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAWINDOW_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbawordbasic.cxx b/sw/source/ui/vba/vbawordbasic.cxx new file mode 100644 index 0000000000..f08ed4e0da --- /dev/null +++ b/sw/source/ui/vba/vbawordbasic.cxx @@ -0,0 +1,265 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column:100 -*- */ +/* + * 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 "vbaapplication.hxx" +#include "vbafilterpropsfromformat.hxx" +#include "vbamailmerge.hxx" +#include "vbawordbasic.hxx" + +#include <basic/sbx.hxx> +#include <basic/sbxvar.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/propertyvalue.hxx> +#include <osl/file.hxx> +#include <sal/log.hxx> +#include <tools/urlobj.hxx> + +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/util/thePathSettings.hpp> +#include <ooo/vba/word/XBookmarks.hpp> +#include <ooo/vba/word/XDocuments.hpp> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +SwWordBasic::SwWordBasic(SwVbaApplication* pApp) + : mpApp(pApp) +{ +} + +sal_Int32 SAL_CALL SwWordBasic::getMailMergeMainDocumentType() +{ + return SwVbaMailMerge::get(mpApp->getParent(), mpApp->getContext())->getMainDocumentType(); +} + +void SAL_CALL SwWordBasic::setMailMergeMainDocumentType(sal_Int32 _mailmergemaindocumenttype) +{ + SwVbaMailMerge::get(mpApp->getParent(), mpApp->getContext()) + ->setMainDocumentType(_mailmergemaindocumenttype); +} + +void SAL_CALL SwWordBasic::FileOpen(const OUString& Name, const uno::Any& ConfirmConversions, + const uno::Any& ReadOnly, const uno::Any& AddToMru, + const uno::Any& PasswordDoc, const uno::Any& PasswordDot, + const uno::Any& Revert, const uno::Any& WritePasswordDoc, + const uno::Any& WritePasswordDot) +{ + uno::Any aDocuments = mpApp->Documents(uno::Any()); + + uno::Reference<word::XDocuments> rDocuments; + + if (aDocuments >>= rDocuments) + rDocuments->Open(Name, ConfirmConversions, ReadOnly, AddToMru, PasswordDoc, PasswordDot, + Revert, WritePasswordDoc, WritePasswordDot, uno::Any(), uno::Any(), + uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any()); +} + +void SAL_CALL SwWordBasic::FileSave() +{ + uno::Reference<frame::XModel> xModel(mpApp->getCurrentDocument(), uno::UNO_SET_THROW); + dispatchRequests(xModel, ".uno:Save"); +} + +void SAL_CALL SwWordBasic::FileSaveAs( + const css::uno::Any& Name, const css::uno::Any& Format, const css::uno::Any& /*LockAnnot*/, + const css::uno::Any& /*Password*/, const css::uno::Any& /*AddToMru*/, + const css::uno::Any& /*WritePassword*/, const css::uno::Any& /*RecommendReadOnly*/, + const css::uno::Any& /*EmbedFonts*/, const css::uno::Any& /*NativePictureFormat*/, + const css::uno::Any& /*FormsData*/, const css::uno::Any& /*SaveAsAOCELetter*/) +{ + SAL_INFO("sw.vba", "WordBasic.FileSaveAs(Name:=" << Name << ",Format:=" << Format << ")"); + + uno::Reference<frame::XModel> xModel(mpApp->getCurrentDocument(), uno::UNO_SET_THROW); + + // Based on SwVbaDocument::SaveAs2000. + + OUString sFileName; + Name >>= sFileName; + + OUString sURL; + osl::FileBase::getFileURLFromSystemPath(sFileName, sURL); + + // Detect if there is no path then we need to use the current folder. + INetURLObject aURL(sURL); + sURL = aURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri); + if (sURL.isEmpty()) + { + // Need to add cur dir ( of this document ) or else the 'Work' dir + sURL = xModel->getURL(); + + if (sURL.isEmpty()) + { + // Not path available from 'this' document. Need to add the 'document'/work directory then. + // Based on SwVbaOptions::getValueEvent() + uno::Reference<util::XPathSettings> xPathSettings + = util::thePathSettings::get(comphelper::getProcessComponentContext()); + OUString sPathUrl; + xPathSettings->getPropertyValue("Work") >>= sPathUrl; + // Path could be a multipath, Microsoft doesn't support this feature in Word currently. + // Only the last path is from interest. + // No idea if this crack is relevant for WordBasic or not. + sal_Int32 nIndex = sPathUrl.lastIndexOf(';'); + if (nIndex != -1) + { + sPathUrl = sPathUrl.copy(nIndex + 1); + } + + aURL.SetURL(sPathUrl); + } + else + { + aURL.SetURL(sURL); + aURL.Append(sFileName); + } + sURL = aURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri); + } + sal_Int32 nFileFormat = word::WdSaveFormat::wdFormatDocument; + Format >>= nFileFormat; + + uno::Sequence aProps{ comphelper::makePropertyValue("FilterName", css::uno::Any()), + comphelper::makePropertyValue("FileName", sURL) }; + + setFilterPropsFromFormat(nFileFormat, aProps); + + dispatchRequests(xModel, ".uno:SaveAs", aProps); +} + +void SAL_CALL SwWordBasic::FileClose(const css::uno::Any& Save) +{ + uno::Reference<frame::XModel> xModel(mpApp->getCurrentDocument(), uno::UNO_SET_THROW); + + sal_Int16 nSave = 0; + if (Save.hasValue() && (Save >>= nSave) && (nSave == 0 || nSave == 1)) + FileSave(); + + // FIXME: Here I would much prefer to call VbaDocumentBase::Close() but not sure how to get at + // the VbaDocumentBase of the current document. (Probably it is easy and I haven't looked hard + // enough.) + // + // FIXME: Error handling. If there is no current document, return some kind of error? But for + // now, just ignore errors. This code is written to work for a very specific customer use case + // anyway, not for an arbitrary sequence of COM calls to the "VBA" API. + dispatchRequests(xModel, ".uno:CloseDoc"); +} + +void SAL_CALL SwWordBasic::ToolsOptionsView( + const css::uno::Any& DraftFont, const css::uno::Any& WrapToWindow, + const css::uno::Any& PicturePlaceHolders, const css::uno::Any& FieldCodes, + const css::uno::Any& BookMarks, const css::uno::Any& FieldShading, + const css::uno::Any& StatusBar, const css::uno::Any& HScroll, const css::uno::Any& VScroll, + const css::uno::Any& StyleAreaWidth, const css::uno::Any& Tabs, const css::uno::Any& Spaces, + const css::uno::Any& Paras, const css::uno::Any& Hyphens, const css::uno::Any& Hidden, + const css::uno::Any& ShowAll, const css::uno::Any& Drawings, const css::uno::Any& Anchors, + const css::uno::Any& TextBoundaries, const css::uno::Any& VRuler, + const css::uno::Any& Highlight) +{ + SAL_INFO("sw.vba", "WordBasic.ToolsOptionsView(" + "DraftFont:=" + << DraftFont << ", WrapToWindow:=" << WrapToWindow + << ", PicturePlaceHolders:=" << PicturePlaceHolders + << ", FieldCodes:=" << FieldCodes << ", BookMarks:=" << BookMarks + << ", FieldShading:=" << FieldShading << ", StatusBar:=" << StatusBar + << ", HScroll:=" << HScroll << ", VScroll:=" << VScroll + << ", StyleAreaWidth:=" << StyleAreaWidth << ", Tabs:=" << Tabs + << ", Spaces:=" << Spaces << ", Paras:=" << Paras + << ", Hyphens:=" << Hyphens << ", Hidden:=" << Hidden + << ", ShowAll:=" << ShowAll << ", Drawings:=" << Drawings + << ", Anchors:=" << Anchors << ", TextBoundaries:=" << TextBoundaries + << ", VRuler:=" << VRuler << ", Highlight:=" << Highlight << ")"); +} + +css::uno::Any SAL_CALL SwWordBasic::WindowName(const css::uno::Any& /*Number*/) +{ + return css::uno::Any(mpApp->getActiveSwVbaWindow()->getCaption()); +} + +css::uno::Any SAL_CALL SwWordBasic::ExistingBookmark(const OUString& Name) +{ + uno::Reference<word::XBookmarks> xBookmarks(mpApp->getActiveDocument()->Bookmarks(uno::Any()), + uno::UNO_QUERY); + return css::uno::Any(xBookmarks.is() && xBookmarks->Exists(Name)); +} + +void SAL_CALL SwWordBasic::MailMergeOpenDataSource( + const OUString& Name, const css::uno::Any& Format, const css::uno::Any& ConfirmConversions, + const css::uno::Any& ReadOnly, const css::uno::Any& LinkToSource, + const css::uno::Any& AddToRecentFiles, const css::uno::Any& PasswordDocument, + const css::uno::Any& PasswordTemplate, const css::uno::Any& Revert, + const css::uno::Any& WritePasswordDocument, const css::uno::Any& WritePasswordTemplate, + const css::uno::Any& Connection, const css::uno::Any& SQLStatement, + const css::uno::Any& SQLStatement1, const css::uno::Any& OpenExclusive, + const css::uno::Any& SubType) +{ + mpApp->getActiveDocument()->getMailMerge()->OpenDataSource( + Name, Format, ConfirmConversions, ReadOnly, LinkToSource, AddToRecentFiles, + PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, + Connection, SQLStatement, SQLStatement1, OpenExclusive, SubType); +} + +css::uno::Any SAL_CALL SwWordBasic::AppMaximize(const css::uno::Any& WindowName, + const css::uno::Any& State) +{ + SAL_INFO("sw.vba", "WordBasic.AppMaximize( WindowName:=" << WindowName << ", State:=" << State); + + // FIXME: Implement if necessary + return css::uno::Any(sal_Int32(0)); +} + +css::uno::Any SAL_CALL SwWordBasic::DocMaximize(const css::uno::Any& State) +{ + SAL_INFO("sw.vba", "WordBasic.DocMaximize(State:=" << State << ")"); + + // FIXME: Implement if necessary + return css::uno::Any(sal_Int32(0)); +} + +void SAL_CALL SwWordBasic::AppShow(const css::uno::Any& WindowName) +{ + SAL_INFO("sw.vba", "WordBasic.AppShow(WindowName:=" << WindowName << ")"); + + // FIXME: Implement if necessary +} + +css::uno::Any SAL_CALL SwWordBasic::AppCount() +{ + SAL_INFO("sw.vba", "WordBasic.AppCount()"); + + // FIXME: Implement if necessary. Return a random number for now. + return css::uno::Any(sal_Int32(2)); +} + +void SAL_CALL SwWordBasic::MsgBox(const OUString& sPrompt) +{ + SbxArrayRef pArgs = new SbxArray; + SbxVariable* pVar = new SbxVariable(); + pVar->PutString(sPrompt); + pArgs->Put(pVar, 1); + + if (!executeRunTimeLibrary(u"MsgBox", pArgs.get())) + SAL_WARN("sw.vba", "failed to execute runtime library function MsgBox (" << sPrompt << ")"); +} + +void SAL_CALL SwWordBasic::ScreenUpdating(const uno::Any& On) +{ + sal_Int32 nOn; + if (On >>= nOn) + mpApp->setScreenUpdating(nOn != 0); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbawordbasic.hxx b/sw/source/ui/vba/vbawordbasic.hxx new file mode 100644 index 0000000000..05589f0c58 --- /dev/null +++ b/sw/source/ui/vba/vbawordbasic.hxx @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAWORDBASIC_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAWORDBASIC_HXX + +class SwVbaApplication; + +/** + * This is a representation of the WordBasic statements and functions + * that were available in Word version 6.0 and Word for Windows 95. + * + * It can be specified as "Application.WordBasic." or "WordBasic.". + * + * Starting with Word 2000, old macros were automatically converted + * into Visual Basic modules, and the WordBasic prefix was added where + * no VBA methods precisely corresponded. + * + * In other words, it is a compatibility shim. + */ +class SwWordBasic : public cppu::WeakImplHelper<ooo::vba::word::XWordBasic> +{ +private: + SwVbaApplication* mpApp; + +public: + SwWordBasic(SwVbaApplication* pApp); + + // XWordBasic + virtual sal_Int32 SAL_CALL getMailMergeMainDocumentType() override; + virtual void SAL_CALL + setMailMergeMainDocumentType(sal_Int32 _mailmergemaindocumenttype) override; + + virtual void SAL_CALL FileOpen(const OUString& Name, const css::uno::Any& ConfirmConversions, + const css::uno::Any& ReadOnly, const css::uno::Any& AddToMru, + const css::uno::Any& PasswordDoc, + const css::uno::Any& PasswordDot, const css::uno::Any& Revert, + const css::uno::Any& WritePasswordDoc, + const css::uno::Any& WritePasswordDot) override; + virtual void SAL_CALL FileSave() override; + virtual void SAL_CALL FileSaveAs( + const css::uno::Any& Name, const css::uno::Any& Format, const css::uno::Any& LockAnnot, + const css::uno::Any& Password, const css::uno::Any& AddToMru, + const css::uno::Any& WritePassword, const css::uno::Any& RecommendReadOnly, + const css::uno::Any& EmbedFonts, const css::uno::Any& NativePictureFormat, + const css::uno::Any& FormsData, const css::uno::Any& SaveAsAOCELetter) override; + virtual void SAL_CALL FileClose(const css::uno::Any& Save) override; + virtual void SAL_CALL ToolsOptionsView( + const css::uno::Any& DraftFont, const css::uno::Any& WrapToWindow, + const css::uno::Any& PicturePlaceHolders, const css::uno::Any& FieldCodes, + const css::uno::Any& BookMarks, const css::uno::Any& FieldShading, + const css::uno::Any& StatusBar, const css::uno::Any& HScroll, const css::uno::Any& VScroll, + const css::uno::Any& StyleAreaWidth, const css::uno::Any& Tabs, const css::uno::Any& Spaces, + const css::uno::Any& Paras, const css::uno::Any& Hyphens, const css::uno::Any& Hidden, + const css::uno::Any& ShowAll, const css::uno::Any& Drawings, const css::uno::Any& Anchors, + const css::uno::Any& TextBoundaries, const css::uno::Any& VRuler, + const css::uno::Any& Highlight) override; + virtual css::uno::Any SAL_CALL WindowName(const css::uno::Any& Number) override; + virtual css::uno::Any SAL_CALL ExistingBookmark(const OUString& Name) override; + virtual void SAL_CALL MailMergeOpenDataSource( + const OUString& Name, const css::uno::Any& Format, const css::uno::Any& ConfirmConversions, + const css::uno::Any& ReadOnly, const css::uno::Any& LinkToSource, + const css::uno::Any& AddToRecentFiles, const css::uno::Any& PasswordDocument, + const css::uno::Any& PasswordTemplate, const css::uno::Any& Revert, + const css::uno::Any& WritePasswordDocument, const css::uno::Any& WritePasswordTemplate, + const css::uno::Any& Connection, const css::uno::Any& SQLStatement, + const css::uno::Any& SQLStatement1, const css::uno::Any& OpenExclusive, + const css::uno::Any& SubType) override; + virtual css::uno::Any SAL_CALL AppMaximize(const css::uno::Any& WindowName, + const css::uno::Any& State) override; + virtual css::uno::Any SAL_CALL DocMaximize(const css::uno::Any& State) override; + virtual void SAL_CALL AppShow(const css::uno::Any& WindowName) override; + virtual css::uno::Any SAL_CALL AppCount() override; + virtual void SAL_CALL MsgBox(const OUString& sPrompt) override; + virtual void SAL_CALL ScreenUpdating(const css::uno::Any& On) override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAWORDBASIC_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbawrapformat.cxx b/sw/source/ui/vba/vbawrapformat.cxx new file mode 100644 index 0000000000..2aef0523b4 --- /dev/null +++ b/sw/source/ui/vba/vbawrapformat.cxx @@ -0,0 +1,243 @@ +/* -*- 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 "vbawrapformat.hxx" +#include <ooo/vba/word/WdWrapSideType.hpp> +#include <ooo/vba/word/WdWrapType.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/text/WrapTextMode.hpp> +#include <basic/sberrors.hxx> +#include <vbahelper/vbahelper.hxx> + +using namespace ooo::vba; +using namespace com::sun::star; + +SwVbaWrapFormat::SwVbaWrapFormat( uno::Sequence< uno::Any > const& aArgs, uno::Reference< uno::XComponentContext >const& xContext ) : SwVbaWrapFormat_BASE( getXSomethingFromArgs< XHelperInterface >( aArgs, 0 ), xContext ), m_xShape( getXSomethingFromArgs< drawing::XShape >( aArgs, 1, false ) ), mnWrapFormatType( 0 ), mnSide( word::WdWrapSideType::wdWrapBoth ) +{ + m_xPropertySet.set( m_xShape, uno::UNO_QUERY_THROW ); +} + +void SwVbaWrapFormat::makeWrap() +{ + text::WrapTextMode eTextMode = text::WrapTextMode_NONE; + if( mnSide == word::WdWrapSideType::wdWrapLeft ) + { + eTextMode = text::WrapTextMode_LEFT; + } + else if( mnSide == word::WdWrapSideType::wdWrapRight ) + { + eTextMode = text::WrapTextMode_RIGHT; + } + else if( mnSide == word::WdWrapSideType::wdWrapBoth || + mnSide == word::WdWrapSideType::wdWrapLargest ) + { + switch( mnWrapFormatType ) + { + case word::WdWrapType::wdWrapNone: + case word::WdWrapType::wdWrapThrough: + { + eTextMode = text::WrapTextMode_THROUGH; + break; + } + case word::WdWrapType::wdWrapInline: + case word::WdWrapType::wdWrapTopBottom: + { + eTextMode = text::WrapTextMode_NONE; + break; + } + case word::WdWrapType::wdWrapSquare: + { + eTextMode = text::WrapTextMode_PARALLEL; + m_xPropertySet->setPropertyValue("SurroundContour", uno::Any( false ) ); + break; + } + case word::WdWrapType::wdWrapTight: + { + eTextMode = text::WrapTextMode_PARALLEL; + m_xPropertySet->setPropertyValue("SurroundContour", uno::Any( true ) ); + break; + } + default: + { + DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_ARGUMENT); + } + } + } + m_xPropertySet->setPropertyValue("TextWrap", uno::Any( eTextMode ) ); +} + +::sal_Int32 SAL_CALL SwVbaWrapFormat::getType() +{ + sal_Int32 nType = word::WdWrapType::wdWrapSquare; + text::WrapTextMode eTextMode; + m_xPropertySet->getPropertyValue("TextWrap") >>= eTextMode; + switch( eTextMode ) + { + case text::WrapTextMode_NONE: + { + nType = word::WdWrapType::wdWrapTopBottom; + break; + } + case text::WrapTextMode_THROUGH: + { + nType = word::WdWrapType::wdWrapNone; + break; + } + case text::WrapTextMode_PARALLEL: + { + bool bContour = false; + m_xPropertySet->getPropertyValue("SurroundContour") >>= bContour; + if( bContour ) + nType = word::WdWrapType::wdWrapTight; + else + nType = word::WdWrapType::wdWrapSquare; + break; + } + case text::WrapTextMode_DYNAMIC: + case text::WrapTextMode_LEFT: + case text::WrapTextMode_RIGHT: + { + nType = word::WdWrapType::wdWrapThrough; + break; + } + default: + { + nType = word::WdWrapType::wdWrapSquare; + } + } + return nType; +} + +void SAL_CALL SwVbaWrapFormat::setType( ::sal_Int32 _type ) +{ + mnWrapFormatType = _type; + makeWrap(); +} + +::sal_Int32 SAL_CALL SwVbaWrapFormat::getSide() +{ + sal_Int32 nSide = word::WdWrapSideType::wdWrapBoth; + text::WrapTextMode eTextMode; + m_xPropertySet->getPropertyValue("TextWrap") >>= eTextMode; + switch( eTextMode ) + { + case text::WrapTextMode_LEFT: + { + nSide = word::WdWrapSideType::wdWrapLeft; + break; + } + case text::WrapTextMode_RIGHT: + { + nSide = word::WdWrapSideType::wdWrapRight; + break; + } + default: + { + nSide = word::WdWrapSideType::wdWrapBoth; + } + } + return nSide; +} + +void SAL_CALL SwVbaWrapFormat::setSide( ::sal_Int32 _side ) +{ + mnSide = _side; + makeWrap(); +} + +float SwVbaWrapFormat::getDistance( const OUString& sName ) +{ + sal_Int32 nDistance = 0; + m_xPropertySet->getPropertyValue( sName ) >>= nDistance; + return static_cast< float >( Millimeter::getInPoints( nDistance ) ); +} + +void SwVbaWrapFormat::setDistance( const OUString& sName, float _distance ) +{ + sal_Int32 nDistance = Millimeter::getInHundredthsOfOneMillimeter( _distance ); + m_xPropertySet->setPropertyValue( sName, uno::Any( nDistance ) ); +} + +float SAL_CALL SwVbaWrapFormat::getDistanceTop() +{ + return getDistance( "TopMargin" ); +} + +void SAL_CALL SwVbaWrapFormat::setDistanceTop( float _distancetop ) +{ + setDistance( "TopMargin", _distancetop ); +} + +float SAL_CALL SwVbaWrapFormat::getDistanceBottom() +{ + return getDistance( "BottomMargin" ); +} + +void SAL_CALL SwVbaWrapFormat::setDistanceBottom( float _distancebottom ) +{ + setDistance( "BottomMargin", _distancebottom ); +} + +float SAL_CALL SwVbaWrapFormat::getDistanceLeft() +{ + return getDistance( "LeftMargin" ); +} + +void SAL_CALL SwVbaWrapFormat::setDistanceLeft( float _distanceleft ) +{ + setDistance( "LeftMargin", _distanceleft ); +} + +float SAL_CALL SwVbaWrapFormat::getDistanceRight() +{ + return getDistance( "RightMargin" ); +} + +void SAL_CALL SwVbaWrapFormat::setDistanceRight( float _distanceright ) +{ + setDistance( "RightMargin", _distanceright ); +} + +OUString +SwVbaWrapFormat::getServiceImplName() +{ + return "SwVbaWrapFormat"; +} + +uno::Sequence< OUString > +SwVbaWrapFormat::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.word.WrapFormat" + }; + return aServiceNames; +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +Writer_SwVbaWrapFormat_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args) +{ + return cppu::acquire(new SwVbaWrapFormat(args, context)); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbawrapformat.hxx b/sw/source/ui/vba/vbawrapformat.hxx new file mode 100644 index 0000000000..ef28118ed9 --- /dev/null +++ b/sw/source/ui/vba/vbawrapformat.hxx @@ -0,0 +1,66 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAWRAPFORMAT_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_VBAWRAPFORMAT_HXX + +#include <com/sun/star/drawing/XShape.hpp> +#include <ooo/vba/word/XWrapFormat.hpp> +#include <vbahelper/vbahelperinterface.hxx> + +typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XWrapFormat > SwVbaWrapFormat_BASE; + +class SwVbaWrapFormat : public SwVbaWrapFormat_BASE +{ +private: + css::uno::Reference< css::drawing::XShape > m_xShape; + css::uno::Reference< css::beans::XPropertySet > m_xPropertySet; + sal_Int32 mnWrapFormatType; + sal_Int32 mnSide; + +private: + /// @throws css::uno::RuntimeException + void makeWrap(); + /// @throws css::uno::RuntimeException + float getDistance( const OUString& sName ); + /// @throws css::uno::RuntimeException + void setDistance( const OUString& sName, float _distance ); + +public: + SwVbaWrapFormat( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext ); + + virtual ::sal_Int32 SAL_CALL getType() override; + virtual void SAL_CALL setType( ::sal_Int32 _type ) override; + virtual ::sal_Int32 SAL_CALL getSide() override; + virtual void SAL_CALL setSide( ::sal_Int32 _side ) override; + virtual float SAL_CALL getDistanceTop() override; + virtual void SAL_CALL setDistanceTop( float _distancetop ) override; + virtual float SAL_CALL getDistanceBottom() override; + virtual void SAL_CALL setDistanceBottom( float _distancebottom ) override; + virtual float SAL_CALL getDistanceLeft() override; + virtual void SAL_CALL setDistanceLeft( float _distanceleft ) override; + virtual float SAL_CALL getDistanceRight() override; + virtual void SAL_CALL setDistanceRight( float _distanceright ) override; + + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAWRAPFORMAT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/wordvbahelper.cxx b/sw/source/ui/vba/wordvbahelper.cxx new file mode 100644 index 0000000000..5bf7e26c77 --- /dev/null +++ b/sw/source/ui/vba/wordvbahelper.cxx @@ -0,0 +1,176 @@ +/* -*- 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 <docsh.hxx> +#include "wordvbahelper.hxx" +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/text/XTextViewCursorSupplier.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <unotxdoc.hxx> +#include <doc.hxx> +#include <IDocumentLayoutAccess.hxx> +#include <view.hxx> +#include <viewsh.hxx> +#include <comphelper/servicehelper.hxx> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +namespace ooo::vba::word +{ + +SwDocShell* getDocShell( const uno::Reference< frame::XModel>& xModel ) +{ + uno::Reference< lang::XUnoTunnel > xTunnel( xModel, uno::UNO_QUERY_THROW ); + SwXTextDocument* pXDoc = comphelper::getFromUnoTunnel<SwXTextDocument>(xTunnel); + return pXDoc ? pXDoc->GetDocShell() : nullptr; +} + +SwView* getView( const uno::Reference< frame::XModel>& xModel ) +{ + SwDocShell* pDocShell = getDocShell( xModel ); + return pDocShell? pDocShell->GetView() : nullptr; +} + +uno::Reference< text::XTextViewCursor > getXTextViewCursor( const uno::Reference< frame::XModel >& xModel ) +{ + uno::Reference< frame::XController > xController = xModel->getCurrentController(); + uno::Reference< text::XTextViewCursorSupplier > xTextViewCursorSupp( xController, uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextViewCursor > xTextViewCursor = xTextViewCursorSupp->getViewCursor(); + return xTextViewCursor; +} + +uno::Reference< style::XStyle > getCurrentPageStyle( const uno::Reference< frame::XModel >& xModel ) +{ + uno::Reference< beans::XPropertySet > xCursorProps( getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW ); + return getCurrentPageStyle( xModel, xCursorProps ); +} + +uno::Reference< style::XStyle > getCurrentPageStyle( const uno::Reference< frame::XModel >& xModel, const uno::Reference< beans::XPropertySet >& xProps ) +{ + OUString aPageStyleName; + xProps->getPropertyValue("PageStyleName") >>= aPageStyleName; + uno::Reference< style::XStyleFamiliesSupplier > xSytleFamSupp( xModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameAccess > xSytleFamNames( xSytleFamSupp->getStyleFamilies(), uno::UNO_SET_THROW ); + uno::Reference< container::XNameAccess > xPageStyles( xSytleFamNames->getByName("PageStyles"), uno::UNO_QUERY_THROW ); + uno::Reference< style::XStyle > xStyle( xPageStyles->getByName( aPageStyleName ), uno::UNO_QUERY_THROW ); + + return xStyle; +} + +sal_Int32 getPageCount( const uno::Reference< frame::XModel>& xModel ) +{ + SwDocShell* pDocShell = getDocShell( xModel ); + SwViewShell* pViewSh = pDocShell ? pDocShell->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() : nullptr; + return pViewSh ? pViewSh->GetPageCount() : 0; +} + +uno::Reference< style::XStyle > getDefaultParagraphStyle( const uno::Reference< frame::XModel >& xModel ) +{ + uno::Reference< style::XStyleFamiliesSupplier > xSytleFamSupp( xModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameAccess > xSytleFamNames( xSytleFamSupp->getStyleFamilies(), uno::UNO_SET_THROW ); + uno::Reference< container::XNameAccess > xParaStyles( xSytleFamNames->getByName("ParagraphStyles"), uno::UNO_QUERY_THROW ); + uno::Reference< style::XStyle > xStyle( xParaStyles->getByName("Standard"), uno::UNO_QUERY_THROW ); + + return xStyle; +} + +uno::Reference< text::XTextRange > getFirstObjectPosition( const uno::Reference< text::XText >& xText ) +{ + // if the first object is table, get the position of first cell + uno::Reference< text::XTextRange > xTextRange; + uno::Reference< container::XEnumerationAccess > xParaAccess( xText, uno::UNO_QUERY_THROW ); + uno::Reference< container::XEnumeration> xParaEnum = xParaAccess->createEnumeration(); + if( xParaEnum->hasMoreElements() ) + { + uno::Reference< lang::XServiceInfo > xServiceInfo( xParaEnum->nextElement(), uno::UNO_QUERY_THROW ); + if( xServiceInfo->supportsService("com.sun.star.text.TextTable") ) + { + uno::Reference< table::XCellRange > xCellRange( xServiceInfo, uno::UNO_QUERY_THROW ); + uno::Reference< text::XText> xFirstCellText( xCellRange->getCellByPosition(0, 0), uno::UNO_QUERY_THROW ); + xTextRange = xFirstCellText->getStart(); + } + } + if( !xTextRange.is() ) + xTextRange = xText->getStart(); + return xTextRange; +} + +uno::Reference< text::XText > getCurrentXText( const uno::Reference< frame::XModel >& xModel ) +{ + uno::Reference< text::XTextRange > xTextRange; + uno::Reference< text::XTextContent > xTextContent( xModel->getCurrentSelection(), uno::UNO_QUERY ); + if( !xTextContent.is() ) + { + uno::Reference< container::XIndexAccess > xIndexAccess( xModel->getCurrentSelection(), uno::UNO_QUERY ); + if( xIndexAccess.is() ) + { + xTextContent.set( xIndexAccess->getByIndex(0), uno::UNO_QUERY ); + } + } + + if( xTextContent.is() ) + xTextRange = xTextContent->getAnchor(); + + if( !xTextRange.is() ) + xTextRange.set( getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW ); + + uno::Reference< text::XText > xText; + try + { + xText = xTextRange->getText(); + } + catch (const uno::RuntimeException&) + { + //catch exception "no text selection" + } + uno::Reference< beans::XPropertySet > xVCProps( xTextRange, uno::UNO_QUERY_THROW ); + while( xVCProps->getPropertyValue("TextTable") >>= xTextContent ) + { + xText = xTextContent->getAnchor()->getText(); + xVCProps.set( xText->createTextCursor(), uno::UNO_QUERY_THROW ); + } + + if( !xText.is() ) + throw uno::RuntimeException("no text selection" ); + + return xText; +} + +bool gotoSelectedObjectAnchor( const uno::Reference< frame::XModel>& xModel ) +{ + bool isObjectSelected = false; + uno::Reference< text::XTextContent > xTextContent( xModel->getCurrentSelection(), uno::UNO_QUERY ); + if( xTextContent.is() ) + { + uno::Reference< text::XTextRange > xTextRange( xTextContent->getAnchor(), uno::UNO_SET_THROW ); + uno::Reference< view::XSelectionSupplier > xSelectSupp( xModel->getCurrentController(), uno::UNO_QUERY_THROW ); + xSelectSupp->select( uno::Any( xTextRange ) ); + isObjectSelected = true; + } + return isObjectSelected; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/wordvbahelper.hxx b/sw/source/ui/vba/wordvbahelper.hxx new file mode 100644 index 0000000000..ba8f77885c --- /dev/null +++ b/sw/source/ui/vba/wordvbahelper.hxx @@ -0,0 +1,63 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_SOURCE_UI_VBA_WORDVBAHELPER_HXX +#define INCLUDED_SW_SOURCE_UI_VBA_WORDVBAHELPER_HXX + +#include <vbahelper/vbahelper.hxx> +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/text/XTextViewCursor.hpp> +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +class SwDocShell; +class SwView; +namespace ooo::vba::word + { + //css::uno::Reference< css::frame::XModel > getCurrentDocument() throw (css::uno::RuntimeException); + SwDocShell* getDocShell( const css::uno::Reference< css::frame::XModel>& xModel ); + SwView* getView( const css::uno::Reference< css::frame::XModel>& xModel ); + /// @throws css::uno::RuntimeException + css::uno::Reference< css::text::XTextViewCursor > getXTextViewCursor( const css::uno::Reference< css::frame::XModel >& xModel ); + /// @throws css::uno::RuntimeException + css::uno::Reference< css::style::XStyle > getCurrentPageStyle( const css::uno::Reference< css::frame::XModel >& xModel ); + /// @throws css::uno::RuntimeException + css::uno::Reference< css::style::XStyle > getCurrentPageStyle( const css::uno::Reference< css::frame::XModel>& xModel, const css::uno::Reference< css::beans::XPropertySet >& xProps ); + /// @throws css::uno::RuntimeException + sal_Int32 getPageCount( const css::uno::Reference< css::frame::XModel>& xModel ); + /// @throws css::uno::RuntimeException + css::uno::Reference< css::style::XStyle > getDefaultParagraphStyle( const css::uno::Reference< css::frame::XModel >& xModel ); + /// @throws css::uno::RuntimeException + css::uno::Reference< css::text::XTextRange > getFirstObjectPosition( const css::uno::Reference< css::text::XText >& xText ); + /// @throws css::uno::RuntimeException + css::uno::Reference< css::text::XText > getCurrentXText( const css::uno::Reference< css::frame::XModel>& xModel ); + /// @throws css::uno::RuntimeException + bool gotoSelectedObjectAnchor( const css::uno::Reference< css::frame::XModel>& xModel ); + + enum E_DIRECTION + { + MOVE_LEFT = 1, + MOVE_RIGHT, + MOVE_UP, + MOVE_DOWN + }; + +} // ooo::vba::word +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |