diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /vbahelper/source | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vbahelper/source')
78 files changed, 13780 insertions, 0 deletions
diff --git a/vbahelper/source/msforms/service.cxx b/vbahelper/source/msforms/service.cxx new file mode 100644 index 000000000..ed348af03 --- /dev/null +++ b/vbahelper/source/msforms/service.cxx @@ -0,0 +1,45 @@ +/* -*- 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/servicedecl.hxx> +#include <sal/log.hxx> + +#include "service.hxx" + +// component exports + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace sdecl = comphelper::service_decl; + +extern "C" +{ + SAL_DLLPUBLIC_EXPORT void * msforms_component_getFactory( + const char * pImplName, void *, void *) + { + SAL_INFO("vbahelper", "In component_getFactory for " << pImplName ); + void* pRet = sdecl::component_getFactoryHelper( + pImplName, {&controlprovider::serviceDecl, &userform::serviceDecl} ); + SAL_INFO("vbahelper", "Ret is 0x" << std::hex << pRet); + return pRet; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/service.hxx b/vbahelper/source/msforms/service.hxx new file mode 100644 index 000000000..a94d54e3c --- /dev/null +++ b/vbahelper/source/msforms/service.hxx @@ -0,0 +1,27 @@ +/* -*- 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_VBAHELPER_SOURCE_MSFORMS_SERVICE_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_SERVICE_HXX + +#include <sal/config.h> + +namespace comphelper::service_decl { class ServiceDecl; } + +namespace controlprovider { +extern comphelper::service_decl::ServiceDecl const serviceDecl; +} + +namespace userform { +extern comphelper::service_decl::ServiceDecl const serviceDecl; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vbahelper/source/msforms/vbabutton.cxx b/vbahelper/source/msforms/vbabutton.cxx new file mode 100644 index 000000000..b1d07ba99 --- /dev/null +++ b/vbahelper/source/msforms/vbabutton.cxx @@ -0,0 +1,128 @@ +/* -*- 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 "vbabutton.hxx" +#include "vbanewfont.hxx" + +using namespace com::sun::star; +using namespace ooo::vba; + +VbaButton::VbaButton( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<AbstractGeometryAttributes> pGeomHelper ) + : ButtonImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ) +{ +} + +// Attributes +OUString SAL_CALL +VbaButton::getCaption() +{ + OUString Label; + m_xProps->getPropertyValue( "Label" ) >>= Label; + return Label; +} + +void SAL_CALL +VbaButton::setCaption( const OUString& _caption ) +{ + m_xProps->setPropertyValue( "Label", uno::makeAny( _caption ) ); +} + +sal_Bool SAL_CALL VbaButton::getAutoSize() +{ + return ScVbaControl::getAutoSize(); +} + +void SAL_CALL VbaButton::setAutoSize( sal_Bool bAutoSize ) +{ + ScVbaControl::setAutoSize( bAutoSize ); +} + +sal_Bool SAL_CALL VbaButton::getLocked() +{ + return ScVbaControl::getLocked(); +} + +void SAL_CALL VbaButton::setLocked( sal_Bool bLocked ) +{ + ScVbaControl::setLocked( bLocked ); +} + +sal_Bool SAL_CALL VbaButton::getCancel() +{ + return false; +} + +void SAL_CALL VbaButton::setCancel( sal_Bool /*bCancel*/ ) +{ + // #STUB +} + +sal_Bool SAL_CALL VbaButton::getDefault() +{ + // #STUB + return false; +} + +void SAL_CALL VbaButton::setDefault( sal_Bool /*bDefault*/ ) +{ + // #STUB +} + +sal_Int32 SAL_CALL VbaButton::getBackColor() +{ + return ScVbaControl::getBackColor(); +} + +void SAL_CALL VbaButton::setBackColor( sal_Int32 nBackColor ) +{ + ScVbaControl::setBackColor( nBackColor ); +} + +sal_Int32 SAL_CALL VbaButton::getForeColor() +{ + return ScVbaControl::getForeColor(); +} + +void SAL_CALL VbaButton::setForeColor( sal_Int32 /*nForeColor*/ ) +{ + // #STUB +} + +uno::Reference< msforms::XNewFont > SAL_CALL VbaButton::getFont() +{ + return new VbaNewFont( m_xProps ); +} + +OUString +VbaButton::getServiceImplName() +{ + return "VbaButton"; +} + +uno::Sequence< OUString > +VbaButton::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.Button" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbabutton.hxx b/vbahelper/source/msforms/vbabutton.hxx new file mode 100644 index 000000000..ad2aed40d --- /dev/null +++ b/vbahelper/source/msforms/vbabutton.hxx @@ -0,0 +1,55 @@ +/* -*- 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_VBAHELPER_SOURCE_MSFORMS_VBABUTTON_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBABUTTON_HXX +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/msforms/XCommandButton.hpp> + +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XCommandButton > ButtonImpl_BASE; + +class VbaButton : public ButtonImpl_BASE +{ +public: + VbaButton( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ); + // Attributes + virtual OUString SAL_CALL getCaption() override; + virtual void SAL_CALL setCaption( const OUString& _caption ) override; + virtual sal_Bool SAL_CALL getAutoSize() override; + virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) override; + virtual sal_Bool SAL_CALL getCancel() override; + virtual void SAL_CALL setCancel( sal_Bool bCancel ) override; + virtual sal_Bool SAL_CALL getDefault() override; + virtual void SAL_CALL setDefault( sal_Bool bDefault ) override; + virtual sal_Int32 SAL_CALL getBackColor() override; + virtual void SAL_CALL setBackColor( sal_Int32 nBackColor ) override; + virtual sal_Int32 SAL_CALL getForeColor() override; + virtual void SAL_CALL setForeColor( sal_Int32 nForeColor ) override; + virtual sal_Bool SAL_CALL getLocked() override; + virtual void SAL_CALL setLocked( sal_Bool bAutoSize ) override; + virtual css::uno::Reference< ov::msforms::XNewFont > SAL_CALL getFont() override; + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBABUTTON_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbacheckbox.cxx b/vbahelper/source/msforms/vbacheckbox.cxx new file mode 100644 index 000000000..61e2216c2 --- /dev/null +++ b/vbahelper/source/msforms/vbacheckbox.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/. + * + * 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 "vbacheckbox.hxx" +#include "vbanewfont.hxx" + +using namespace com::sun::star; +using namespace ooo::vba; + +ScVbaCheckbox::ScVbaCheckbox( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ) + : CheckBoxImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ) +{ +} + +// Attributes +OUString SAL_CALL +ScVbaCheckbox::getCaption() +{ + OUString Label; + m_xProps->getPropertyValue( "Label" ) >>= Label; + return Label; +} + +void SAL_CALL +ScVbaCheckbox::setCaption( const OUString& _caption ) +{ + m_xProps->setPropertyValue( "Label", uno::makeAny( _caption ) ); +} + +uno::Any SAL_CALL +ScVbaCheckbox::getValue() +{ + sal_Int16 nValue = -1; + m_xProps->getPropertyValue( "State" ) >>= nValue; + if( nValue != 0 ) + nValue = -1; +// return uno::makeAny( nValue ); +// I must be missing something MSO says value should be -1 if selected, 0 if not +// selected + return uno::makeAny( nValue == -1 ); +} + +void SAL_CALL +ScVbaCheckbox::setValue( const uno::Any& _value ) +{ + sal_Int16 nValue = 0; + sal_Int16 nOldValue = 0; + m_xProps->getPropertyValue( "State" ) >>= nOldValue; + if( !( _value >>= nValue ) ) + { + bool bValue = false; + _value >>= bValue; + if ( bValue ) + nValue = -1; + } + + if( nValue == -1) + nValue = 1; + m_xProps->setPropertyValue( "State", uno::makeAny( nValue ) ); + if ( nValue != nOldValue ) + fireClickEvent(); +} + +uno::Reference< msforms::XNewFont > SAL_CALL ScVbaCheckbox::getFont() +{ + return new VbaNewFont( m_xProps ); +} + +OUString +ScVbaCheckbox::getServiceImplName() +{ + return "ScVbaCheckbox"; +} + +uno::Sequence< OUString > +ScVbaCheckbox::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.CheckBox" + }; + return aServiceNames; +} + +sal_Int32 SAL_CALL ScVbaCheckbox::getBackColor() +{ + return ScVbaControl::getBackColor(); +} + +void SAL_CALL ScVbaCheckbox::setBackColor( sal_Int32 nBackColor ) +{ + ScVbaControl::setBackColor( nBackColor ); +} + +sal_Bool SAL_CALL ScVbaCheckbox::getAutoSize() +{ + return ScVbaControl::getAutoSize(); +} + +void SAL_CALL ScVbaCheckbox::setAutoSize( sal_Bool bAutoSize ) +{ + ScVbaControl::setAutoSize( bAutoSize ); +} + +sal_Bool SAL_CALL ScVbaCheckbox::getLocked() +{ + return ScVbaControl::getLocked(); +} + +void SAL_CALL ScVbaCheckbox::setLocked( sal_Bool bLocked ) +{ + ScVbaControl::setLocked( bLocked ); +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbacheckbox.hxx b/vbahelper/source/msforms/vbacheckbox.hxx new file mode 100644 index 000000000..91de78eb5 --- /dev/null +++ b/vbahelper/source/msforms/vbacheckbox.hxx @@ -0,0 +1,55 @@ +/* -*- 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_VBAHELPER_SOURCE_MSFORMS_VBACHECKBOX_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBACHECKBOX_HXX +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/msforms/XCheckBox.hpp> +#include <com/sun/star/script/XDefaultProperty.hpp> + +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XCheckBox, css::script::XDefaultProperty > CheckBoxImpl_BASE; + +class ScVbaCheckbox : public CheckBoxImpl_BASE +{ +public: + ScVbaCheckbox( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ); + // Attributes + virtual OUString SAL_CALL getCaption() override; + virtual void SAL_CALL setCaption( const OUString& _caption ) override; + virtual css::uno::Any SAL_CALL getValue() override; + virtual void SAL_CALL setValue( const css::uno::Any& _value ) override; + virtual css::uno::Reference< ov::msforms::XNewFont > SAL_CALL getFont() override; + virtual sal_Int32 SAL_CALL getBackColor() override; + virtual void SAL_CALL setBackColor( sal_Int32 nBackColor ) override; + virtual sal_Bool SAL_CALL getAutoSize() override; + virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) override; + virtual sal_Bool SAL_CALL getLocked() override; + virtual void SAL_CALL setLocked( sal_Bool bAutoSize ) override; + // XDefaultProperty + OUString SAL_CALL getDefaultPropertyName( ) override { return "Value"; } + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBACHECKBOX_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbacombobox.cxx b/vbahelper/source/msforms/vbacombobox.cxx new file mode 100644 index 000000000..07c937ccb --- /dev/null +++ b/vbahelper/source/msforms/vbacombobox.cxx @@ -0,0 +1,306 @@ +/* -*- 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 "vbacombobox.hxx" +#include <comphelper/sequence.hxx> +#include "vbanewfont.hxx" +#include <ooo/vba/msforms/fmStyle.hpp> +#include <ooo/vba/msforms/fmDropButtonStyle.hpp> +#include <ooo/vba/msforms/fmDragBehavior.hpp> +#include <ooo/vba/msforms/fmEnterFieldBehavior.hpp> +#include <ooo/vba/msforms/fmListStyle.hpp> +#include <ooo/vba/msforms/fmTextAlign.hpp> +#include <sal/log.hxx> + +using namespace com::sun::star; +using namespace ooo::vba; + + +//SelectedItems list of integer indexes +//StringItemList list of items + +ScVbaComboBox::ScVbaComboBox( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ) + : ComboBoxImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ) +{ + mpListHelper.reset( new ListControlHelper( m_xProps ) ); + try + { + // grab the default value property name + m_xProps->getPropertyValue( "DataFieldProperty" ) >>= sSourceName; + } + catch( uno::Exception& ) + { + } + if( sSourceName.isEmpty() ) + sSourceName = "Text"; +} + +// Attributes + + +// Value, [read] e.g. getValue returns the value of ooo Text property e.g. the value in +// the drop down +uno::Any SAL_CALL +ScVbaComboBox::getValue() +{ + return m_xProps->getPropertyValue( sSourceName ); +} + +void SAL_CALL +ScVbaComboBox::setListIndex( const uno::Any& _value ) +{ + sal_Int16 nIndex = 0; + if( _value >>= nIndex ) + { + sal_Int32 nOldIndex = -1; + getListIndex() >>= nOldIndex; + uno::Sequence< OUString > sItems; + m_xProps->getPropertyValue( "StringItemList" ) >>= sItems; + if( ( nIndex >= 0 ) && ( sItems.getLength() > nIndex ) ) + { + OUString sText = sItems[ nIndex ]; + m_xProps->setPropertyValue( "Text", uno::makeAny( sText ) ); + + // fire the _Change event + if( nOldIndex != nIndex ) + fireClickEvent(); + } + } +} + +uno::Any SAL_CALL +ScVbaComboBox::getListIndex() +{ + uno::Sequence< OUString > sItems; + m_xProps->getPropertyValue( "StringItemList" ) >>= sItems; + // should really return the item that has focus regardless of + // it been selected + if ( sItems.hasElements() ) + { + OUString sText = getText(); + if (!sText.isEmpty()) + { + sal_Int32 index = comphelper::findValue(sItems, sText); + if (index != -1) + { + SAL_INFO("vbahelper", "getListIndex returning " << index ); + return uno::makeAny( index ); + } + } + } + SAL_INFO("vbahelper", "getListIndex returning -1" ); + return uno::makeAny( sal_Int32( -1 ) ); +} + +// Value, [write]e.g. setValue sets the value in the drop down, and if the value is one +// of the values in the list then the selection is also set +void SAL_CALL +ScVbaComboBox::setValue( const uno::Any& _value ) +{ + // booleans are converted to uppercase strings + OUString oldValue = extractStringFromAny( getValue(), OUString(), true ); + m_xProps->setPropertyValue( sSourceName, uno::Any( extractStringFromAny( _value, OUString(), true ) ) ); + OUString newValue = extractStringFromAny( getValue(), OUString(), true ); + if ( oldValue != newValue ) + { + sal_Int32 index = 0; + uno::Any aIndex = getListIndex(); + aIndex >>= index; + if ( index < 0 ) + fireChangeEvent(); + else + fireClickEvent(); + } +} + +// see Value + +OUString SAL_CALL +ScVbaComboBox::getText() +{ + OUString result; + getValue() >>= result; + return result; +} + +void SAL_CALL +ScVbaComboBox::setText( const OUString& _text ) +{ + setValue( uno::makeAny( _text ) ); // seems the same +} + +// Methods +void SAL_CALL +ScVbaComboBox::AddItem( const uno::Any& pvargItem, const uno::Any& pvargIndex ) +{ + mpListHelper->AddItem( pvargItem, pvargIndex ); +} + +void SAL_CALL +ScVbaComboBox::removeItem( const uno::Any& index ) +{ + mpListHelper->removeItem( index ); +} + +void SAL_CALL +ScVbaComboBox::Clear( ) +{ + mpListHelper->Clear(); +} + +void SAL_CALL +ScVbaComboBox::setRowSource( const OUString& _rowsource ) +{ + ScVbaControl::setRowSource( _rowsource ); + mpListHelper->setRowSource( _rowsource ); +} + +sal_Int32 SAL_CALL +ScVbaComboBox::getListCount() +{ + return mpListHelper->getListCount(); +} + +uno::Any SAL_CALL +ScVbaComboBox::List( const ::uno::Any& pvargIndex, const uno::Any& pvarColumn ) +{ + return mpListHelper->List( pvargIndex, pvarColumn ); +} + +sal_Int32 SAL_CALL ScVbaComboBox::getStyle() +{ + return msforms::fmStyle::fmStyleDropDownCombo; +} + +void SAL_CALL ScVbaComboBox::setStyle( sal_Int32 /*nStyle*/ ) +{ +} + +sal_Int32 SAL_CALL ScVbaComboBox::getDropButtonStyle() +{ + return msforms::fmDropButtonStyle::fmDropButtonStyleArrow; +} + +void SAL_CALL ScVbaComboBox::setDropButtonStyle( sal_Int32 /*nDropButtonStyle*/ ) +{ +} + +sal_Int32 SAL_CALL ScVbaComboBox::getDragBehavior() +{ + return msforms::fmDragBehavior::fmDragBehaviorDisabled; +} + +void SAL_CALL ScVbaComboBox::setDragBehavior( sal_Int32 /*nDragBehavior*/ ) +{ +} + +sal_Int32 SAL_CALL ScVbaComboBox::getEnterFieldBehavior() +{ + return msforms::fmEnterFieldBehavior::fmEnterFieldBehaviorSelectAll; +} + +void SAL_CALL ScVbaComboBox::setEnterFieldBehavior( sal_Int32 /*nEnterFieldBehavior*/ ) +{ +} + +sal_Int32 SAL_CALL ScVbaComboBox::getListStyle() +{ + return msforms::fmListStyle::fmListStylePlain; +} + +void SAL_CALL ScVbaComboBox::setListStyle( sal_Int32 /*nListStyle*/ ) +{ +} + +sal_Int32 SAL_CALL ScVbaComboBox::getTextAlign() +{ + return msforms::fmTextAlign::fmTextAlignLeft; +} + +void SAL_CALL ScVbaComboBox::setTextAlign( sal_Int32 /*nTextAlign*/ ) +{ +} + +sal_Int32 SAL_CALL ScVbaComboBox::getTextLength() +{ + return getText().getLength(); +} + +uno::Reference< msforms::XNewFont > SAL_CALL ScVbaComboBox::getFont() +{ + return new VbaNewFont( m_xProps ); +} + +OUString +ScVbaComboBox::getServiceImplName() +{ + return "ScVbaComboBox"; +} + +sal_Int32 SAL_CALL ScVbaComboBox::getBackColor() +{ + return ScVbaControl::getBackColor(); +} + +void SAL_CALL ScVbaComboBox::setBackColor( sal_Int32 nBackColor ) +{ + ScVbaControl::setBackColor( nBackColor ); +} + +sal_Bool SAL_CALL ScVbaComboBox::getAutoSize() +{ + return ScVbaControl::getAutoSize(); +} + +void SAL_CALL ScVbaComboBox::setAutoSize( sal_Bool bAutoSize ) +{ + ScVbaControl::setAutoSize( bAutoSize ); +} + +sal_Bool SAL_CALL ScVbaComboBox::getLocked() +{ + return ScVbaControl::getLocked(); +} + +void SAL_CALL ScVbaComboBox::setLocked( sal_Bool bLocked ) +{ + ScVbaControl::setLocked( bLocked ); +} + +OUString SAL_CALL ScVbaComboBox::getLinkedCell() +{ + return ScVbaControl::getControlSource(); +} + +void SAL_CALL ScVbaComboBox::setLinkedCell( const OUString& _linkedcell ) +{ + ScVbaControl::setControlSource( _linkedcell ); +} + +uno::Sequence< OUString > +ScVbaComboBox::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.ComboBox" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbacombobox.hxx b/vbahelper/source/msforms/vbacombobox.hxx new file mode 100644 index 000000000..feea8e52c --- /dev/null +++ b/vbahelper/source/msforms/vbacombobox.hxx @@ -0,0 +1,90 @@ +/* -*- 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_VBAHELPER_SOURCE_MSFORMS_VBACOMBOBOX_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBACOMBOBOX_HXX +#include <memory> +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/script/XDefaultProperty.hpp> +#include <ooo/vba/msforms/XComboBox.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +#include "vbacontrol.hxx" +#include "vbalistcontrolhelper.hxx" +#include <vbahelper/vbahelper.hxx> + +typedef cppu::ImplInheritanceHelper<ScVbaControl, ov::msforms::XComboBox, css::script::XDefaultProperty > ComboBoxImpl_BASE; +class ScVbaComboBox : public ComboBoxImpl_BASE +{ + std::unique_ptr< ListControlHelper > mpListHelper; + OUString sSourceName; + +public: + ScVbaComboBox( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ); + + // Attributes + virtual css::uno::Any SAL_CALL getListIndex() override; + virtual ::sal_Int32 SAL_CALL getListCount() override; + virtual void SAL_CALL setListIndex( const css::uno::Any& _value ) override; + virtual css::uno::Any SAL_CALL getValue() override; + virtual void SAL_CALL setValue( const css::uno::Any& _value ) override; + virtual OUString SAL_CALL getText() override; + virtual void SAL_CALL setText( const OUString& _text ) override; + virtual sal_Int32 SAL_CALL getStyle() override; + virtual void SAL_CALL setStyle( sal_Int32 nStyle ) override; + virtual sal_Int32 SAL_CALL getDropButtonStyle() override; + virtual void SAL_CALL setDropButtonStyle( sal_Int32 nDropButtonStyle ) override; + virtual sal_Int32 SAL_CALL getDragBehavior() override; + virtual void SAL_CALL setDragBehavior( sal_Int32 nDragBehavior ) override; + virtual sal_Int32 SAL_CALL getEnterFieldBehavior() override; + virtual void SAL_CALL setEnterFieldBehavior( sal_Int32 nEnterFieldBehavior ) override; + virtual sal_Int32 SAL_CALL getListStyle() override; + virtual void SAL_CALL setListStyle( sal_Int32 nListStyle ) override; + virtual sal_Int32 SAL_CALL getTextAlign() override; + virtual void SAL_CALL setTextAlign( sal_Int32 nTextAlign ) override; + virtual sal_Int32 SAL_CALL getTextLength() override; + virtual css::uno::Reference< ov::msforms::XNewFont > SAL_CALL getFont() override; + virtual sal_Int32 SAL_CALL getBackColor() override; + virtual void SAL_CALL setBackColor( sal_Int32 nBackColor ) override; + virtual sal_Bool SAL_CALL getAutoSize() override; + virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) override; + virtual sal_Bool SAL_CALL getLocked() override; + virtual void SAL_CALL setLocked( sal_Bool bAutoSize ) override; + virtual OUString SAL_CALL getLinkedCell() override; + virtual void SAL_CALL setLinkedCell( const OUString& _linkedcell ) override; + + // Methods + virtual void SAL_CALL AddItem( const css::uno::Any& pvargItem, const css::uno::Any& pvargIndex ) override; + virtual void SAL_CALL removeItem( const css::uno::Any& index ) override; + virtual void SAL_CALL Clear( ) override; + virtual css::uno::Any SAL_CALL List( const css::uno::Any& pvargIndex, const css::uno::Any& pvarColumn ) override; + // XControl + virtual void SAL_CALL setRowSource( const OUString& _rowsource ) override; + + // XDefaultProperty + OUString SAL_CALL getDefaultPropertyName( ) override { return "Value"; } + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbacontrol.cxx b/vbahelper/source/msforms/vbacontrol.cxx new file mode 100644 index 000000000..8efb94de7 --- /dev/null +++ b/vbahelper/source/msforms/vbacontrol.cxx @@ -0,0 +1,801 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <memory> +#include <com/sun/star/form/FormComponentType.hpp> +#include <com/sun/star/awt/XControlModel.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XActionListener.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/drawing/XControlShape.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/view/XControlAccess.hpp> +#include <com/sun/star/form/binding/XBindableValue.hpp> +#include <com/sun/star/form/binding/XListEntrySink.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include <com/sun/star/script/XScriptListener.hpp> +#include <com/sun/star/document/XCodeNameQuery.hpp> +#include <com/sun/star/form/XChangeListener.hpp> +#include <ooo/vba/XControlProvider.hpp> +#include <ooo/vba/msforms/fmMousePointer.hpp> +#include <svtools/bindablecontrolhelper.hxx> +#include "service.hxx" +#include "vbacontrol.hxx" +#include "vbacombobox.hxx" +#include "vbabutton.hxx" +#include "vbalabel.hxx" +#include "vbatextbox.hxx" +#include "vbaradiobutton.hxx" +#include "vbalistbox.hxx" +#include "vbatogglebutton.hxx" +#include "vbacheckbox.hxx" +#include "vbaframe.hxx" +#include "vbascrollbar.hxx" +#include "vbaprogressbar.hxx" +#include "vbamultipage.hxx" +#include "vbaspinbutton.hxx" +#include "vbasystemaxcontrol.hxx" +#include "vbaimage.hxx" +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/window.hxx> +#include <comphelper/servicedecl.hxx> +#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <com/sun/star/form/XFormsSupplier.hpp> +#include <svx/svdobj.hxx> +#include <cppuhelper/implbase.hxx> + +using namespace com::sun::star; +using namespace ooo::vba; + +uno::Reference< css::awt::XWindowPeer > +ScVbaControl::getWindowPeer() +{ + uno::Reference< drawing::XControlShape > xControlShape( m_xControl, uno::UNO_QUERY ); + + uno::Reference< awt::XControlModel > xControlModel; + uno::Reference< css::awt::XWindowPeer > xWinPeer; + if ( !xControlShape.is() ) + { + // would seem to be a Userform control + uno::Reference< awt::XControl > xControl( m_xControl, uno::UNO_QUERY_THROW ); + xWinPeer = xControl->getPeer(); + return xWinPeer; + } + // form control + xControlModel.set( xControlShape->getControl(), uno::UNO_SET_THROW ); + + uno::Reference< view::XControlAccess > xControlAccess( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); + try + { + uno::Reference< awt::XControl > xControl = xControlAccess->getControl( xControlModel ); + xWinPeer = xControl->getPeer(); + } + catch(const uno::Exception&) + { + throw uno::RuntimeException( "The Control does not exist" ); + } + return xWinPeer; +} + +namespace { + +//ScVbaControlListener +class ScVbaControlListener: public cppu::WeakImplHelper< lang::XEventListener > +{ +private: + ScVbaControl *pControl; +public: + explicit ScVbaControlListener( ScVbaControl *pTmpControl ); + + virtual void SAL_CALL disposing( const lang::EventObject& rEventObject ) override; +}; + +} + +ScVbaControlListener::ScVbaControlListener( ScVbaControl *pTmpControl ): pControl( pTmpControl ) +{ +} + +void SAL_CALL +ScVbaControlListener::disposing( const lang::EventObject& ) +{ + if( pControl ) + { + pControl->removeResource(); + pControl = nullptr; + } +} + +//ScVbaControl + +ScVbaControl::ScVbaControl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< ::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ) + : ControlImpl_BASE( xParent, xContext ), m_xControl( xControl ), m_xModel( xModel ) +{ + //add listener + m_xEventListener.set( new ScVbaControlListener( this ) ); + setGeometryHelper( std::move(pGeomHelper) ); + uno::Reference< lang::XComponent > xComponent( m_xControl, uno::UNO_QUERY_THROW ); + xComponent->addEventListener( m_xEventListener ); + + //init m_xProps + uno::Reference< drawing::XControlShape > xControlShape( m_xControl, uno::UNO_QUERY ) ; + uno::Reference< awt::XControl> xUserFormControl( m_xControl, uno::UNO_QUERY ) ; + if ( xControlShape.is() ) // form control + { + m_xProps.set( xControlShape->getControl(), uno::UNO_QUERY_THROW ); + OUString sDefaultControl; + m_xProps->getPropertyValue( "DefaultControl" ) >>= sDefaultControl; + uno::Reference< lang::XMultiComponentFactory > xMFac( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + m_xEmptyFormControl.set( xMFac->createInstanceWithContext( sDefaultControl, mxContext ), uno::UNO_QUERY_THROW ); + } + else if ( xUserFormControl.is() ) // userform control + { + m_xProps.set( xUserFormControl->getModel(), uno::UNO_QUERY_THROW ); + } +} + +ScVbaControl::~ScVbaControl() +{ + if( m_xControl.is() ) + { + uno::Reference< lang::XComponent > xComponent( m_xControl, uno::UNO_QUERY_THROW ); + xComponent->removeEventListener( m_xEventListener ); + } +} + +void +ScVbaControl::setGeometryHelper( std::unique_ptr<AbstractGeometryAttributes> pHelper ) +{ + mpGeometryHelper = std::move( pHelper ); +} + +void ScVbaControl::removeResource() +{ + uno::Reference< lang::XComponent > xComponent( m_xControl, uno::UNO_QUERY_THROW ); + xComponent->removeEventListener( m_xEventListener ); + m_xControl= nullptr; + m_xProps = nullptr; +} + +//In design model has different behavior +sal_Bool SAL_CALL ScVbaControl::getEnabled() +{ + uno::Any aValue = m_xProps->getPropertyValue ( "Enabled" ); + bool bRet = false; + aValue >>= bRet; + return bRet; +} + +void SAL_CALL ScVbaControl::setEnabled( sal_Bool bVisible ) +{ + uno::Any aValue( bVisible ); + m_xProps->setPropertyValue( "Enabled" , aValue); + +} + +sal_Bool SAL_CALL ScVbaControl::getVisible() +{ + bool bVisible( true ); + m_xProps->getPropertyValue ( "EnableVisible" ) >>= bVisible; + uno::Reference< drawing::XControlShape > xControlShape( m_xControl, uno::UNO_QUERY ); + if ( xControlShape.is() ) + { + bool bEnableVisible = bVisible; + uno::Reference< beans::XPropertySet > xProps( m_xControl, uno::UNO_QUERY_THROW ); + xProps->getPropertyValue ( "Visible" ) >>= bVisible; + bVisible = bVisible && bEnableVisible; + } + else + m_xProps->getPropertyValue ( "EnableVisible" ) >>= bVisible; + return bVisible; +} + +void SAL_CALL ScVbaControl::setVisible( sal_Bool bVisible ) +{ + uno::Any aValue( bVisible ); + m_xProps->setPropertyValue( "EnableVisible" , aValue); + uno::Reference< drawing::XControlShape > xControlShape( m_xControl, uno::UNO_QUERY ); + if ( xControlShape.is() ) + { + uno::Reference< beans::XPropertySet > xProps( m_xControl, uno::UNO_QUERY_THROW ); + xProps->setPropertyValue ( "Visible", aValue ); + } +} +double SAL_CALL ScVbaControl::getHeight() +{ + return mpGeometryHelper->getHeight(); +} +void SAL_CALL ScVbaControl::setHeight( double _height ) +{ + mpGeometryHelper->setHeight( _height ); +} + +double SAL_CALL ScVbaControl::getWidth() +{ + return mpGeometryHelper->getWidth(); +} +void SAL_CALL ScVbaControl::setWidth( double _width ) +{ + mpGeometryHelper->setWidth( _width ); +} + +double SAL_CALL +ScVbaControl::getLeft() +{ + return mpGeometryHelper->getLeft(); +} + +void SAL_CALL +ScVbaControl::setLeft( double _left ) +{ + mpGeometryHelper->setLeft( _left ); +} + +double SAL_CALL +ScVbaControl::getTop() +{ + return mpGeometryHelper->getTop(); +} + +void SAL_CALL +ScVbaControl::setTop( double _top ) +{ + mpGeometryHelper->setTop( _top ); +} + +uno::Reference< uno::XInterface > SAL_CALL +ScVbaControl::getObject() +{ + uno::Reference< msforms::XControl > xRet( this ); + return xRet; +} + +void SAL_CALL ScVbaControl::SetFocus() +{ + uno::Reference< awt::XWindow > xWin( m_xControl, uno::UNO_QUERY_THROW ); + xWin->setFocus(); +} + +void SAL_CALL ScVbaControl::Move( double Left, double Top, const uno::Any& Width, const uno::Any& Height ) +{ + double nWidth = 0.0; + double nHeight = 0.0; + + setLeft( Left ); + setTop( Top ); + + if ( Width >>= nWidth ) + setWidth( nWidth ); + + if ( Height >>= nHeight ) + setHeight( nHeight ); +} + +OUString SAL_CALL +ScVbaControl::getControlSource() +{ +// #FIXME I *hate* having these upstream differences +// but this is necessary until I manage to upstream other +// dependent parts + OUString sControlSource; + uno::Reference< form::binding::XBindableValue > xBindable( m_xProps, uno::UNO_QUERY ); + if ( xBindable.is() ) + { + try + { + uno::Reference< lang::XMultiServiceFactory > xFac( m_xModel, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xConvertor( xFac->createInstance( "com.sun.star.table.CellAddressConversion" ), uno::UNO_QUERY ); + uno::Reference< beans::XPropertySet > xProps( xBindable->getValueBinding(), uno::UNO_QUERY_THROW ); + table::CellAddress aAddress; + xProps->getPropertyValue( "BoundCell" ) >>= aAddress; + xConvertor->setPropertyValue( "Address" , uno::makeAny( aAddress ) ); + xConvertor->getPropertyValue( "XLA1Representation" ) >>= sControlSource; + } + catch(const uno::Exception&) + { + } + } + return sControlSource; +} + +void SAL_CALL +ScVbaControl::setControlSource( const OUString& _controlsource ) +{ + // afaik this is only relevant for Excel documents ( and we need to set up a + // reference tab in case no Sheet is specified in "_controlsource" + // Can't use the active sheet either, code may of course access + uno::Reference< drawing::XDrawPagesSupplier > xSupplier( m_xModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xIndex( xSupplier->getDrawPages(), uno::UNO_QUERY_THROW ); + sal_Int32 nLen = xIndex->getCount(); + bool bMatched = false; + sal_Int16 nRefTab = 0; + for ( sal_Int32 index = 0; index < nLen; ++index ) + { + try + { + uno::Reference< form::XFormsSupplier > xFormSupplier( xIndex->getByIndex( index ), uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xFormIndex( xFormSupplier->getForms(), uno::UNO_QUERY_THROW ); + // get the www-standard container + uno::Reference< container::XIndexAccess > xFormControls( xFormIndex->getByIndex(0), uno::UNO_QUERY_THROW ); + sal_Int32 nCntrls = xFormControls->getCount(); + for( sal_Int32 cIndex = 0; cIndex < nCntrls; ++cIndex ) + { + uno::Reference< uno::XInterface > xControl( xFormControls->getByIndex( cIndex ), uno::UNO_QUERY_THROW ); + bMatched = ( m_xProps == xControl ); + if ( bMatched ) + { + nRefTab = index; + break; + } + } + } + catch( uno::Exception& ) {} + if ( bMatched ) + break; + } + + svt::BindableControlHelper::ApplyListSourceAndBindableData( m_xModel, m_xProps, _controlsource, "", sal_uInt16( nRefTab ) ); +} + +OUString SAL_CALL +ScVbaControl::getRowSource() +{ + OUString sRowSource; + uno::Reference< form::binding::XListEntrySink > xListSink( m_xProps, uno::UNO_QUERY ); + if ( xListSink.is() ) + { + try + { + uno::Reference< lang::XMultiServiceFactory > xFac( m_xModel, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xConvertor( xFac->createInstance( "com.sun.star.table.CellRangeAddressConversion" ), uno::UNO_QUERY ); + + uno::Reference< beans::XPropertySet > xProps( xListSink->getListEntrySource(), uno::UNO_QUERY_THROW ); + table::CellRangeAddress aAddress; + xProps->getPropertyValue( "CellRange" ) >>= aAddress; + xConvertor->setPropertyValue( "Address" , uno::makeAny( aAddress ) ); + xConvertor->getPropertyValue( "XLA1Representation" ) >>= sRowSource; + } + catch(const uno::Exception&) + { + } + } + return sRowSource; +} + +void SAL_CALL +ScVbaControl::setRowSource( const OUString& _rowsource ) +{ + svt::BindableControlHelper::ApplyListSourceAndBindableData( m_xModel, m_xProps, "", _rowsource ); +} + +OUString SAL_CALL +ScVbaControl::getName() +{ + OUString sName; + m_xProps->getPropertyValue( "Name" ) >>= sName; + return sName; + +} + +void SAL_CALL +ScVbaControl::setName( const OUString& _name ) +{ + m_xProps->setPropertyValue( "Name" , uno::makeAny( _name ) ); + } + +OUString SAL_CALL +ScVbaControl::getControlTipText() +{ + OUString sName; + m_xProps->getPropertyValue( "HelpText" ) >>= sName; + return sName; +} + +void SAL_CALL +ScVbaControl::setControlTipText( const OUString& rsToolTip ) +{ + m_xProps->setPropertyValue( "HelpText" , uno::makeAny( rsToolTip ) ); +} + +OUString SAL_CALL ScVbaControl::getTag() +{ + return m_aControlTag; +} + +void SAL_CALL ScVbaControl::setTag( const OUString& aTag ) +{ + m_aControlTag = aTag; +} + +::sal_Int32 SAL_CALL ScVbaControl::getForeColor() +{ + Color nForeColor; + m_xProps->getPropertyValue( "TextColor" ) >>= nForeColor; + return OORGBToXLRGB( nForeColor ); +} + +namespace { + +struct PointerStyles +{ + long msoPointerStyle; + PointerStyle loPointStyle; +}; + +} + +// 1 -> 1 map of styles ( some dubious choices in there though ) +PointerStyles const styles[] = { + /// assuming pointer default is Arrow + { msforms::fmMousePointer::fmMousePointerDefault, PointerStyle::Arrow }, + { msforms::fmMousePointer::fmMousePointerArrow, PointerStyle::Arrow }, + { msforms::fmMousePointer::fmMousePointerCross, PointerStyle::Cross }, + { msforms::fmMousePointer::fmMousePointerIBeam, PointerStyle::Text }, + { msforms::fmMousePointer::fmMousePointerSizeNESW, PointerStyle::AutoScrollNSWE }, // #TODO not correct, need to check, need to find the right one + { msforms::fmMousePointer::fmMousePointerSizeNS, PointerStyle::AutoScrollNS }, + { msforms::fmMousePointer::fmMousePointerSizeNWSE, PointerStyle::AutoScrollNSWE }, // #TODO not correct, need to check, need to find the right one + { msforms::fmMousePointer::fmMousePointerSizeWE, PointerStyle::AutoScrollWE }, + { msforms::fmMousePointer::fmMousePointerUpArrow, PointerStyle::WindowNSize }, + { msforms::fmMousePointer::fmMousePointerHourGlass, PointerStyle::Wait }, + { msforms::fmMousePointer::fmMousePointerNoDrop, PointerStyle::NotAllowed }, + { msforms::fmMousePointer::fmMousePointerAppStarting, PointerStyle::Wait }, + { msforms::fmMousePointer::fmMousePointerHelp, PointerStyle::Help }, + { msforms::fmMousePointer::fmMousePointerSizeAll, PointerStyle::Cross }, + { msforms::fmMousePointer::fmMousePointerCustom, PointerStyle::Arrow }, // not supported I guess + +}; + +static long lcl_loPointerToMsoPointer( PointerStyle eType ) +{ + long nRet = msforms::fmMousePointer::fmMousePointerDefault; + for ( int i = 0; i < int(SAL_N_ELEMENTS( styles )); ++i ) + { + if ( styles[ i ].loPointStyle == eType ) + { + nRet = styles[ i ].msoPointerStyle; + break; + } + } + return nRet; +} + +static PointerStyle lcl_msoPointerToLOPointer( long msoPointerStyle ) +{ + PointerStyle aPointer( PointerStyle::Arrow ); + for ( int i = 0; i < int(SAL_N_ELEMENTS( styles )); ++i ) + { + if ( styles[ i ].msoPointerStyle == msoPointerStyle ) + { + aPointer = styles[ i ].loPointStyle; + break; + } + } + return aPointer; +} + +::sal_Int32 SAL_CALL +ScVbaControl::getMousePointer() +{ + PointerStyle eType = PointerStyle::Arrow; // default ? + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( getWindowPeer() ); + if ( pWindow ) + { + eType = pWindow->GetPointer(); + } + return lcl_loPointerToMsoPointer( eType ); +} + +void SAL_CALL +ScVbaControl::setMousePointer( ::sal_Int32 _mousepointer ) +{ + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( getWindowPeer() ); + if ( pWindow ) + { + PointerStyle aPointer = lcl_msoPointerToLOPointer( _mousepointer ); + pWindow->SetPointer( aPointer ); + } +} + +void SAL_CALL ScVbaControl::fireEvent( const script::ScriptEvent& rEvt ) +{ + script::ScriptEvent evt( rEvt ); + uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< script::XScriptListener > xScriptListener( xServiceManager->createInstanceWithContext( "ooo.vba.EventListener" , mxContext ), uno::UNO_QUERY_THROW ); + + uno::Reference< beans::XPropertySet > xProps( xScriptListener, uno::UNO_QUERY_THROW ); + xProps->setPropertyValue( "Model" , uno::makeAny( m_xModel ) ); + + // handling for sheet control + uno::Reference< msforms::XControl > xThisControl( this ); + try + { + evt.Arguments.realloc( 1 ); + lang::EventObject aEvt; + + uno::Reference< drawing::XControlShape > xControlShape( m_xControl, uno::UNO_QUERY ) ; + uno::Reference< awt::XControl > xControl( m_xControl, uno::UNO_QUERY ) ; + + if ( xControlShape.is() ) + { + evt.Source = xControlShape; + aEvt.Source = m_xEmptyFormControl; + // Set up proper scriptcode + uno::Reference< lang::XMultiServiceFactory > xDocFac( m_xModel, uno::UNO_QUERY_THROW ); + uno::Reference< document::XCodeNameQuery > xNameQuery( xDocFac->createInstance( "ooo.vba.VBACodeNameProvider" ), uno::UNO_QUERY_THROW ); + uno::Reference< uno::XInterface > xIf( xControlShape->getControl(), uno::UNO_QUERY_THROW ); + evt.ScriptCode = xNameQuery->getCodeNameForObject( xIf ); + // handle if we passed in our own arguments + if ( !rEvt.Arguments.hasElements() ) + evt.Arguments[ 0 ] <<= aEvt; + xScriptListener->firing( evt ); + } + else + { + if ( xControl.is() ) // normal control ( from dialog/userform ) + { + // #FIXME We should probably store a reference to the + // parent dialog/userform here (otherwise the name of + // dialog could be changed and we won't be aware of it. + // (OTOH this is probably an unlikely scenario) + evt.Source = xThisControl; + aEvt.Source = xControl; + evt.ScriptCode = m_sLibraryAndCodeName; + evt.Arguments[ 0 ] <<= aEvt; + xScriptListener->firing( evt ); + } + } + } + catch(const uno::Exception&) + { + } +} +void ScVbaControl::fireChangeEvent() +{ + script::ScriptEvent evt; + evt.ScriptType = "VBAInterop"; + evt.ListenerType = cppu::UnoType<form::XChangeListener>::get(); + evt.MethodName = "changed"; + fireEvent( evt ); +} + +void ScVbaControl::fireClickEvent() +{ + script::ScriptEvent evt; + evt.ScriptType = "VBAInterop"; + evt.ListenerType = cppu::UnoType<awt::XActionListener>::get(); + evt.MethodName = "actionPerformed"; + fireEvent( evt ); +} + +sal_Int32 SAL_CALL ScVbaControl::getTabIndex() +{ + return 1; +} + +void SAL_CALL ScVbaControl::setTabIndex( sal_Int32 /*nTabIndex*/ ) +{ +} + +//ScVbaControlFactory + +/*static*/ uno::Reference< msforms::XControl > ScVbaControlFactory::createShapeControl( + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< drawing::XControlShape >& xControlShape, + const uno::Reference< frame::XModel >& xModel ) +{ + uno::Reference< beans::XPropertySet > xProps( xControlShape->getControl(), uno::UNO_QUERY_THROW ); + sal_Int32 nClassId = -1; + xProps->getPropertyValue( "ClassId" ) >>= nClassId; + uno::Reference< XHelperInterface > xVbaParent; // #FIXME - should be worksheet I guess + uno::Reference< drawing::XShape > xShape( xControlShape, uno::UNO_QUERY_THROW ); + ::std::unique_ptr< ConcreteXShapeGeometryAttributes > xGeoHelper( new ConcreteXShapeGeometryAttributes( xShape ) ); + switch( nClassId ) + { + case form::FormComponentType::COMBOBOX: + return new ScVbaComboBox( xVbaParent, xContext, xControlShape, xModel, std::move(xGeoHelper) ); + case form::FormComponentType::COMMANDBUTTON: + { + bool bToggle = false; + xProps->getPropertyValue( "Toggle" ) >>= bToggle; + if ( bToggle ) + return new ScVbaToggleButton( xVbaParent, xContext, xControlShape, xModel, std::move(xGeoHelper) ); + else + return new VbaButton( xVbaParent, xContext, xControlShape, xModel, std::move(xGeoHelper) ); + } + case form::FormComponentType::FIXEDTEXT: + return new ScVbaLabel( xVbaParent, xContext, xControlShape, xModel, std::move(xGeoHelper) ); + case form::FormComponentType::TEXTFIELD: + return new ScVbaTextBox( xVbaParent, xContext, xControlShape, xModel, std::move(xGeoHelper) ); + case form::FormComponentType::CHECKBOX: + return new ScVbaCheckbox( xVbaParent, xContext, xControlShape, xModel, std::move(xGeoHelper) ); + case form::FormComponentType::RADIOBUTTON: + return new ScVbaRadioButton( xVbaParent, xContext, xControlShape, xModel, std::move(xGeoHelper) ); + case form::FormComponentType::LISTBOX: + return new ScVbaListBox( xVbaParent, xContext, xControlShape, xModel, std::move(xGeoHelper) ); + case form::FormComponentType::SPINBUTTON: + return new ScVbaSpinButton( xVbaParent, xContext, xControlShape, xModel, std::move(xGeoHelper) ); + case form::FormComponentType::IMAGECONTROL: + return new ScVbaImage( xVbaParent, xContext, xControlShape, xModel, std::move(xGeoHelper) ); + case form::FormComponentType::SCROLLBAR: + return new ScVbaScrollBar( xVbaParent, xContext, xControlShape, xModel, std::move(xGeoHelper) ); + } + throw uno::RuntimeException( "Unsupported control." ); +} + +/*static*/ uno::Reference< msforms::XControl > ScVbaControlFactory::createUserformControl( + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< awt::XControl >& xControl, + const uno::Reference< awt::XControl >& xDialog, + const uno::Reference< frame::XModel >& xModel, + double fOffsetX, double fOffsetY ) +{ + uno::Reference< beans::XPropertySet > xProps( xControl->getModel(), uno::UNO_QUERY_THROW ); + uno::Reference< lang::XServiceInfo > xServiceInfo( xProps, uno::UNO_QUERY_THROW ); + uno::Reference< msforms::XControl > xVBAControl; + uno::Reference< XHelperInterface > xVbaParent; // #FIXME - should be worksheet I guess + ::std::unique_ptr< UserFormGeometryHelper > xGeoHelper( new UserFormGeometryHelper( xControl, fOffsetX, fOffsetY ) ); + + if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) ) + xVBAControl.set( new ScVbaCheckbox( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) ) + xVBAControl.set( new ScVbaRadioButton( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlEditModel" ) ) + xVBAControl.set( new ScVbaTextBox( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper), true ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlButtonModel" ) ) + { + bool bToggle = false; + xProps->getPropertyValue( "Toggle" ) >>= bToggle; + if ( bToggle ) + xVBAControl.set( new ScVbaToggleButton( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + else + xVBAControl.set( new VbaButton( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + } + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ) ) + xVBAControl.set( new ScVbaComboBox( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlListBoxModel" ) ) + xVBAControl.set( new ScVbaListBox( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) ) + xVBAControl.set( new ScVbaLabel( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlImageControlModel" ) ) + xVBAControl.set( new ScVbaImage( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ) ) + xVBAControl.set( new ScVbaProgressBar( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) ) + xVBAControl.set( new ScVbaFrame( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper), xDialog ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ) ) + xVBAControl.set( new ScVbaScrollBar( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoMultiPageModel" ) ) + xVBAControl.set( new ScVbaMultiPage( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlSpinButtonModel" ) ) + xVBAControl.set( new ScVbaSpinButton( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.custom.awt.UnoControlSystemAXContainerModel" ) ) + xVBAControl.set( new VbaSystemAXControl( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + // #FIXME implement a page control + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoPageModel" ) ) + xVBAControl.set( new ScVbaControl( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper) ) ); + else if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoFrameModel" ) ) + xVBAControl.set( new ScVbaFrame( xVbaParent, xContext, xControl, xModel, std::move(xGeoHelper), xDialog ) ); + if( xVBAControl.is() ) + return xVBAControl; + throw uno::RuntimeException( "Unsupported control." ); +} + +OUString +ScVbaControl::getServiceImplName() +{ + return "ScVbaControl"; +} + +uno::Sequence< OUString > +ScVbaControl::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.excel.Control" + }; + return aServiceNames; +} + +sal_Int32 const nSysCols[] = { 0xC8D0D4, 0x0, 0x6A240A, 0x808080, 0xE4E4E4, 0xFFFFFF, 0x0, 0x0, 0x0, 0xFFFFFF, 0xE4E4E4, 0xE4E4E4, 0x808080, 0x6A240A, 0xFFFFFF, 0xE4E4E4, 0x808080, 0x808080, 0x0, 0xC8D0D4, 0xFFFFFF, 0x404040, 0xE4E4E4, 0x0, 0xE1FFFF }; + +sal_Int32 ScVbaControl::getBackColor() +{ + sal_Int32 nBackColor = 0; + m_xProps->getPropertyValue( "BackgroundColor" ) >>= nBackColor; + return nBackColor; +} + +void ScVbaControl::setBackColor( sal_Int32 nBackColor ) +{ + auto const col = static_cast<sal_uInt32>(nBackColor); + if ( ( col >= sal_uInt32(0x80000000) ) && + ( col <= sal_uInt32(0x80000000) + SAL_N_ELEMENTS(nSysCols) ) ) + { + nBackColor = nSysCols[ col & 0x0FF]; + } + m_xProps->setPropertyValue( "BackgroundColor" , uno::makeAny( XLRGBToOORGB( nBackColor ) ) ); +} + +bool ScVbaControl::getAutoSize() const +{ + bool bIsResizeEnabled = false; + uno::Reference< uno::XInterface > xIf( m_xControl, uno::UNO_SET_THROW ); + SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xIf ); + if ( pObj ) + bIsResizeEnabled = !pObj->IsResizeProtect(); + return bIsResizeEnabled; +} + +// currently no implementation for this +void ScVbaControl::setAutoSize( bool bAutoSize ) +{ + uno::Reference< uno::XInterface > xIf( m_xControl, uno::UNO_SET_THROW ); + SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xIf ); + if ( pObj ) + pObj->SetResizeProtect( !bAutoSize ); +} + +bool ScVbaControl::getLocked() +{ + bool bRes( false ); + m_xProps->getPropertyValue( "ReadOnly" ) >>= bRes; + return bRes; +} + +void ScVbaControl::setLocked( bool bLocked ) +{ + m_xProps->setPropertyValue( "ReadOnly" , uno::makeAny( bLocked ) ); +} + +namespace { + +class ControlProviderImpl : public cppu::WeakImplHelper< XControlProvider > +{ + uno::Reference< uno::XComponentContext > m_xCtx; +public: + explicit ControlProviderImpl( const uno::Reference< uno::XComponentContext >& xCtx ) : m_xCtx( xCtx ) {} + virtual uno::Reference< msforms::XControl > SAL_CALL createControl( const uno::Reference< drawing::XControlShape >& xControl, const uno::Reference< frame::XModel >& xDocOwner ) override; +}; + +} + +uno::Reference< msforms::XControl > SAL_CALL +ControlProviderImpl::createControl( const uno::Reference< drawing::XControlShape >& xControlShape, const uno::Reference< frame::XModel >& xDocOwner ) +{ + uno::Reference< msforms::XControl > xControlToReturn; + if ( xControlShape.is() ) + xControlToReturn = ScVbaControlFactory::createShapeControl( m_xCtx, xControlShape, xDocOwner ); + return xControlToReturn; + +} + +namespace controlprovider +{ +namespace sdecl = comphelper::service_decl; +sdecl::class_<ControlProviderImpl, sdecl::with_args<false> > const serviceImpl; +sdecl::ServiceDecl const serviceDecl( + serviceImpl, + "ControlProviderImpl", + "ooo.vba.ControlProvider" ); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbacontrol.hxx b/vbahelper/source/msforms/vbacontrol.hxx new file mode 100644 index 000000000..e96cd5fa9 --- /dev/null +++ b/vbahelper/source/msforms/vbacontrol.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/. + * + * 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_VBAHELPER_SOURCE_MSFORMS_VBACONTROL_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBACONTROL_HXX + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/drawing/XControlShape.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XWindowPeer.hpp> +#include <com/sun/star/script/ScriptEvent.hpp> +#include <ooo/vba/msforms/XControl.hpp> + +#include <vbahelper/vbahelper.hxx> +#include <vbahelper/vbahelperinterface.hxx> +#include <memory> + +typedef InheritedHelperInterfaceWeakImpl< ov::msforms::XControl > ControlImpl_BASE; + +class ScVbaControl : public ControlImpl_BASE +{ +private: + css::uno::Reference< css::lang::XEventListener > m_xEventListener; + css::uno::Reference< css::awt::XControl > m_xEmptyFormControl; +protected: + // awt control has nothing similar to Tag property of Mso controls, + // whether it is necessary is another question + OUString m_aControlTag; + + OUString m_sLibraryAndCodeName; + std::unique_ptr< ov::AbstractGeometryAttributes > mpGeometryHelper; + css::uno::Reference< css::beans::XPropertySet > m_xProps; + css::uno::Reference< css::uno::XInterface > m_xControl; + css::uno::Reference< css::frame::XModel > m_xModel; + + /// @throws css::uno::RuntimeException + css::uno::Reference< css::awt::XWindowPeer > getWindowPeer(); + void fireChangeEvent(); + void fireClickEvent(); +public: + ScVbaControl( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pHelper ); + virtual ~ScVbaControl() override; + // This class will own the helper, so make sure it is allocated from + // the heap + void setGeometryHelper( std::unique_ptr<ov::AbstractGeometryAttributes> pHelper ); + // sets the name of the associated library ( used for UserForm controls ) + void setLibraryAndCodeName( const OUString& sLibCodeName ) { m_sLibraryAndCodeName = sLibCodeName; } + + // XControl + virtual sal_Bool SAL_CALL getEnabled() override; + virtual void SAL_CALL setEnabled( sal_Bool _enabled ) override; + virtual sal_Bool SAL_CALL getVisible() override; + virtual void SAL_CALL setVisible( sal_Bool _visible ) override; + virtual double SAL_CALL getHeight() override; + virtual void SAL_CALL setHeight( double _height ) override; + virtual double SAL_CALL getWidth() override; + virtual void SAL_CALL setWidth( double _width ) override; + virtual double SAL_CALL getLeft() override; + virtual void SAL_CALL setLeft( double _left ) override; + virtual double SAL_CALL getTop() override; + virtual void SAL_CALL setTop( double _top ) override; + virtual void SAL_CALL SetFocus( ) override; + virtual void SAL_CALL Move( double Left, double Top, const css::uno::Any& Width, const css::uno::Any& Height ) override; + virtual void SAL_CALL fireEvent( const css::script::ScriptEvent& evt ) override; + + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getObject() override; + virtual OUString SAL_CALL getControlSource() override; + virtual void SAL_CALL setControlSource( const OUString& _controlsource ) override; + virtual OUString SAL_CALL getRowSource() override; + virtual void SAL_CALL setRowSource( const OUString& _rowsource ) override; + virtual OUString SAL_CALL getName() override; + virtual void SAL_CALL setName( const OUString& _name ) override; + virtual OUString SAL_CALL getControlTipText() override; + virtual void SAL_CALL setControlTipText( const OUString& ) override; + virtual OUString SAL_CALL getTag() override; + virtual void SAL_CALL setTag( const OUString& aTag ) override; + virtual sal_Int32 SAL_CALL getTabIndex() override; + virtual void SAL_CALL setTabIndex( sal_Int32 nTabIndex ) override; + virtual ::sal_Int32 SAL_CALL getMousePointer() override; + virtual void SAL_CALL setMousePointer( ::sal_Int32 _mousepointer ) override; + //remove resource because ooo.vba.excel.XControl is a wrapper of com.sun.star.drawing.XControlShape + /// @throws css::uno::RuntimeException + void removeResource(); + /// @throws css::uno::RuntimeException + virtual ::sal_Int32 SAL_CALL getForeColor(); + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + //General helper methods for properties (may or may not be relevant for all + //controls) + /// @throws css::uno::RuntimeException + sal_Int32 getBackColor(); + /// @throws css::uno::RuntimeException + void setBackColor( sal_Int32 nBackColor ); + /// @throws css::uno::RuntimeException + bool getAutoSize() const; + /// @throws css::uno::RuntimeException + void setAutoSize( bool bAutoSize ); + /// @throws css::uno::RuntimeException + bool getLocked(); + /// @throws css::uno::RuntimeException + void setLocked( bool bAutoSize ); +}; + + +namespace ScVbaControlFactory +{ + /// @throws css::uno::RuntimeException + css::uno::Reference< ov::msforms::XControl > createShapeControl( + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::drawing::XControlShape >& xControlShape, + const css::uno::Reference< css::frame::XModel >& xModel ); + + /// @throws css::uno::RuntimeException + css::uno::Reference< ov::msforms::XControl > createUserformControl( + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::awt::XControl >& xControl, + const css::uno::Reference< css::awt::XControl >& xDialog, + const css::uno::Reference< css::frame::XModel >& xModel, + double fOffsetX, double fOffsetY ); +} + +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBACONTROL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbacontrols.cxx b/vbahelper/source/msforms/vbacontrols.cxx new file mode 100644 index 000000000..56a0b80ae --- /dev/null +++ b/vbahelper/source/msforms/vbacontrols.cxx @@ -0,0 +1,485 @@ +/* -*- 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/awt/XControl.hpp> +#include <com/sun/star/awt/XControlContainer.hpp> +#include <com/sun/star/awt/FontWeight.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/awt/FontStrikeout.hpp> +#include <com/sun/star/awt/FontUnderline.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/script/XInvocation.hpp> +#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include "vbacontrols.hxx" +#include "vbacontrol.hxx" +#include <cppuhelper/exc_hlp.hxx> +#include <cppuhelper/implbase.hxx> +#include <unordered_map> + +using namespace com::sun::star; +using namespace ooo::vba; + + +typedef std::unordered_map< OUString, sal_Int32 > ControlIndexMap; + +namespace { + +class ControlArrayWrapper : public ::cppu::WeakImplHelper< container::XNameAccess, container::XIndexAccess > +{ + uno::Reference< awt::XControlContainer > mxDialog; + uno::Sequence< OUString > msNames; + std::vector< uno::Reference< awt::XControl > > mControls; + ControlIndexMap mIndices; + +private: + void SetArrayElementTo( const uno::Reference< awt::XControl >& xCtrl, sal_Int32 nIndex ) + { + // initialize the element with specified index to the control + if ( xCtrl.is() ) + { + if ( nIndex == -1 ) + nIndex = msNames.getLength(); + + if ( nIndex >= msNames.getLength() ) + msNames.realloc( nIndex ); + + msNames[ nIndex ] = getControlName( xCtrl ); + mControls.push_back( xCtrl ); + mIndices[ msNames[ nIndex ] ] = nIndex; + } + } +public: + explicit ControlArrayWrapper( const uno::Reference< awt::XControl >& xDialog ) + { + try + { + mxDialog.set( xDialog, uno::UNO_QUERY_THROW ); + uno::Sequence< uno::Reference< awt::XControl > > sXControls = mxDialog->getControls(); + + msNames.realloc( sXControls.getLength() ); + for ( sal_Int32 i = 0; i < sXControls.getLength(); ++i ) + SetArrayElementTo( sXControls[ i ], i ); + } + catch (const uno::Exception&) + { + // accept the case when the dialog already does not exist + // in this case the wrapper should work in dummy mode + } + } + + static OUString getControlName( const uno::Reference< awt::XControl >& xCtrl ) + { + if ( !xCtrl.is() ) + throw uno::RuntimeException(); + + uno::Reference< beans::XPropertySet > xProp( xCtrl->getModel(), uno::UNO_QUERY_THROW ); + OUString sName; + xProp->getPropertyValue( "Name" ) >>= sName; + return sName; + } + + + // XElementAccess + virtual uno::Type SAL_CALL getElementType( ) override + { + return cppu::UnoType<awt::XControl>::get(); + } + + virtual sal_Bool SAL_CALL hasElements( ) override + { + return ( !mControls.empty() ); + } + + // XNameAccess + virtual uno::Any SAL_CALL getByName( const OUString& aName ) override + { + if ( !hasByName( aName ) ) + throw container::NoSuchElementException(); + return getByIndex( mIndices[ aName ] ); + } + + virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override + { + return msNames; + } + + virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override + { + ControlIndexMap::iterator it = mIndices.find( aName ); + return it != mIndices.end(); + } + + // XElementAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override + { + return mControls.size(); + } + + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override + { + if ( Index < 0 || Index >= static_cast< sal_Int32 >( mControls.size() ) ) + throw lang::IndexOutOfBoundsException(); + return uno::makeAny( mControls[ Index ] ); + } +}; + + +class ControlsEnumWrapper : public EnumerationHelper_BASE +{ + uno::Reference<uno::XComponentContext > m_xContext; + uno::Reference<container::XIndexAccess > m_xIndexAccess; + uno::Reference<awt::XControl > m_xDlg; + uno::Reference< frame::XModel > m_xModel; + double mfOffsetX; + double mfOffsetY; + sal_Int32 nIndex; + +public: + + ControlsEnumWrapper( + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< container::XIndexAccess >& xIndexAccess, + const uno::Reference< awt::XControl >& xDlg, + const uno::Reference< frame::XModel >& xModel, + double fOffsetX, double fOffsetY ) : + m_xContext( xContext), + m_xIndexAccess( xIndexAccess ), + m_xDlg( xDlg ), + m_xModel( xModel ), + mfOffsetX( fOffsetX ), + mfOffsetY( fOffsetY ), + nIndex( 0 ) {} + + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( nIndex < m_xIndexAccess->getCount() ); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( nIndex < m_xIndexAccess->getCount() ) + { + uno::Reference< awt::XControl > xControl; + m_xIndexAccess->getByIndex( nIndex++ ) >>= xControl; + + uno::Reference< msforms::XControl > xVBAControl; + if ( xControl.is() && m_xDlg.is() ) + xVBAControl = ScVbaControlFactory::createUserformControl( m_xContext, xControl, m_xDlg, m_xModel, mfOffsetX, mfOffsetY ); + return uno::makeAny( xVBAControl ); + } + throw container::NoSuchElementException(); + } + +}; + +} + +static uno::Reference<container::XIndexAccess > +lcl_controlsWrapper( const uno::Reference< awt::XControl >& xDlg ) +{ + return new ControlArrayWrapper( xDlg ); +} + +ScVbaControls::ScVbaControls( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const css::uno::Reference< awt::XControl >& xDialog, + const uno::Reference< frame::XModel >& xModel, + double fOffsetX, double fOffsetY ) : + ControlsImpl_BASE( xParent, xContext, lcl_controlsWrapper( xDialog ) ), + mxDialog( xDialog ), + mxModel( xModel ), + mfOffsetX( fOffsetX ), + mfOffsetY( fOffsetY ) +{ +} + +uno::Reference< container::XEnumeration > +ScVbaControls::createEnumeration() +{ + uno::Reference< container::XEnumeration > xEnum( new ControlsEnumWrapper( mxContext, m_xIndexAccess, mxDialog, mxModel, mfOffsetX, mfOffsetY ) ); + if ( !xEnum.is() ) + throw uno::RuntimeException(); + return xEnum; +} + +uno::Any +ScVbaControls::createCollectionObject( const css::uno::Any& aSource ) +{ + // Create control from awt::XControl + uno::Reference< awt::XControl > xControl( aSource, uno::UNO_QUERY_THROW ); + uno::Reference< msforms::XControl > xVBAControl = ScVbaControlFactory::createUserformControl( mxContext, xControl, mxDialog, mxModel, mfOffsetX, mfOffsetY ); + return uno::Any( xVBAControl ); +} + +void SAL_CALL +ScVbaControls::Move( double cx, double cy ) +{ + uno::Reference< container::XEnumeration > xEnum( createEnumeration() ); + while ( xEnum->hasMoreElements() ) + { + uno::Reference< msforms::XControl > xControl( xEnum->nextElement(), uno::UNO_QUERY_THROW ); + xControl->setLeft( xControl->getLeft() + cx ); + xControl->setTop( xControl->getTop() + cy ); + } +} + +uno::Any SAL_CALL ScVbaControls::Add( const uno::Any& Object, const uno::Any& StringKey, const uno::Any& /*Before*/, const uno::Any& /*After*/ ) +{ + uno::Any aResult; + OUString aComServiceName; + + try + { + if ( !mxDialog.is() ) + throw uno::RuntimeException(); + + uno::Reference< awt::XControl > xNewControl; + uno::Reference< lang::XMultiServiceFactory > xModelFactory( mxDialog->getModel(), uno::UNO_QUERY_THROW ); + + uno::Reference< container::XNameContainer > xDialogContainer( xModelFactory, uno::UNO_QUERY_THROW ); + + Object >>= aComServiceName; + + // TODO: Support Before and After? + OUString aNewName; + StringKey >>= aNewName; + if ( aNewName.isEmpty() ) + { + aNewName = aComServiceName; + if ( aNewName.isEmpty() ) + aNewName = "Control"; + + sal_Int32 nInd = 0; + while( xDialogContainer->hasByName( aNewName ) && (nInd < SAL_MAX_INT32) ) + { + aNewName = aComServiceName + OUString::number( nInd++ ); + } + } + + double fDefWidth = 72.0, fDefHeight = 18.0; + if ( !aComServiceName.isEmpty() ) + { + // create a UNO control model based on the passed control type + uno::Reference< awt::XControlModel > xNewModel; + bool bFontSupport = false; + bool bNativeAX = false; + if( aComServiceName.equalsIgnoreAsciiCase( "Forms.CommandButton.1" ) ) + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.awt.UnoControlButtonModel" ), uno::UNO_QUERY_THROW ); + fDefWidth = 72.0; fDefHeight = 24.0; + bFontSupport = true; + } + else if( aComServiceName.equalsIgnoreAsciiCase( "Forms.Label.1" ) ) + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.awt.UnoControlFixedTextModel" ), uno::UNO_QUERY_THROW ); + fDefWidth = 72.0; fDefHeight = 18.0; + bFontSupport = true; + } + else if( aComServiceName.equalsIgnoreAsciiCase( "Forms.Image.1" ) ) + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.awt.UnoControlImageControlModel" ), uno::UNO_QUERY_THROW ); + fDefWidth = 72.0; fDefHeight = 72.0; + } + else if( aComServiceName.equalsIgnoreAsciiCase( "Forms.CheckBox.1" ) ) + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.awt.UnoControlCheckBoxModel" ), uno::UNO_QUERY_THROW ); + fDefWidth = 108.0; fDefHeight = 18.0; + bFontSupport = true; + } + else if( aComServiceName.equalsIgnoreAsciiCase( "Forms.OptionButton.1" ) ) + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.awt.UnoControlRadioButtonModel" ), uno::UNO_QUERY_THROW ); + fDefWidth = 108.0; fDefHeight = 18.0; + bFontSupport = true; + } + else if( aComServiceName.equalsIgnoreAsciiCase( "Forms.TextBox.1" ) ) + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.awt.UnoControlEditModel" ), uno::UNO_QUERY_THROW ); + fDefWidth = 72.0; fDefHeight = 18.0; + bFontSupport = true; + } + else if( aComServiceName.equalsIgnoreAsciiCase( "Forms.ListBox.1" ) ) + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.awt.UnoControlListBoxModel" ), uno::UNO_QUERY_THROW ); + fDefWidth = 72.0; fDefHeight = 18.0; + bFontSupport = true; + } + else if( aComServiceName.equalsIgnoreAsciiCase( "Forms.ComboBox.1" ) ) + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.awt.UnoControlComboBoxModel" ), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xProps( xNewModel, uno::UNO_QUERY_THROW ); + xProps->setPropertyValue( "Dropdown" , uno::Any( true ) ); + fDefWidth = 72.0; fDefHeight = 18.0; + bFontSupport = true; + } + else if( aComServiceName.equalsIgnoreAsciiCase( "Forms.ToggleButton.1" ) ) + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.awt.UnoControlButtonModel" ), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xProps( xNewModel, uno::UNO_QUERY_THROW ); + xProps->setPropertyValue( "Toggle" , uno::Any( true ) ); + fDefWidth = 72.0; fDefHeight = 18.0; + bFontSupport = true; + } + else if( aComServiceName.equalsIgnoreAsciiCase( "Forms.Frame.1" ) ) + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.awt.UnoControlGroupBoxModel" ), uno::UNO_QUERY_THROW ); + fDefWidth = 216.0; fDefHeight = 144.0; + bFontSupport = true; + } + else if( aComServiceName.equalsIgnoreAsciiCase( "Forms.SpinButton.1" ) ) + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.awt.UnoControlSpinButtonModel" ), uno::UNO_QUERY_THROW ); + fDefWidth = 12.75; fDefHeight = 25.5; + } + else if( aComServiceName.equalsIgnoreAsciiCase( "Forms.ScrollBar.1" ) ) + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.awt.UnoControlScrollBarModel" ), uno::UNO_QUERY_THROW ); + fDefWidth = 12.75; fDefHeight = 63.8; + } + else + { + xNewModel.set( xModelFactory->createInstance( "com.sun.star.custom.awt.UnoControlSystemAXContainerModel" ), uno::UNO_QUERY_THROW ); + fDefWidth = 72.0; fDefHeight = 18.0; + bNativeAX = true; + } + + // need to set a few font properties to get rid of the default DONT_KNOW values + if( bFontSupport ) + { + uno::Reference< beans::XPropertySet > xModelProps( xNewModel, uno::UNO_QUERY_THROW ); + xModelProps->setPropertyValue( "FontName" , uno::Any( OUString("Tahoma" ) ) ); + xModelProps->setPropertyValue( "FontHeight" , uno::Any( float( 8.0 ) ) ); + xModelProps->setPropertyValue( "FontWeight" , uno::Any( awt::FontWeight::NORMAL ) ); + xModelProps->setPropertyValue( "FontSlant" , uno::Any( awt::FontSlant_NONE ) ); + xModelProps->setPropertyValue( "FontUnderline" , uno::Any( awt::FontUnderline::NONE ) ); + xModelProps->setPropertyValue( "FontStrikeout" , uno::Any( awt::FontStrikeout::NONE ) ); + } + + xDialogContainer->insertByName( aNewName, uno::makeAny( xNewModel ) ); + uno::Reference< awt::XControlContainer > xControlContainer( mxDialog, uno::UNO_QUERY_THROW ); + xNewControl = xControlContainer->getControl( aNewName ); + + if( bNativeAX ) try + { + uno::Reference< script::XInvocation > xControlInvoke( xNewControl, uno::UNO_QUERY_THROW ); + + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[0] <<= aComServiceName; + uno::Sequence< sal_Int16 > aOutIDDummy; + uno::Sequence< uno::Any > aOutDummy; + xControlInvoke->invoke( "SOAddAXControl" , aArgs, aOutIDDummy, aOutDummy ); + } + catch (const uno::Exception&) + { + xDialogContainer->removeByName( aNewName ); + throw; + } + } + + if ( !xNewControl.is() ) + throw uno::RuntimeException(); + + UpdateCollectionIndex( lcl_controlsWrapper( mxDialog ) ); + aResult <<= xNewControl; + aResult = createCollectionObject( aResult ); + uno::Reference< msforms::XControl > xVBAControl( aResult, uno::UNO_QUERY_THROW ); + if( fDefWidth > 0.0 ) + xVBAControl->setWidth( fDefWidth ); + if( fDefHeight > 0.0 ) + xVBAControl->setHeight( fDefHeight ); + } + catch (const uno::RuntimeException&) + { + throw; + } + catch (const uno::Exception&) + { + css::uno::Any anyEx = cppu::getCaughtException(); + throw lang::WrappedTargetRuntimeException( "Can not create AXControl!", + uno::Reference< uno::XInterface >(), + anyEx ); + } + + return aResult; +} + +void SAL_CALL ScVbaControls::Remove( const uno::Any& StringKeyOrIndex ) +{ + OUString aControlName; + sal_Int32 nIndex = -1; + + try + { + if ( !mxDialog.is() ) + throw uno::RuntimeException(); + + uno::Reference< lang::XMultiServiceFactory > xModelFactory( mxDialog->getModel(), uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameContainer > xDialogContainer( xModelFactory, uno::UNO_QUERY_THROW ); + + if ( !( ( StringKeyOrIndex >>= aControlName ) && !aControlName.isEmpty() ) + && !( ( StringKeyOrIndex >>= nIndex ) && nIndex >= 0 && nIndex < m_xIndexAccess->getCount() ) ) + throw uno::RuntimeException(); + + uno::Reference< awt::XControl > xControl; + if ( !aControlName.isEmpty() ) + { + uno::Reference< awt::XControlContainer > xControlContainer( mxDialog, uno::UNO_QUERY_THROW ); + xControl = xControlContainer->getControl( aControlName ); + } + else + { + m_xIndexAccess->getByIndex( nIndex ) >>= xControl; + } + + if ( !xControl.is() ) + throw uno::RuntimeException(); + + if ( aControlName.isEmpty() ) + aControlName = ControlArrayWrapper::getControlName( xControl ); + + xDialogContainer->removeByName( aControlName ); + xControl->dispose(); + } + catch (const uno::RuntimeException&) + { + // the exceptions are not rethrown, impossibility to find or remove the control is currently not reported + // since in most cases it means just that the controls is already not there, the VBA seems to do it in the same way + + // throw; + } + catch (const uno::Exception&) + { + // throw lang::WrappedTargetException("Can not create AXControl!", + // uno::Reference< uno::XInterface >(), + // uno::makeAny( e ) ); + } +} + + +uno::Type +ScVbaControls::getElementType() +{ + return cppu::UnoType<ooo::vba::msforms::XControl>::get(); +} + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaControls, "ooo.vba.msforms.Controls" ) +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbacontrols.hxx b/vbahelper/source/msforms/vbacontrols.hxx new file mode 100644 index 000000000..1e9d95042 --- /dev/null +++ b/vbahelper/source/msforms/vbacontrols.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_VBAHELPER_SOURCE_MSFORMS_VBACONTROLS_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBACONTROLS_HXX + +#include <ooo/vba/msforms/XControls.hpp> +#include <com/sun/star/awt/XControl.hpp> + +#include <vbahelper/vbacollectionimpl.hxx> +#include <vbahelper/vbahelper.hxx> + +typedef CollTestImplHelper< ov::msforms::XControls > ControlsImpl_BASE; + +class ScVbaControls : public ControlsImpl_BASE +{ +public: + ScVbaControls( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::awt::XControl >& xDialog, + const css::uno::Reference< css::frame::XModel >& xModel, + double fOffsetX, double fOffsetY ); + // XControls + virtual void SAL_CALL Move( double cx, double cy ) override; + virtual css::uno::Any SAL_CALL Add( const css::uno::Any& Object, const css::uno::Any& StringKey, const css::uno::Any& Before, const css::uno::Any& After ) override; + virtual void SAL_CALL Remove( const css::uno::Any& StringKeyOrIndex ) 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 + VBAHELPER_DECL_XHELPERINTERFACE + +private: + css::uno::Reference< css::awt::XControl > mxDialog; + css::uno::Reference< css::frame::XModel > mxModel; + double mfOffsetX; + double mfOffsetY; +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBACONTROLS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbaframe.cxx b/vbahelper/source/msforms/vbaframe.cxx new file mode 100644 index 000000000..3af0ffee9 --- /dev/null +++ b/vbahelper/source/msforms/vbaframe.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 "vbaframe.hxx" +#include "vbanewfont.hxx" +#include "vbacontrols.hxx" +#include <ooo/vba/msforms/fmBorderStyle.hpp> +#include <ooo/vba/msforms/fmSpecialEffect.hpp> + +using namespace com::sun::star; +using namespace ooo::vba; + +ScVbaFrame::ScVbaFrame( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< uno::XInterface >& xControl, + const uno::Reference< frame::XModel >& xModel, + std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper, + const css::uno::Reference< css::awt::XControl >& xDialog ) : + FrameImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ), + mxDialog( xDialog ) +{ +} + +// XFrame attributes + +OUString SAL_CALL ScVbaFrame::getCaption() +{ + OUString Label; + m_xProps->getPropertyValue( "Label" ) >>= Label; + return Label; +} + +void SAL_CALL ScVbaFrame::setCaption( const OUString& _caption ) +{ + m_xProps->setPropertyValue( "Label", uno::makeAny( _caption ) ); +} + +sal_Int32 SAL_CALL ScVbaFrame::getSpecialEffect() +{ + return msforms::fmSpecialEffect::fmSpecialEffectEtched; +} + + +void SAL_CALL ScVbaFrame::setSpecialEffect( sal_Int32 /*nSpecialEffect*/ ) +{ + // #STUB +} + +sal_Int32 SAL_CALL ScVbaFrame::getBorderStyle() +{ + return msforms::fmBorderStyle::fmBorderStyleNone; +} + +void SAL_CALL ScVbaFrame::setBorderStyle( sal_Int32 /*nBorderStyle*/ ) +{ + // #STUB +} + +uno::Reference< msforms::XNewFont > SAL_CALL ScVbaFrame::getFont() +{ + return new VbaNewFont( m_xProps ); +} + +// XFrame methods + +uno::Any SAL_CALL ScVbaFrame::Controls( const uno::Any& rIndex ) +{ + // horizontal anchor of frame children is inside border line (add one unit to compensate border line width) + double fOffsetX = mpGeometryHelper->getOffsetX() + getLeft() + 1.0; + // vertical anchor of frame children is inside border line (add half of text height and one unit to compensate border line width) + double fOffsetY = mpGeometryHelper->getOffsetY() + getTop() + (getFont()->getSize() / 2.0) + 1.0; + + uno::Reference< XCollection > xControls( new ScVbaControls( this, mxContext, mxDialog, m_xModel, fOffsetX, fOffsetY ) ); + if( rIndex.hasValue() ) + return xControls->Item( rIndex, uno::Any() ); + return uno::Any( xControls ); +} + +// XHelperInterface + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaFrame, "ooo.vba.msforms.Frame" ) +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbaframe.hxx b/vbahelper/source/msforms/vbaframe.hxx new file mode 100644 index 000000000..354858a27 --- /dev/null +++ b/vbahelper/source/msforms/vbaframe.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_VBAHELPER_SOURCE_MSFORMS_VBAFRAME_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBAFRAME_HXX + +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/msforms/XFrame.hpp> + +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XFrame > FrameImpl_BASE; + +class ScVbaFrame : public FrameImpl_BASE +{ +public: + ScVbaFrame( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::uno::XInterface >& xControl, + const css::uno::Reference< css::frame::XModel >& xModel, + std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper, + const css::uno::Reference< css::awt::XControl >& xDialog ); + + // XFrame attributes + virtual OUString SAL_CALL getCaption() override; + virtual void SAL_CALL setCaption( const OUString& _caption ) override; + + virtual sal_Int32 SAL_CALL getSpecialEffect() override; + virtual void SAL_CALL setSpecialEffect( sal_Int32 nSpecialEffect ) override; + virtual sal_Int32 SAL_CALL getBorderStyle() override; + virtual void SAL_CALL setBorderStyle( sal_Int32 nBorderStyle ) override; + virtual css::uno::Reference< ov::msforms::XNewFont > SAL_CALL getFont() override; + // XFrame methods + css::uno::Any SAL_CALL Controls( const css::uno::Any& rIndex ) override; + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + +private: + css::uno::Reference< css::awt::XControl > mxDialog; +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBAFRAME_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbaimage.cxx b/vbahelper/source/msforms/vbaimage.cxx new file mode 100644 index 000000000..827544168 --- /dev/null +++ b/vbahelper/source/msforms/vbaimage.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/. + * + * 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 "vbaimage.hxx" + +using namespace com::sun::star; +using namespace ooo::vba; + + +ScVbaImage::ScVbaImage( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ) + : ImageImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ) +{ +} + +OUString +ScVbaImage::getServiceImplName() +{ + return "ScVbaImage"; +} + +uno::Sequence< OUString > +ScVbaImage::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.Image" + }; + return aServiceNames; +} + +sal_Int32 SAL_CALL ScVbaImage::getBackColor() +{ + return ScVbaControl::getBackColor(); +} + +void SAL_CALL ScVbaImage::setBackColor( sal_Int32 nBackColor ) +{ + ScVbaControl::setBackColor( nBackColor ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbaimage.hxx b/vbahelper/source/msforms/vbaimage.hxx new file mode 100644 index 000000000..2f7081f52 --- /dev/null +++ b/vbahelper/source/msforms/vbaimage.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_VBAHELPER_SOURCE_MSFORMS_VBAIMAGE_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBAIMAGE_HXX +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/msforms/XImage.hpp> + +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XImage > ImageImpl_BASE; + +class ScVbaImage : public ImageImpl_BASE +{ +public: + ScVbaImage( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ); + virtual sal_Int32 SAL_CALL getBackColor() override; + virtual void SAL_CALL setBackColor( sal_Int32 nBackColor ) override; + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBAIMAGE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbalabel.cxx b/vbahelper/source/msforms/vbalabel.cxx new file mode 100644 index 000000000..df4ac8be0 --- /dev/null +++ b/vbahelper/source/msforms/vbalabel.cxx @@ -0,0 +1,112 @@ +/* -*- 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 "vbalabel.hxx" +#include "vbanewfont.hxx" + +using namespace com::sun::star; +using namespace ooo::vba; + +ScVbaLabel::ScVbaLabel( const css::uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ) + : LabelImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ) +{ +} + +// Attributes +OUString SAL_CALL +ScVbaLabel::getCaption() +{ + OUString Label; + m_xProps->getPropertyValue( "Label" ) >>= Label; + return Label; +} + +void SAL_CALL +ScVbaLabel::setCaption( const OUString& _caption ) +{ + m_xProps->setPropertyValue( "Label", uno::makeAny( _caption ) ); +} +uno::Any SAL_CALL +ScVbaLabel::getValue() +{ + return uno::makeAny( getCaption() ); +} + +void SAL_CALL +ScVbaLabel::setValue( const uno::Any& _value ) +{ + OUString sCaption; + _value >>= sCaption; + setCaption( sCaption ); +} + +OUString SAL_CALL +ScVbaLabel::getAccelerator() +{ + // #STUB + return OUString(); +} + +void SAL_CALL +ScVbaLabel::setAccelerator( const OUString& /*_accelerator*/ ) +{ + // #STUB +} + +uno::Reference< msforms::XNewFont > SAL_CALL ScVbaLabel::getFont() +{ + return new VbaNewFont( m_xProps ); +} + +OUString ScVbaLabel::getServiceImplName() +{ + return "ScVbaLabel"; +} + +sal_Int32 SAL_CALL ScVbaLabel::getBackColor() +{ + return ScVbaControl::getBackColor(); +} + +void SAL_CALL ScVbaLabel::setBackColor( sal_Int32 nBackColor ) +{ + ScVbaControl::setBackColor( nBackColor ); +} + +sal_Bool SAL_CALL ScVbaLabel::getAutoSize() +{ + return ScVbaControl::getAutoSize(); +} + +void SAL_CALL ScVbaLabel::setAutoSize( sal_Bool bAutoSize ) +{ + ScVbaControl::setAutoSize( bAutoSize ); +} + +uno::Sequence< OUString > +ScVbaLabel::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.Label" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbalabel.hxx b/vbahelper/source/msforms/vbalabel.hxx new file mode 100644 index 000000000..f7fc98416 --- /dev/null +++ b/vbahelper/source/msforms/vbalabel.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_VBAHELPER_SOURCE_MSFORMS_VBALABEL_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBALABEL_HXX +#include <ooo/vba/msforms/XLabel.hpp> +#include <com/sun/star/script/XDefaultProperty.hpp> + +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> +#include <cppuhelper/implbase.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XLabel, css::script::XDefaultProperty > LabelImpl_BASE; + +class ScVbaLabel : public LabelImpl_BASE +{ +public: + ScVbaLabel( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ); + // Attributes + virtual css::uno::Any SAL_CALL getValue() override; + virtual void SAL_CALL setValue( const css::uno::Any& _value ) override; + virtual OUString SAL_CALL getCaption() override; + virtual void SAL_CALL setCaption( const OUString& _caption ) override; + virtual OUString SAL_CALL getAccelerator() override; + virtual void SAL_CALL setAccelerator( const OUString& _accelerator ) override; + virtual css::uno::Reference< ov::msforms::XNewFont > SAL_CALL getFont() override; + virtual sal_Int32 SAL_CALL getBackColor() override; + virtual void SAL_CALL setBackColor( sal_Int32 nBackColor ) override; + virtual sal_Bool SAL_CALL getAutoSize() override; + virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) override; + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + // XDefaultProperty + OUString SAL_CALL getDefaultPropertyName( ) override { return "Value"; } +}; +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBALABEL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbalistbox.cxx b/vbahelper/source/msforms/vbalistbox.cxx new file mode 100644 index 000000000..f4af24a5b --- /dev/null +++ b/vbahelper/source/msforms/vbalistbox.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 "vbalistbox.hxx" +#include "vbanewfont.hxx" +#include <comphelper/sequence.hxx> +#include <ooo/vba/msforms/fmMultiSelect.hpp> + +using namespace com::sun::star; +using namespace ooo::vba; + +ScVbaListBox::ScVbaListBox( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< css::uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ) + : ListBoxImpl_BASE(xParent, xContext, xControl, xModel, std::move(pGeomHelper)) + , m_nIndex(0) +{ + mpListHelper.reset( new ListControlHelper( m_xProps ) ); +} + +// Attributes +void SAL_CALL +ScVbaListBox::setListIndex( const uno::Any& _value ) +{ + sal_Int32 nIndex = 0; + _value >>= nIndex; + uno::Reference< XPropValue > xPropVal( Selected( nIndex ), uno::UNO_QUERY_THROW ); + xPropVal->setValue( uno::makeAny( true ) ); +} + +uno::Any SAL_CALL +ScVbaListBox::getListIndex() +{ + uno::Sequence< sal_Int16 > sSelection; + m_xProps->getPropertyValue( "SelectedItems" ) >>= sSelection; + if ( !sSelection.hasElements() ) + return uno::Any( sal_Int32( -1 ) ); + return uno::Any( sSelection[ 0 ] ); +} + +uno::Any SAL_CALL +ScVbaListBox::getValue() +{ + uno::Sequence< sal_Int16 > sSelection; + uno::Sequence< OUString > sItems; + m_xProps->getPropertyValue( "SelectedItems" ) >>= sSelection; + m_xProps->getPropertyValue( "StringItemList" ) >>= sItems; + if( getMultiSelect() ) + throw uno::RuntimeException( "Attribute use invalid." ); + uno::Any aRet; + if ( sSelection.hasElements() ) + aRet <<= sItems[ sSelection[ 0 ] ]; + return aRet; +} + +void SAL_CALL +ScVbaListBox::setValue( const uno::Any& _value ) +{ + if( getMultiSelect() ) + { + throw uno::RuntimeException( "Attribute use invalid." ); + } + OUString sValue = getAnyAsString( _value ); + uno::Sequence< OUString > sList; + m_xProps->getPropertyValue( "StringItemList" ) >>= sList; + sal_Int16 nValue = static_cast<sal_Int16>(comphelper::findValue(sList, sValue)); + if( nValue == -1 ) + throw uno::RuntimeException( "Attribute use invalid." ); + + uno::Sequence< sal_Int16 > nSelectedIndices(1); + uno::Sequence< sal_Int16 > nOldSelectedIndices; + m_xProps->getPropertyValue( "SelectedItems" ) >>= nOldSelectedIndices; + nSelectedIndices[ 0 ] = nValue; + m_xProps->setPropertyValue( "SelectedItems", uno::makeAny( nSelectedIndices ) ); + if ( nSelectedIndices != nOldSelectedIndices ) + fireClickEvent(); +} + +OUString SAL_CALL +ScVbaListBox::getText() +{ + OUString result; + getValue() >>= result; + return result; +} + +void SAL_CALL +ScVbaListBox::setText( const OUString& _text ) +{ + setValue( uno::makeAny( _text ) ); // seems the same +} + +sal_Int32 SAL_CALL +ScVbaListBox::getMultiSelect() +{ + bool bMultiSelect = false; + m_xProps->getPropertyValue( "MultiSelection" ) >>= bMultiSelect; + + return bMultiSelect ? msforms::fmMultiSelect::fmMultiSelectMulti : msforms::fmMultiSelect::fmMultiSelectSingle; +} + +void SAL_CALL +ScVbaListBox::setMultiSelect( sal_Int32 _multiselect ) +{ + bool bBoolVal = false; + switch ( _multiselect ) + { + case msforms::fmMultiSelect::fmMultiSelectMulti: + case msforms::fmMultiSelect::fmMultiSelectExtended: + bBoolVal = true; + break; + case msforms::fmMultiSelect::fmMultiSelectSingle: + bBoolVal = false; + break; + default: + throw lang::IllegalArgumentException(); + break; + } + m_xProps->setPropertyValue( "MultiSelection" , uno::makeAny( bBoolVal ) ); +} + + +css::uno::Any SAL_CALL +ScVbaListBox::Selected( sal_Int32 index ) +{ + uno::Sequence< OUString > sList; + m_xProps->getPropertyValue( "StringItemList" ) >>= sList; + sal_Int16 nLength = static_cast< sal_Int16 >( sList.getLength() ); + // no choice but to do a horror cast as internally + // the indices are but sal_Int16 + sal_Int16 nIndex = static_cast< sal_Int16 >( index ); + if( nIndex < 0 || nIndex >= nLength ) + throw uno::RuntimeException( "Error Number." ); + m_nIndex = nIndex; + return uno::makeAny( uno::Reference< XPropValue > ( new ScVbaPropValue( this ) ) ); +} + +// Methods +void SAL_CALL +ScVbaListBox::AddItem( const uno::Any& pvargItem, const uno::Any& pvargIndex ) +{ + mpListHelper->AddItem( pvargItem, pvargIndex ); +} + +void SAL_CALL +ScVbaListBox::removeItem( const uno::Any& index ) +{ + mpListHelper->removeItem( index ); +} + +void SAL_CALL +ScVbaListBox::Clear( ) +{ + mpListHelper->Clear(); +} + +// this is called when something like the following vba code is used +// to set the selected state of particular entries in the Listbox +// ListBox1.Selected( 3 ) = false +//PropListener +void +ScVbaListBox::setValueEvent( const uno::Any& value ) +{ + bool bValue = false; + if( !(value >>= bValue) ) + throw uno::RuntimeException( "Invalid type. need boolean." ); + uno::Sequence< sal_Int16 > nList; + m_xProps->getPropertyValue( "SelectedItems" ) >>= nList; + sal_Int16 nLength = static_cast<sal_Int16>( nList.getLength() ); + sal_Int16 nIndex = m_nIndex; + for( sal_Int16 i = 0; i < nLength; i++ ) + { + if( nList[i] == nIndex ) + { + if( !bValue ) + { + for( ; i < nLength - 1; i++ ) + { + nList[i] = nList[i + 1]; + } + nList.realloc( nLength - 1 ); + //m_xProps->setPropertyValue( sSourceName, uno::makeAny( nList ) ); + fireClickEvent(); + m_xProps->setPropertyValue( "SelectedItems", uno::makeAny( nList ) ); + } + return; + } + } + if( bValue ) + { + if( getMultiSelect() ) + { + nList.realloc( nLength + 1 ); + nList[nLength] = nIndex; + } + else + { + nList.realloc( 1 ); + nList[0] = nIndex; + } + //m_xProps->setPropertyValue( sSourceName, uno::makeAny( nList ) ); + fireClickEvent(); + m_xProps->setPropertyValue( "SelectedItems", uno::makeAny( nList ) ); + } +} + +// this is called when something like the following vba code is used +// to determine the selected state of particular entries in the Listbox +// msgbox ListBox1.Selected( 3 ) + +css::uno::Any +ScVbaListBox::getValueEvent() +{ + uno::Sequence< sal_Int16 > nList; + m_xProps->getPropertyValue( "SelectedItems" ) >>= nList; + sal_Int32 nIndex = m_nIndex; + bool bRet = std::find(nList.begin(), nList.end(), nIndex) != nList.end(); + + return uno::makeAny( bRet ); +} + +void SAL_CALL +ScVbaListBox::setRowSource( const OUString& _rowsource ) +{ + ScVbaControl::setRowSource( _rowsource ); + mpListHelper->setRowSource( _rowsource ); +} + +sal_Int32 SAL_CALL +ScVbaListBox::getListCount() +{ + return mpListHelper->getListCount(); +} + +uno::Any SAL_CALL +ScVbaListBox::List( const ::uno::Any& pvargIndex, const uno::Any& pvarColumn ) +{ + return mpListHelper->List( pvargIndex, pvarColumn ); +} + +uno::Reference< msforms::XNewFont > SAL_CALL ScVbaListBox::getFont() +{ + return new VbaNewFont( m_xProps ); +} + +OUString +ScVbaListBox::getServiceImplName() +{ + return "ScVbaListBox"; +} + +uno::Sequence< OUString > +ScVbaListBox::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.ScVbaListBox" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbalistbox.hxx b/vbahelper/source/msforms/vbalistbox.hxx new file mode 100644 index 000000000..b87f9e74f --- /dev/null +++ b/vbahelper/source/msforms/vbalistbox.hxx @@ -0,0 +1,81 @@ +/* -*- 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_VBAHELPER_SOURCE_MSFORMS_VBALISTBOX_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBALISTBOX_HXX +#include <memory> +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/script/XDefaultProperty.hpp> +#include <ooo/vba/msforms/XListBox.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +#include "vbacontrol.hxx" +#include <vbahelper/vbapropvalue.hxx> +#include "vbalistcontrolhelper.hxx" +#include <vbahelper/vbahelper.hxx> + +typedef cppu::ImplInheritanceHelper<ScVbaControl, ov::msforms::XListBox, css::script::XDefaultProperty > ListBoxImpl_BASE; +class ScVbaListBox : public ListBoxImpl_BASE + ,public PropListener +{ + std::unique_ptr< ListControlHelper > mpListHelper; + + sal_Int16 m_nIndex; + +public: + ScVbaListBox( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ); + + // Attributes + virtual css::uno::Any SAL_CALL getListIndex() override; + virtual void SAL_CALL setListIndex( const css::uno::Any& _value ) override; + virtual ::sal_Int32 SAL_CALL getListCount() override; + virtual css::uno::Any SAL_CALL getValue() override; + virtual void SAL_CALL setValue( const css::uno::Any& _value ) override; + virtual OUString SAL_CALL getText() override; + virtual void SAL_CALL setText( const OUString& _text ) override; + virtual sal_Int32 SAL_CALL getMultiSelect() override; + virtual void SAL_CALL setMultiSelect( sal_Int32 _multiselect ) override; + virtual css::uno::Reference< ov::msforms::XNewFont > SAL_CALL getFont() override; + + // Methods + virtual css::uno::Any SAL_CALL Selected( ::sal_Int32 index ) override; + virtual void SAL_CALL AddItem( const css::uno::Any& pvargItem, const css::uno::Any& pvargIndex ) override; + virtual void SAL_CALL removeItem( const css::uno::Any& index ) override; + virtual void SAL_CALL Clear( ) override; + virtual css::uno::Any SAL_CALL List( const css::uno::Any& pvargIndex, const css::uno::Any& pvarColumn ) override; + // XControl + virtual void SAL_CALL setRowSource( const OUString& _rowsource ) override; + + // XDefaultProperty + OUString SAL_CALL getDefaultPropertyName( ) override { return "Value"; } + + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + + //PropListener + virtual void setValueEvent( const css::uno::Any& value ) override; + virtual css::uno::Any getValueEvent() override; + + +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbalistcontrolhelper.cxx b/vbahelper/source/msforms/vbalistcontrolhelper.cxx new file mode 100644 index 000000000..02a500aa2 --- /dev/null +++ b/vbahelper/source/msforms/vbalistcontrolhelper.cxx @@ -0,0 +1,189 @@ +/* -*- 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 "vbalistcontrolhelper.hxx" +#include <vector> +#include <vbahelper/vbapropvalue.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <comphelper/sequence.hxx> + +using namespace com::sun::star; +using namespace ooo::vba; + +namespace { + +class ListPropListener : public PropListener +{ +private: + uno::Reference< beans::XPropertySet > m_xProps; + uno::Any m_pvargIndex; + uno::Any m_pvarColumn; + +public: + ListPropListener( const uno::Reference< beans::XPropertySet >& xProps, const uno::Any& pvargIndex, const uno::Any& pvarColumn ); + virtual ~ListPropListener() { }; + virtual void setValueEvent( const css::uno::Any& value ) override; + virtual css::uno::Any getValueEvent() override; +}; + +} + +ListPropListener::ListPropListener( const uno::Reference< beans::XPropertySet >& xProps, const uno::Any& pvargIndex, const uno::Any& pvarColumn ) : m_xProps( xProps ), m_pvargIndex( pvargIndex ), m_pvarColumn( pvarColumn ) +{ +} + +void ListPropListener::setValueEvent( const uno::Any& value ) +{ + if( m_pvargIndex.hasValue() || m_pvarColumn.hasValue() ) + throw uno::RuntimeException( "Bad argument" ); + + m_xProps->setPropertyValue( "StringItemList", value ); +} + +uno::Any ListPropListener::getValueEvent() +{ + uno::Sequence< OUString > sList; + m_xProps->getPropertyValue( "StringItemList" ) >>= sList; + sal_Int16 nLength = static_cast< sal_Int16 >( sList.getLength() ); + uno::Any aRet; + if ( m_pvargIndex.hasValue() ) + { + sal_Int16 nIndex = -1; + m_pvargIndex >>= nIndex; + if( nIndex < 0 || nIndex >= nLength ) + throw uno::RuntimeException( "Bad row Index" ); + aRet <<= sList[ nIndex ]; + } + else if ( m_pvarColumn.hasValue() ) // pvarColumn on its own would be bad + throw uno::RuntimeException( "Bad column Index" ); + else // List() ( e.g. no args ) + { + uno::Sequence< uno::Sequence< OUString > > sReturnArray( nLength ); + for ( sal_Int32 i = 0; i < nLength; ++i ) + { + sReturnArray[ i ].realloc( 10 ); + sReturnArray[ i ][ 0 ] = sList[ i ]; + } + aRet <<= sReturnArray; + } + return aRet; +} + +void +ListControlHelper::AddItem( const uno::Any& pvargItem, const uno::Any& pvargIndex ) +{ + if ( pvargItem.hasValue() ) + { + uno::Sequence< OUString > sList; + m_xProps->getPropertyValue( "StringItemList" ) >>= sList; + + sal_Int32 nIndex = sList.getLength(); + + if ( pvargIndex.hasValue() ) + pvargIndex >>= nIndex; + + OUString sString = getAnyAsString( pvargItem ); + + // if no index specified or item is to be appended to end of + // list just realloc the array and set the last item + if ( nIndex == sList.getLength() ) + { + sal_Int32 nOldSize = sList.getLength(); + sList.realloc( nOldSize + 1 ); + sList[ nOldSize ] = sString; + } + else + { + // just copy those elements above the one to be inserted + std::vector< OUString > sVec; + // reserve just the amount we need to copy + sVec.reserve( sList.getLength() - nIndex + 1); + + // insert the new element + sVec.push_back( sString ); + + // point at first element to copy + std::copy(std::next(sList.begin(), nIndex), sList.end(), std::back_inserter(sVec)); + + sList.realloc( sList.getLength() + 1 ); + + // point at first element to be overwritten + std::copy(sVec.begin(), sVec.end(), std::next(sList.begin(), nIndex)); + } + + m_xProps->setPropertyValue( "StringItemList", uno::makeAny( sList ) ); + } +} + +void +ListControlHelper::removeItem( const uno::Any& index ) +{ + sal_Int32 nIndex = 0; + // for int index + if ( index >>= nIndex ) + { + uno::Sequence< OUString > sList; + m_xProps->getPropertyValue( "StringItemList" ) >>= sList; + if( nIndex < 0 || nIndex > ( sList.getLength() - 1 ) ) + throw uno::RuntimeException( "Invalid index" , uno::Reference< uno::XInterface > () ); + if( sList.hasElements() ) + { + if( sList.getLength() == 1 ) + { + Clear(); + return; + } + + comphelper::removeElementAt(sList, nIndex); + } + + m_xProps->setPropertyValue( "StringItemList", uno::makeAny( sList ) ); + } +} + +void +ListControlHelper::Clear( ) +{ + // urk, setValue doesn't seem to work !! + //setValue( uno::makeAny( sal_Int16() ) ); + m_xProps->setPropertyValue( "StringItemList", uno::makeAny( uno::Sequence< OUString >() ) ); +} + +void +ListControlHelper::setRowSource( const OUString& _rowsource ) +{ + if ( _rowsource.isEmpty() ) + Clear(); +} + +sal_Int32 +ListControlHelper::getListCount() +{ + uno::Sequence< OUString > sList; + m_xProps->getPropertyValue( "StringItemList" ) >>= sList; + return sList.getLength(); +} + +uno::Any +ListControlHelper::List( const ::uno::Any& pvargIndex, const uno::Any& pvarColumn ) +{ + return uno::makeAny( uno::Reference< XPropValue > ( new ScVbaPropValue( new ListPropListener( m_xProps, pvargIndex, pvarColumn ) ) ) ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbalistcontrolhelper.hxx b/vbahelper/source/msforms/vbalistcontrolhelper.hxx new file mode 100644 index 000000000..dff3e1c33 --- /dev/null +++ b/vbahelper/source/msforms/vbalistcontrolhelper.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_VBAHELPER_SOURCE_MSFORMS_VBALISTCONTROLHELPER_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBALISTCONTROLHELPER_HXX + +#include <vbahelper/vbahelper.hxx> + +class ListControlHelper final +{ + css::uno::Reference< css::beans::XPropertySet > m_xProps; + +public: + explicit ListControlHelper( const css::uno::Reference< css::beans::XPropertySet >& rxControl ) : m_xProps( rxControl ){} + /// @throws css::uno::RuntimeException + void AddItem( const css::uno::Any& pvargItem, const css::uno::Any& pvargIndex ); + /// @throws css::uno::RuntimeException + void removeItem( const css::uno::Any& index ); + /// @throws css::uno::RuntimeException + void setRowSource( const OUString& _rowsource ); + /// @throws css::uno::RuntimeException + ::sal_Int32 getListCount(); + /// @throws css::uno::RuntimeException + css::uno::Any List( const css::uno::Any& pvargIndex, const css::uno::Any& pvarColumn ); + /// @throws css::uno::RuntimeException + void Clear( ); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbamultipage.cxx b/vbahelper/source/msforms/vbamultipage.cxx new file mode 100644 index 000000000..a23949ad9 --- /dev/null +++ b/vbahelper/source/msforms/vbamultipage.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/. + * + * 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 "vbamultipage.hxx" +#include <ooo/vba/XCollection.hpp> +#include "vbapages.hxx" +#include <com/sun/star/container/XNameContainer.hpp> +#include <cppuhelper/implbase.hxx> + +using namespace com::sun::star; +using namespace ooo::vba; + +const OUString SVALUE( "MultiPageValue" ); + +namespace { + +class PagesImpl : public cppu::WeakImplHelper< container::XIndexAccess > +{ + sal_Int32 mnPages; +public: + explicit PagesImpl( sal_Int32 nPages ) : mnPages( nPages ) {} + virtual ::sal_Int32 SAL_CALL getCount() override { return mnPages; } + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override + { + if ( Index < 0 || Index > mnPages ) + throw lang::IndexOutOfBoundsException(); + return uno::makeAny( uno::Reference< uno::XInterface >() ); + } + // XElementAccess + virtual uno::Type SAL_CALL getElementType() override + { + // no Pages object yet #FIXME + //return cppu::UnoType<msforms::XPage>::get(); + return cppu::UnoType<uno::XInterface>::get(); + } + virtual sal_Bool SAL_CALL hasElements( ) override + { + return ( mnPages > 0 ); + } +}; + +} + +ScVbaMultiPage::ScVbaMultiPage( + const uno::Reference< ov::XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< uno::XInterface >& xControl, + const uno::Reference< frame::XModel >& xModel, + std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper) : + MultiPageImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ) +{ +} + +// Attributes +sal_Int32 SAL_CALL +ScVbaMultiPage::getValue() +{ + sal_Int32 nValue = 0; + m_xProps->getPropertyValue( SVALUE ) >>= nValue; + // VBA 0 based tab index + return nValue - 1; +} + +void SAL_CALL +ScVbaMultiPage::setValue( const sal_Int32 _value ) +{ + // Openoffice 1 based tab index + sal_Int32 nVal = _value + 1; + sal_Int32 nOldVal = getValue(); + m_xProps->setPropertyValue( SVALUE, uno::makeAny( nVal ) ); + if ( nVal != nOldVal ) + fireChangeEvent(); +} + +OUString +ScVbaMultiPage::getServiceImplName() +{ + return "ScVbaMultiPage"; +} + +uno::Any SAL_CALL +ScVbaMultiPage::Pages( const uno::Any& index ) +{ + // get the container model + uno::Reference< container::XNameContainer > xContainer( m_xProps, uno::UNO_QUERY_THROW ); + uno::Reference< XCollection > xColl( new ScVbaPages( this, mxContext, new PagesImpl( xContainer->getElementNames().getLength() ) ) ); + if ( !index.hasValue() ) + return uno::makeAny( xColl ); + return xColl->Item( index, uno::Any() ); +} + +uno::Sequence< OUString > +ScVbaMultiPage::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.MultiPage" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbamultipage.hxx b/vbahelper/source/msforms/vbamultipage.hxx new file mode 100644 index 000000000..45c861105 --- /dev/null +++ b/vbahelper/source/msforms/vbamultipage.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_VBAHELPER_SOURCE_MSFORMS_VBAMULTIPAGE_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBAMULTIPAGE_HXX + +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/msforms/XMultiPage.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> + +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XMultiPage > MultiPageImpl_BASE; + +class ScVbaMultiPage : public MultiPageImpl_BASE +{ +public: + ScVbaMultiPage( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::uno::XInterface >& xControl, + const css::uno::Reference< css::frame::XModel >& xModel, + std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper); + + // Attributes + virtual sal_Int32 SAL_CALL getValue() override; + virtual void SAL_CALL setValue( sal_Int32 _value ) override; + virtual css::uno::Any SAL_CALL Pages( const css::uno::Any& index ) override; + + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBAMULTIPAGE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbanewfont.cxx b/vbahelper/source/msforms/vbanewfont.cxx new file mode 100644 index 000000000..b966d8454 --- /dev/null +++ b/vbahelper/source/msforms/vbanewfont.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 <rtl/tencinfo.h> +#include "vbanewfont.hxx" +#include <com/sun/star/awt/FontWeight.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/awt/FontStrikeout.hpp> +#include <com/sun/star/awt/FontUnderline.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + + +VbaNewFont::VbaNewFont( + const uno::Reference< beans::XPropertySet >& rxModelProps ) : + mxProps( rxModelProps, uno::UNO_SET_THROW ) +{ +} + +// XNewFont attributes + +OUString SAL_CALL VbaNewFont::getName() +{ + uno::Any aAny = mxProps->getPropertyValue( "FontName" ); + return aAny.get< OUString >(); +} + +void SAL_CALL VbaNewFont::setName( const OUString& rName ) +{ + mxProps->setPropertyValue( "FontName" , uno::Any( rName ) ); +} + +double SAL_CALL VbaNewFont::getSize() +{ + uno::Any aAny = mxProps->getPropertyValue( "FontHeight" ); + return aAny.get< float >(); +} + +void SAL_CALL VbaNewFont::setSize( double fSize ) +{ + mxProps->setPropertyValue( "FontHeight" , uno::Any( static_cast< float >( fSize ) ) ); +} + +sal_Int16 SAL_CALL VbaNewFont::getCharset() +{ + uno::Any aAny = mxProps->getPropertyValue( "FontCharset" ); + return rtl_getBestWindowsCharsetFromTextEncoding( static_cast< rtl_TextEncoding >( aAny.get< sal_Int16 >() ) ); +} + +void SAL_CALL VbaNewFont::setCharset( sal_Int16 nCharset ) +{ + rtl_TextEncoding eFontEnc = RTL_TEXTENCODING_DONTKNOW; + if( (0 <= nCharset) && (nCharset <= SAL_MAX_UINT8) ) + eFontEnc = rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( nCharset ) ); + if( eFontEnc == RTL_TEXTENCODING_DONTKNOW ) + throw uno::RuntimeException("an unknown or missing encoding"); + mxProps->setPropertyValue( "FontCharset" , uno::Any( static_cast< sal_Int16 >( eFontEnc ) ) ); +} + +sal_Int16 SAL_CALL VbaNewFont::getWeight() +{ + return getBold() ? 700 : 400; +} + +void SAL_CALL VbaNewFont::setWeight( sal_Int16 nWeight ) +{ + setBold( nWeight >= 700 ); +} + +sal_Bool SAL_CALL VbaNewFont::getBold() +{ + uno::Any aAny = mxProps->getPropertyValue( "FontWeight" ); + return aAny.get< float >() > awt::FontWeight::NORMAL; +} + +void SAL_CALL VbaNewFont::setBold( sal_Bool bBold ) +{ + mxProps->setPropertyValue( "FontWeight" , uno::Any( bBold ? awt::FontWeight::BOLD : awt::FontWeight::NORMAL ) ); +} + +sal_Bool SAL_CALL VbaNewFont::getItalic() +{ + uno::Any aAny = mxProps->getPropertyValue( "FontSlant" ); + return aAny.get< awt::FontSlant >() != awt::FontSlant_NONE; +} + +void SAL_CALL VbaNewFont::setItalic( sal_Bool bItalic ) +{ + mxProps->setPropertyValue( "FontSlant" , uno::Any( bItalic ? awt::FontSlant_ITALIC : awt::FontSlant_NONE ) ); +} + +sal_Bool SAL_CALL VbaNewFont::getUnderline() +{ + uno::Any aAny = mxProps->getPropertyValue("FontUnderline" ); + return aAny.get< sal_Int16 >() != awt::FontUnderline::NONE; +} + +void SAL_CALL VbaNewFont::setUnderline( sal_Bool bUnderline ) +{ + mxProps->setPropertyValue("FontUnderline" , uno::Any( bUnderline ? awt::FontUnderline::SINGLE : awt::FontUnderline::NONE ) ); +} + +sal_Bool SAL_CALL VbaNewFont::getStrikethrough() +{ + uno::Any aAny = mxProps->getPropertyValue( "FontStrikeout" ); + return aAny.get< sal_Int16 >() != awt::FontStrikeout::NONE; +} + +void SAL_CALL VbaNewFont::setStrikethrough( sal_Bool bStrikethrough ) +{ + mxProps->setPropertyValue( "FontStrikeout" ,uno::Any( bStrikethrough ? awt::FontStrikeout::SINGLE : awt::FontStrikeout::NONE ) ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbanewfont.hxx b/vbahelper/source/msforms/vbanewfont.hxx new file mode 100644 index 000000000..6f00a2724 --- /dev/null +++ b/vbahelper/source/msforms/vbanewfont.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_VBAHELPER_SOURCE_MSFORMS_VBANEWFONT_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBANEWFONT_HXX + +#include <ooo/vba/msforms/XNewFont.hpp> +#include <vbahelper/vbahelper.hxx> +#include <cppuhelper/implbase.hxx> + + +class VbaNewFont : public cppu::WeakImplHelper< ov::msforms::XNewFont > +{ +public: + /// @throws css::uno::RuntimeException + explicit VbaNewFont( + const css::uno::Reference< css::beans::XPropertySet >& rxModelProps ); + + // XNewFont attributes + virtual OUString SAL_CALL getName() override; + virtual void SAL_CALL setName( const OUString& rName ) override; + virtual double SAL_CALL getSize() override; + virtual void SAL_CALL setSize( double fSize ) override; + virtual sal_Int16 SAL_CALL getCharset() override; + virtual void SAL_CALL setCharset( sal_Int16 nCharset ) override; + virtual sal_Int16 SAL_CALL getWeight() override; + virtual void SAL_CALL setWeight( sal_Int16 nWeight ) override; + virtual sal_Bool SAL_CALL getBold() override; + virtual void SAL_CALL setBold( sal_Bool bBold ) override; + virtual sal_Bool SAL_CALL getItalic() override; + virtual void SAL_CALL setItalic( sal_Bool bItalic ) override; + virtual sal_Bool SAL_CALL getUnderline() override; + virtual void SAL_CALL setUnderline( sal_Bool bUnderline ) override; + virtual sal_Bool SAL_CALL getStrikethrough() override; + virtual void SAL_CALL setStrikethrough( sal_Bool bStrikethrough ) override; + +private: + css::uno::Reference< css::beans::XPropertySet > mxProps; +}; + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbapages.cxx b/vbahelper/source/msforms/vbapages.cxx new file mode 100644 index 000000000..05e0f25c1 --- /dev/null +++ b/vbahelper/source/msforms/vbapages.cxx @@ -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 . + */ +#include "vbapages.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +ScVbaPages::ScVbaPages( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xPages ) : ScVbaPages_BASE( xParent, xContext, xPages ) +{ +} + +uno::Type SAL_CALL +ScVbaPages::getElementType() +{ + // return cppu::UnoType<msforms::XPage>::get(); + return cppu::UnoType<uno::XInterface>::get(); +} + +uno::Any +ScVbaPages::createCollectionObject( const css::uno::Any& aSource ) +{ + return aSource; +} + +OUString +ScVbaPages::getServiceImplName() +{ + return "ScVbaPages"; +} + +uno::Reference< container::XEnumeration > SAL_CALL +ScVbaPages::createEnumeration() +{ + // #STUB + return uno::Reference< container::XEnumeration >(); +} + +uno::Sequence< OUString > +ScVbaPages::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msform.Pages" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbapages.hxx b/vbahelper/source/msforms/vbapages.hxx new file mode 100644 index 000000000..cc42da280 --- /dev/null +++ b/vbahelper/source/msforms/vbapages.hxx @@ -0,0 +1,45 @@ +/* -*- 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_VBAHELPER_SOURCE_MSFORMS_VBAPAGES_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBAPAGES_HXX + +#include <ooo/vba/msforms/XPages.hpp> + +#include <vbahelper/vbacollectionimpl.hxx> +typedef CollTestImplHelper< +ov::msforms::XPages > ScVbaPages_BASE; + +class ScVbaPages : public ScVbaPages_BASE +{ +protected: + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +public: + /// @throws css::lang::IllegalArgumentException + ScVbaPages( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xPages ); + // XEnumerationAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override; + // ScVbaPages_BASE + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + +}; +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBAPAGES_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbaprogressbar.cxx b/vbahelper/source/msforms/vbaprogressbar.cxx new file mode 100644 index 000000000..b6c3513ab --- /dev/null +++ b/vbahelper/source/msforms/vbaprogressbar.cxx @@ -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 . + */ +#include "vbaprogressbar.hxx" + +using namespace com::sun::star; +using namespace ooo::vba; + +// uno servicename com.sun.star.awt.UnoControlProgressBarMode +const OUString SVALUE( "ProgressValue" ); + +ScVbaProgressBar::ScVbaProgressBar( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ) + : ProgressBarImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ) +{ +} + +// Attributes +uno::Any SAL_CALL +ScVbaProgressBar::getValue() +{ + return m_xProps->getPropertyValue( SVALUE ); +} + +void SAL_CALL +ScVbaProgressBar::setValue( const uno::Any& _value ) +{ + m_xProps->setPropertyValue( SVALUE, _value ); +} + +OUString +ScVbaProgressBar::getServiceImplName() +{ + return "ScVbaProgressBar"; +} + +uno::Sequence< OUString > +ScVbaProgressBar::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.Label" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbaprogressbar.hxx b/vbahelper/source/msforms/vbaprogressbar.hxx new file mode 100644 index 000000000..8385ce457 --- /dev/null +++ b/vbahelper/source/msforms/vbaprogressbar.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_VBAHELPER_SOURCE_MSFORMS_VBAPROGRESSBAR_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBAPROGRESSBAR_HXX + +#include <ooo/vba/msforms/XProgressBar.hpp> +#include <com/sun/star/script/XDefaultProperty.hpp> + +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> +#include <cppuhelper/implbase.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XProgressBar, css::script::XDefaultProperty > ProgressBarImpl_BASE; + +class ScVbaProgressBar : public ProgressBarImpl_BASE +{ +public: + ScVbaProgressBar( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ); + // Attributes + virtual css::uno::Any SAL_CALL getValue() override; + virtual void SAL_CALL setValue( const css::uno::Any& _value ) override; + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + // XDefaultProperty + OUString SAL_CALL getDefaultPropertyName( ) override { return "Value"; } +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBAPROGRESSBAR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbaradiobutton.cxx b/vbahelper/source/msforms/vbaradiobutton.cxx new file mode 100644 index 000000000..5a00c21e0 --- /dev/null +++ b/vbahelper/source/msforms/vbaradiobutton.cxx @@ -0,0 +1,110 @@ +/* -*- 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 "vbaradiobutton.hxx" +#include "vbanewfont.hxx" + +using namespace com::sun::star; +using namespace ooo::vba; + +ScVbaRadioButton::ScVbaRadioButton( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ) + : RadioButtonImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ) +{ +} + +// Attributes +OUString SAL_CALL +ScVbaRadioButton::getCaption() +{ + OUString Label; + m_xProps->getPropertyValue( "Label" ) >>= Label; + return Label; +} + +void SAL_CALL +ScVbaRadioButton::setCaption( const OUString& _caption ) +{ + m_xProps->setPropertyValue( "Label", uno::makeAny( _caption ) ); +} + +uno::Any SAL_CALL +ScVbaRadioButton::getValue() +{ + sal_Int16 nValue = -1; + m_xProps->getPropertyValue( "State" ) >>= nValue; + if( nValue != 0 ) + nValue = -1; +// return uno::makeAny( nValue ); +// I must be missing something MSO says value should be -1 if selected, 0 if not +// selected + return uno::makeAny( nValue == -1 ); + +} + +void SAL_CALL +ScVbaRadioButton::setValue( const uno::Any& _value ) +{ + sal_Int16 nValue = 0; + sal_Int16 nOldValue = 0; + m_xProps->getPropertyValue( "State" ) >>= nOldValue; + + if( !( _value >>= nValue ) ) + { + bool bValue = false; + _value >>= bValue; + if ( bValue ) + nValue = -1; + } + + if( nValue == -1) + nValue = 1; + m_xProps->setPropertyValue( "State", uno::makeAny( nValue ) ); + if ( nValue != nOldValue ) + { + fireChangeEvent(); + // In Excel, only when the radio button is checked, the click event is fired. + if ( nValue != 0 ) + { + fireClickEvent(); + } + } +} + +uno::Reference< msforms::XNewFont > SAL_CALL ScVbaRadioButton::getFont() +{ + return new VbaNewFont( m_xProps ); +} + +OUString +ScVbaRadioButton::getServiceImplName() +{ + return "ScVbaRadioButton"; +} + +uno::Sequence< OUString > +ScVbaRadioButton::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.RadioButton" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbaradiobutton.hxx b/vbahelper/source/msforms/vbaradiobutton.hxx new file mode 100644 index 000000000..a6f12ae90 --- /dev/null +++ b/vbahelper/source/msforms/vbaradiobutton.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_VBAHELPER_SOURCE_MSFORMS_VBARADIOBUTTON_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBARADIOBUTTON_HXX +#include <ooo/vba/msforms/XRadioButton.hpp> +#include <com/sun/star/script/XDefaultProperty.hpp> +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> +#include <cppuhelper/implbase.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XRadioButton, css::script::XDefaultProperty > RadioButtonImpl_BASE; + +class ScVbaRadioButton : public RadioButtonImpl_BASE +{ +public: + ScVbaRadioButton( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ); + // Attributes + virtual OUString SAL_CALL getCaption() override; + virtual void SAL_CALL setCaption( const OUString& _caption ) override; + virtual css::uno::Any SAL_CALL getValue() override; + virtual void SAL_CALL setValue(const css::uno::Any&) override; + virtual css::uno::Reference< ov::msforms::XNewFont > SAL_CALL getFont() override; + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + // XDefaultProperty + OUString SAL_CALL getDefaultPropertyName( ) override { return "Value"; } + +}; +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBARADIOBUTTON_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbascrollbar.cxx b/vbahelper/source/msforms/vbascrollbar.cxx new file mode 100644 index 000000000..4968c7282 --- /dev/null +++ b/vbahelper/source/msforms/vbascrollbar.cxx @@ -0,0 +1,115 @@ +/* -*- 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 "vbascrollbar.hxx" + +using namespace com::sun::star; +using namespace ooo::vba; + +ScVbaScrollBar::ScVbaScrollBar( const css::uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<AbstractGeometryAttributes> pGeomHelper ) + : ScrollBarImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ) +{ +} + +// Attributes +uno::Any SAL_CALL +ScVbaScrollBar::getValue() +{ + return m_xProps->getPropertyValue( "ScrollValue" ); +} + +void SAL_CALL +ScVbaScrollBar::setValue( const uno::Any& _value ) +{ + m_xProps->setPropertyValue( "ScrollValue", _value ); +} + +::sal_Int32 SAL_CALL +ScVbaScrollBar::getMax() +{ + sal_Int32 nMax = 0; + m_xProps->getPropertyValue( "ScrollValueMax" ) >>= nMax; + return nMax; +} + +void SAL_CALL +ScVbaScrollBar::setMax( sal_Int32 nVal ) +{ + m_xProps->setPropertyValue( "ScrollValueMax", uno::makeAny( nVal ) ); +} + +::sal_Int32 SAL_CALL +ScVbaScrollBar::getMin() +{ + sal_Int32 nVal = 0; + m_xProps->getPropertyValue( "ScrollValueMin" ) >>= nVal; + return nVal; +} + +void SAL_CALL +ScVbaScrollBar::setMin( sal_Int32 nVal ) +{ + m_xProps->setPropertyValue( "ScrollValueMin", uno::makeAny( nVal ) ); +} + +void SAL_CALL +ScVbaScrollBar::setLargeChange( ::sal_Int32 _largechange ) +{ + m_xProps->setPropertyValue( "BlockIncrement", uno::makeAny( _largechange ) ); +} + +::sal_Int32 SAL_CALL +ScVbaScrollBar::getLargeChange() +{ + sal_Int32 nVal = 0; + m_xProps->getPropertyValue( "BlockIncrement" ) >>= nVal; + return nVal; +} + +::sal_Int32 SAL_CALL +ScVbaScrollBar::getSmallChange() +{ + sal_Int32 nSmallChange = 0; + m_xProps->getPropertyValue( "LineIncrement" ) >>= nSmallChange; + return nSmallChange; +} + +void SAL_CALL +ScVbaScrollBar::setSmallChange( ::sal_Int32 _smallchange ) +{ + m_xProps->setPropertyValue( "LineIncrement", uno::makeAny( _smallchange ) ); +} + +OUString +ScVbaScrollBar::getServiceImplName() +{ + return "ScVbaScrollBar"; +} + +uno::Sequence< OUString > +ScVbaScrollBar::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.Frame" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbascrollbar.hxx b/vbahelper/source/msforms/vbascrollbar.hxx new file mode 100644 index 000000000..e695e36b3 --- /dev/null +++ b/vbahelper/source/msforms/vbascrollbar.hxx @@ -0,0 +1,55 @@ +/* -*- 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_VBAHELPER_SOURCE_MSFORMS_VBASCROLLBAR_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBASCROLLBAR_HXX + +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/msforms/XScrollBar.hpp> + +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XScrollBar > ScrollBarImpl_BASE; + +class ScVbaScrollBar : public ScrollBarImpl_BASE +{ +public: + ScVbaScrollBar( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ); + // Attributes + virtual css::uno::Any SAL_CALL getValue() override; + virtual void SAL_CALL setValue( const css::uno::Any& _value ) override; + virtual ::sal_Int32 SAL_CALL getMax() override; + virtual void SAL_CALL setMax( ::sal_Int32 _max ) override; + virtual ::sal_Int32 SAL_CALL getMin() override; + virtual void SAL_CALL setMin( ::sal_Int32 _min ) override; + virtual ::sal_Int32 SAL_CALL getLargeChange() override; + virtual void SAL_CALL setLargeChange( ::sal_Int32 _largechange ) override; + virtual ::sal_Int32 SAL_CALL getSmallChange() override; + virtual void SAL_CALL setSmallChange( ::sal_Int32 _smallchange ) override; + + + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBASCROLLBAR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbaspinbutton.cxx b/vbahelper/source/msforms/vbaspinbutton.cxx new file mode 100644 index 000000000..3180f4861 --- /dev/null +++ b/vbahelper/source/msforms/vbaspinbutton.cxx @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "vbaspinbutton.hxx" + +using namespace com::sun::star; +using namespace ooo::vba; + +ScVbaSpinButton::ScVbaSpinButton( const css::uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<AbstractGeometryAttributes> pGeomHelper ) + : SpinButtonImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ) +{ +} + +// Attributes +uno::Any SAL_CALL +ScVbaSpinButton::getValue() +{ + return m_xProps->getPropertyValue( "SpinValue" ); +} + +void SAL_CALL +ScVbaSpinButton::setValue( const uno::Any& _value ) +{ + m_xProps->setPropertyValue( "SpinValue", _value ); +} + +::sal_Int32 SAL_CALL +ScVbaSpinButton::getMax() +{ + sal_Int32 nMax = 0; + m_xProps->getPropertyValue( "SpinValueMax" ) >>= nMax; + return nMax; +} + +void SAL_CALL +ScVbaSpinButton::setMax( sal_Int32 nVal ) +{ + m_xProps->setPropertyValue( "SpinValueMax", uno::makeAny( nVal ) ); +} + +::sal_Int32 SAL_CALL +ScVbaSpinButton::getMin() +{ + sal_Int32 nVal = 0; + m_xProps->getPropertyValue( "SpinValueMin" ) >>= nVal; + return nVal; +} + +void SAL_CALL +ScVbaSpinButton::setMin( sal_Int32 nVal ) +{ + m_xProps->setPropertyValue( "SpinValueMin", uno::makeAny( nVal ) ); +} + +OUString +ScVbaSpinButton::getServiceImplName() +{ + return "ScVbaSpinButton"; +} + +uno::Sequence< OUString > +ScVbaSpinButton::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.Frame" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbaspinbutton.hxx b/vbahelper/source/msforms/vbaspinbutton.hxx new file mode 100644 index 000000000..38f619679 --- /dev/null +++ b/vbahelper/source/msforms/vbaspinbutton.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_VBAHELPER_SOURCE_MSFORMS_VBASPINBUTTON_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBASPINBUTTON_HXX +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/msforms/XSpinButton.hpp> + +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XSpinButton > SpinButtonImpl_BASE; + +class ScVbaSpinButton : public SpinButtonImpl_BASE +{ +public: + ScVbaSpinButton( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ); + // Attributes + virtual css::uno::Any SAL_CALL getValue() override; + virtual void SAL_CALL setValue( const css::uno::Any& _value ) override; + virtual ::sal_Int32 SAL_CALL getMax() override; + virtual void SAL_CALL setMax( ::sal_Int32 _max ) override; + virtual ::sal_Int32 SAL_CALL getMin() override; + virtual void SAL_CALL setMin( ::sal_Int32 _min ) override; + + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBASPINBUTTON_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbasystemaxcontrol.cxx b/vbahelper/source/msforms/vbasystemaxcontrol.cxx new file mode 100644 index 000000000..ea135e270 --- /dev/null +++ b/vbahelper/source/msforms/vbasystemaxcontrol.cxx @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "vbasystemaxcontrol.hxx" + +using namespace com::sun::star; +using namespace ooo::vba; + + +VbaSystemAXControl::VbaSystemAXControl( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<AbstractGeometryAttributes> pGeomHelper ) +: SystemAXControlImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ) +, m_xControlInvocation( xControl, uno::UNO_QUERY_THROW ) +{ +} + + +uno::Reference< beans::XIntrospectionAccess > SAL_CALL VbaSystemAXControl::getIntrospection() +{ + return m_xControlInvocation->getIntrospection(); +} + + +uno::Any SAL_CALL VbaSystemAXControl::invoke( const OUString& aFunctionName, const uno::Sequence< uno::Any >& aParams, uno::Sequence< ::sal_Int16 >& aOutParamIndex, uno::Sequence< uno::Any >& aOutParam ) +{ + return m_xControlInvocation->invoke( aFunctionName, aParams, aOutParamIndex, aOutParam ); +} + + +void SAL_CALL VbaSystemAXControl::setValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + m_xControlInvocation->setValue( aPropertyName, aValue ); +} + + +uno::Any SAL_CALL VbaSystemAXControl::getValue( const OUString& aPropertyName ) +{ + return m_xControlInvocation->getValue( aPropertyName ); +} + + +sal_Bool SAL_CALL VbaSystemAXControl::hasMethod( const OUString& aName ) +{ + return m_xControlInvocation->hasMethod( aName ); +} + + +sal_Bool SAL_CALL VbaSystemAXControl::hasProperty( const OUString& aName ) +{ + return m_xControlInvocation->hasProperty( aName ); +} + + +OUString +VbaSystemAXControl::getServiceImplName() +{ + return "VbaSystemAXControl"; +} + + +uno::Sequence< OUString > +VbaSystemAXControl::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.Frame" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbasystemaxcontrol.hxx b/vbahelper/source/msforms/vbasystemaxcontrol.hxx new file mode 100644 index 000000000..40f575c8b --- /dev/null +++ b/vbahelper/source/msforms/vbasystemaxcontrol.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_VBAHELPER_SOURCE_MSFORMS_VBASYSTEMAXCONTROL_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBASYSTEMAXCONTROL_HXX + +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/script/XInvocation.hpp> + +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, css::script::XInvocation > SystemAXControlImpl_BASE; + +class VbaSystemAXControl : public SystemAXControlImpl_BASE +{ + css::uno::Reference< css::script::XInvocation > m_xControlInvocation; + +public: + VbaSystemAXControl( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ); + + // 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; + + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbatextbox.cxx b/vbahelper/source/msforms/vbatextbox.cxx new file mode 100644 index 000000000..59f736d48 --- /dev/null +++ b/vbahelper/source/msforms/vbatextbox.cxx @@ -0,0 +1,183 @@ +/* -*- 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 "vbatextbox.hxx" +#include "vbanewfont.hxx" +#include <com/sun/star/text/XTextRange.hpp> +#include <ooo/vba/msforms/fmBorderStyle.hpp> +#include <ooo/vba/msforms/fmSpecialEffect.hpp> + +using namespace com::sun::star; +using namespace ooo::vba; + +ScVbaTextBox::ScVbaTextBox( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<AbstractGeometryAttributes> pGeomHelper, bool bDialog ) + : TextBoxImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ), mbDialog( bDialog ) +{ +} + +// Attributes +uno::Any SAL_CALL +ScVbaTextBox::getValue() +{ + return uno::makeAny( getText() ); +} + +void SAL_CALL +ScVbaTextBox::setValue( const uno::Any& _value ) +{ + // booleans are converted to uppercase strings + OUString sVal = extractStringFromAny( _value, true ); + setText( sVal ); +} + +//getString() will cause some info lose. +OUString SAL_CALL +ScVbaTextBox::getText() +{ + uno::Any aValue = m_xProps->getPropertyValue( "Text" ); + OUString sString; + aValue >>= sString; + return sString; +} + +void SAL_CALL +ScVbaTextBox::setText( const OUString& _text ) +{ + OUString oldText( getText() ); + if ( !mbDialog ) + { + uno::Reference< text::XTextRange > xTextRange( m_xProps, uno::UNO_QUERY_THROW ); + xTextRange->setString( _text ); + } + else + m_xProps->setPropertyValue( "Text" , uno::makeAny( _text ) ); + if ( oldText != _text ) + fireChangeEvent(); +} + +sal_Int32 SAL_CALL +ScVbaTextBox::getMaxLength() +{ + uno::Any aValue = m_xProps->getPropertyValue( "MaxTextLen" ); + sal_Int16 nMaxLength = 0; + aValue >>= nMaxLength; + return static_cast<sal_Int32>(nMaxLength); +} + +void SAL_CALL +ScVbaTextBox::setMaxLength( sal_Int32 _maxlength ) +{ + sal_Int16 nTmp( _maxlength ); + uno::Any aValue( nTmp ); + m_xProps->setPropertyValue( "MaxTextLen" , aValue); +} + +sal_Bool SAL_CALL +ScVbaTextBox::getMultiline() +{ + uno::Any aValue = m_xProps->getPropertyValue( "MultiLine" ); + bool bRet = false; + aValue >>= bRet; + return bRet; +} + +void SAL_CALL +ScVbaTextBox::setMultiline( sal_Bool _multiline ) +{ + uno::Any aValue( _multiline ); + m_xProps->setPropertyValue( "MultiLine" , aValue); +} + +sal_Int32 SAL_CALL ScVbaTextBox::getSpecialEffect() +{ + return msforms::fmSpecialEffect::fmSpecialEffectSunken; +} + +void SAL_CALL ScVbaTextBox::setSpecialEffect( sal_Int32 /*nSpecialEffect*/ ) +{ + // #STUB +} + +sal_Int32 SAL_CALL ScVbaTextBox::getBorderStyle() +{ + return msforms::fmBorderStyle::fmBorderStyleNone; +} + +void SAL_CALL ScVbaTextBox::setBorderStyle( sal_Int32 /*nBorderStyle*/ ) +{ + // #STUB +} + +sal_Int32 SAL_CALL ScVbaTextBox::getTextLength() +{ + return getText().getLength(); +} + +uno::Reference< msforms::XNewFont > SAL_CALL ScVbaTextBox::getFont() +{ + return new VbaNewFont( m_xProps ); +} + +sal_Int32 SAL_CALL ScVbaTextBox::getBackColor() +{ + return ScVbaControl::getBackColor(); +} + +void SAL_CALL ScVbaTextBox::setBackColor( sal_Int32 nBackColor ) +{ + ScVbaControl::setBackColor( nBackColor ); +} + +sal_Bool SAL_CALL ScVbaTextBox::getAutoSize() +{ + return ScVbaControl::getAutoSize(); +} + +void SAL_CALL ScVbaTextBox::setAutoSize( sal_Bool bAutoSize ) +{ + ScVbaControl::setAutoSize( bAutoSize ); +} + +sal_Bool SAL_CALL ScVbaTextBox::getLocked() +{ + return ScVbaControl::getLocked(); +} + +void SAL_CALL ScVbaTextBox::setLocked( sal_Bool bLocked ) +{ + ScVbaControl::setLocked( bLocked ); +} + +OUString +ScVbaTextBox::getServiceImplName() +{ + return "ScVbaTextBox"; +} + +uno::Sequence< OUString > +ScVbaTextBox::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.TextBox" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbatextbox.hxx b/vbahelper/source/msforms/vbatextbox.hxx new file mode 100644 index 000000000..9a2b96942 --- /dev/null +++ b/vbahelper/source/msforms/vbatextbox.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_VBAHELPER_SOURCE_MSFORMS_VBATEXTBOX_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBATEXTBOX_HXX + +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/msforms/XTextBox.hpp> +#include <com/sun/star/script/XDefaultProperty.hpp> +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XTextBox, css::script::XDefaultProperty > TextBoxImpl_BASE; + +class ScVbaTextBox : public TextBoxImpl_BASE +{ + bool mbDialog; +public: + ScVbaTextBox( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper, bool bDialog = false ); + // Attributes + virtual css::uno::Any SAL_CALL getValue() override; + virtual void SAL_CALL setValue( const css::uno::Any& _value ) override; + virtual OUString SAL_CALL getText() override; + virtual void SAL_CALL setText( const OUString& _text ) override; + virtual sal_Int32 SAL_CALL getMaxLength() override; + virtual void SAL_CALL setMaxLength( sal_Int32 _maxlength ) override; + virtual sal_Bool SAL_CALL getMultiline() override; + virtual void SAL_CALL setMultiline( sal_Bool _multiline ) override; + virtual sal_Int32 SAL_CALL getSpecialEffect() override; + virtual void SAL_CALL setSpecialEffect( sal_Int32 nSpecialEffect ) override; + virtual sal_Int32 SAL_CALL getBorderStyle() override; + virtual void SAL_CALL setBorderStyle( sal_Int32 nBorderStyle ) override; + virtual sal_Int32 SAL_CALL getTextLength() override; + virtual css::uno::Reference< ov::msforms::XNewFont > SAL_CALL getFont() override; + virtual sal_Int32 SAL_CALL getBackColor() override; + virtual void SAL_CALL setBackColor( sal_Int32 nBackColor ) override; + virtual sal_Bool SAL_CALL getAutoSize() override; + virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) override; + virtual sal_Bool SAL_CALL getLocked() override; + virtual void SAL_CALL setLocked( sal_Bool bAutoSize ) override; + + // XDefaultProperty + OUString SAL_CALL getDefaultPropertyName( ) override { return "Value"; } + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBATEXTBOX_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbatogglebutton.cxx b/vbahelper/source/msforms/vbatogglebutton.cxx new file mode 100644 index 000000000..fbb7c267a --- /dev/null +++ b/vbahelper/source/msforms/vbatogglebutton.cxx @@ -0,0 +1,164 @@ +/* -*- 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 "vbatogglebutton.hxx" +#include "vbanewfont.hxx" +#include <sal/log.hxx> + +using namespace com::sun::star; +using namespace ooo::vba; + +ScVbaToggleButton::ScVbaToggleButton( const css::uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< uno::XInterface >& xControl, const uno::Reference< frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ) + : ToggleButtonImpl_BASE( xParent, xContext, xControl, xModel, std::move(pGeomHelper) ) +{ + SAL_INFO("vbahelper", "ScVbaToggleButton(ctor)"); + m_xProps->setPropertyValue( "Toggle", uno::makeAny( true ) ); +} + +ScVbaToggleButton::~ScVbaToggleButton() +{ + SAL_INFO("vbahelper", "~ScVbaToggleButton(dtor)"); +} + +// Attributes +OUString SAL_CALL +ScVbaToggleButton::getCaption() +{ + OUString Label; + m_xProps->getPropertyValue( "Label" ) >>= Label; + return Label; +} + +void SAL_CALL +ScVbaToggleButton::setCaption( const OUString& _caption ) +{ + m_xProps->setPropertyValue( "Label", uno::makeAny( _caption ) ); +} + +uno::Any SAL_CALL +ScVbaToggleButton::getValue() +{ + sal_Int16 nState = 0; + m_xProps->getPropertyValue( "State" ) >>= nState; + return uno::makeAny( nState ? sal_Int16( -1 ) : sal_Int16( 0 ) ); +} + + +void SAL_CALL +ScVbaToggleButton::setValue( const uno::Any& _value ) +{ + sal_Int16 nState = 0; + if ( ! ( _value >>= nState ) ) + { + bool bState = false; + _value >>= bState; + if ( bState ) + nState = -1; + } + SAL_INFO("vbahelper", "nState - " << nState ); + nState = ( nState == -1 ) ? 1 : 0; + SAL_INFO("vbahelper", "nState - " << nState ); + m_xProps->setPropertyValue( "State", uno::makeAny( nState ) ); +} + +sal_Bool SAL_CALL ScVbaToggleButton::getAutoSize() +{ + return ScVbaControl::getAutoSize(); +} + +void SAL_CALL ScVbaToggleButton::setAutoSize( sal_Bool bAutoSize ) +{ + ScVbaControl::setAutoSize( bAutoSize ); +} + +sal_Bool SAL_CALL ScVbaToggleButton::getCancel() +{ + // #STUB + return false; +} + +void SAL_CALL ScVbaToggleButton::setCancel( sal_Bool /*bCancel*/ ) +{ + // #STUB +} + +sal_Bool SAL_CALL ScVbaToggleButton::getDefault() +{ + // #STUB + return false; +} + +void SAL_CALL ScVbaToggleButton::setDefault( sal_Bool /*bDefault*/ ) +{ + // #STUB +} + +sal_Int32 SAL_CALL ScVbaToggleButton::getBackColor() +{ + return ScVbaControl::getBackColor(); +} + +void SAL_CALL ScVbaToggleButton::setBackColor( sal_Int32 nBackColor ) +{ + ScVbaControl::setBackColor( nBackColor ); +} + +sal_Int32 SAL_CALL ScVbaToggleButton::getForeColor() +{ + // #STUB + return 0; +} + +void SAL_CALL ScVbaToggleButton::setForeColor( sal_Int32 /*nForeColor*/ ) +{ + // #STUB +} + +uno::Reference< msforms::XNewFont > SAL_CALL ScVbaToggleButton::getFont() +{ + return new VbaNewFont( m_xProps ); +} + +sal_Bool SAL_CALL ScVbaToggleButton::getLocked() +{ + return ScVbaControl::getLocked(); +} + +void SAL_CALL ScVbaToggleButton::setLocked( sal_Bool bLocked ) +{ + ScVbaControl::setLocked( bLocked ); +} + +OUString +ScVbaToggleButton::getServiceImplName() +{ + return "ScVbaToggleButton"; +} + +uno::Sequence< OUString > +ScVbaToggleButton::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.ToggleButton" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbatogglebutton.hxx b/vbahelper/source/msforms/vbatogglebutton.hxx new file mode 100644 index 000000000..61be1a672 --- /dev/null +++ b/vbahelper/source/msforms/vbatogglebutton.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_VBAHELPER_SOURCE_MSFORMS_VBATOGGLEBUTTON_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBATOGGLEBUTTON_HXX +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/msforms/XToggleButton.hpp> +#include <com/sun/star/script/XDefaultProperty.hpp> + +#include "vbacontrol.hxx" +#include <vbahelper/vbahelper.hxx> + +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XToggleButton, css::script::XDefaultProperty > ToggleButtonImpl_BASE; + +class ScVbaToggleButton : public ToggleButtonImpl_BASE +{ +public: + ScVbaToggleButton( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::uno::XInterface >& xControl, const css::uno::Reference< css::frame::XModel >& xModel, std::unique_ptr<ov::AbstractGeometryAttributes> pGeomHelper ); + virtual ~ScVbaToggleButton() override; + // Attributes + virtual css::uno::Any SAL_CALL getValue() override; + virtual void SAL_CALL setValue( const css::uno::Any& _value ) override; + virtual OUString SAL_CALL getCaption() override; + virtual void SAL_CALL setCaption( const OUString& _caption ) override; + virtual sal_Bool SAL_CALL getAutoSize() override; + virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) override; + virtual sal_Bool SAL_CALL getCancel() override; + virtual void SAL_CALL setCancel( sal_Bool bCancel ) override; + virtual sal_Bool SAL_CALL getDefault() override; + virtual void SAL_CALL setDefault( sal_Bool bDefault ) override; + virtual sal_Int32 SAL_CALL getBackColor() override; + virtual void SAL_CALL setBackColor( sal_Int32 nBackColor ) override; + virtual sal_Int32 SAL_CALL getForeColor() override; + virtual void SAL_CALL setForeColor( sal_Int32 nForeColor ) override; + virtual sal_Bool SAL_CALL getLocked() override; + virtual void SAL_CALL setLocked( sal_Bool bAutoSize ) override; + virtual css::uno::Reference< ov::msforms::XNewFont > SAL_CALL getFont() override; + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + // XDefaultProperty + OUString SAL_CALL getDefaultPropertyName( ) override { return "Value"; } +}; +#endif // INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBATOGGLEBUTTON_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbauserform.cxx b/vbahelper/source/msforms/vbauserform.cxx new file mode 100644 index 000000000..a89ab604a --- /dev/null +++ b/vbahelper/source/msforms/vbauserform.cxx @@ -0,0 +1,320 @@ +/* -*- 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 <vbahelper/helperdecl.hxx> +#include "service.hxx" +#include "vbauserform.hxx" +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XControlContainer.hpp> +#include <com/sun/star/awt/XWindow2.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/script/XDefaultProperty.hpp> +#include "vbacontrols.hxx" +#include <sal/log.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +// some little notes +// XDialog implementation has the following interesting bits +// a Controls property ( which is an array of the container controls ) +// each item in the controls array is a XControl, where the model is +// basically a property bag +// additionally the XDialog instance has itself a model +// this model has a ControlModels ( array of models ) property +// the models in ControlModels can be accessed by name +// also the XDialog is a XControl ( to access the model above + +ScVbaUserForm::ScVbaUserForm( uno::Sequence< uno::Any > const& aArgs, uno::Reference< uno::XComponentContext >const& xContext ) + : ScVbaUserForm_BASE( getXSomethingFromArgs< XHelperInterface >( aArgs, 0 ), xContext, getXSomethingFromArgs< uno::XInterface >( aArgs, 1 ), getXSomethingFromArgs< frame::XModel >( aArgs, 2 ), nullptr ), + mbDispose( true ) +{ + m_xDialog.set( m_xControl, uno::UNO_QUERY_THROW ); + uno::Reference< awt::XControl > xControl( m_xDialog, uno::UNO_QUERY_THROW ); + m_xProps.set( xControl->getModel(), uno::UNO_QUERY_THROW ); + setGeometryHelper( std::make_unique<UserFormGeometryHelper>( xControl, 0.0, 0.0 ) ); + if ( aArgs.getLength() >= 4 ) + aArgs[ 3 ] >>= m_sLibName; +} + +ScVbaUserForm::~ScVbaUserForm() +{ +} + +void SAL_CALL +ScVbaUserForm::Show( ) +{ + SAL_INFO("vbahelper", "ScVbaUserForm::Show( )"); + short aRet = 0; + mbDispose = true; + + if ( m_xDialog.is() ) + { + // try to center dialog on model window + if( m_xModel.is() ) try + { + uno::Reference< frame::XController > xController( m_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 ); + awt::Rectangle aPosSize = xWindow->getPosSize(); // already in pixel + + uno::Reference< awt::XControl > xControl( m_xDialog, uno::UNO_QUERY_THROW ); + uno::Reference< awt::XWindow > xControlWindow( xControl->getPeer(), uno::UNO_QUERY_THROW ); + xControlWindow->setPosSize(static_cast<sal_Int32>((aPosSize.Width - getWidth()) / 2.0), static_cast<sal_Int32>((aPosSize.Height - getHeight()) / 2.0), 0, 0, awt::PosSize::POS ); + } + catch( uno::Exception& ) + { + } + + aRet = m_xDialog->execute(); + } + SAL_INFO("vbahelper", "ScVbaUserForm::Show() execute returned " << aRet); + if ( mbDispose ) + { + try + { + uno::Reference< lang::XComponent > xComp( m_xDialog, uno::UNO_QUERY_THROW ); + m_xDialog = nullptr; + xComp->dispose(); + mbDispose = false; + } + catch( uno::Exception& ) + { + } + } +} + +OUString SAL_CALL +ScVbaUserForm::getCaption() +{ + OUString sCaption; + m_xProps->getPropertyValue( "Title" ) >>= sCaption; + return sCaption; +} +void +ScVbaUserForm::setCaption( const OUString& _caption ) +{ + m_xProps->setPropertyValue( "Title", uno::makeAny( _caption ) ); +} + +sal_Bool SAL_CALL +ScVbaUserForm::getVisible() +{ + uno::Reference< awt::XControl > xControl( m_xDialog, uno::UNO_QUERY_THROW ); + uno::Reference< awt::XWindow2 > xControlWindow( xControl->getPeer(), uno::UNO_QUERY_THROW ); + return xControlWindow->isVisible(); +} + +void SAL_CALL +ScVbaUserForm::setVisible( sal_Bool bVis ) +{ + if ( bVis ) + Show(); + else + Hide(); +} + +double SAL_CALL ScVbaUserForm::getInnerWidth() +{ + return mpGeometryHelper->getInnerWidth(); +} + +void SAL_CALL ScVbaUserForm::setInnerWidth( double fInnerWidth ) +{ + mpGeometryHelper->setInnerWidth( fInnerWidth ); +} + +double SAL_CALL ScVbaUserForm::getInnerHeight() +{ + return mpGeometryHelper->getInnerHeight(); +} + +void SAL_CALL ScVbaUserForm::setInnerHeight( double fInnerHeight ) +{ + mpGeometryHelper->setInnerHeight( fInnerHeight ); +} + +void SAL_CALL +ScVbaUserForm::Hide( ) +{ + mbDispose = false; // hide not dispose + if ( m_xDialog.is() ) + m_xDialog->endExecute(); +} + +void SAL_CALL +ScVbaUserForm::RePaint( ) +{ + // #STUB + // do nothing +} + +void SAL_CALL +ScVbaUserForm::UnloadObject( ) +{ + mbDispose = true; + if ( m_xDialog.is() ) + m_xDialog->endExecute(); +} + +OUString +ScVbaUserForm::getServiceImplName() +{ + return "ScVbaUserForm"; +} + +uno::Sequence< OUString > +ScVbaUserForm::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.excel.UserForm" + }; + return aServiceNames; +} + +uno::Reference< beans::XIntrospectionAccess > SAL_CALL +ScVbaUserForm::getIntrospection( ) +{ + return uno::Reference< beans::XIntrospectionAccess >(); +} + +uno::Any SAL_CALL +ScVbaUserForm::invoke( const OUString& /*aFunctionName*/, const uno::Sequence< uno::Any >& /*aParams*/, uno::Sequence< ::sal_Int16 >& /*aOutParamIndex*/, uno::Sequence< uno::Any >& /*aOutParam*/ ) +{ + throw uno::RuntimeException(); // unsupported operation +} + +void SAL_CALL +ScVbaUserForm::setValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + uno::Any aObject = getValue( aPropertyName ); + + // in case the dialog is already closed the VBA implementation should not throw exceptions + if ( aObject.hasValue() ) + { + // The Object *must* support XDefaultProperty here because getValue will + // only return properties that are Objects ( e.g. controls ) + // e.g. Userform1.aControl = something + // 'aControl' has to support XDefaultProperty to make sense here + uno::Reference< script::XDefaultProperty > xDfltProp( aObject, uno::UNO_QUERY_THROW ); + OUString aDfltPropName = xDfltProp->getDefaultPropertyName(); + uno::Reference< beans::XIntrospectionAccess > xUnoAccess( getIntrospectionAccess( aObject ) ); + uno::Reference< beans::XPropertySet > xPropSet( xUnoAccess->queryAdapter( cppu::UnoType<beans::XPropertySet>::get()), uno::UNO_QUERY_THROW ); + xPropSet->setPropertyValue( aDfltPropName, aValue ); + } +} + +uno::Reference< awt::XControl > +ScVbaUserForm::nestedSearch( const OUString& aPropertyName, uno::Reference< awt::XControlContainer > const & xContainer ) +{ + uno::Reference< awt::XControl > xControl = xContainer->getControl( aPropertyName ); + if ( !xControl.is() ) + { + const uno::Sequence< uno::Reference< awt::XControl > > aControls = xContainer->getControls(); + + for ( const auto& rCtrl : aControls ) + { + uno::Reference< awt::XControlContainer > xC( rCtrl, uno::UNO_QUERY ); + if ( xC.is() ) + { + xControl.set( nestedSearch( aPropertyName, xC ) ); + if ( xControl.is() ) + break; + } + } + } + return xControl; +} + +uno::Any SAL_CALL +ScVbaUserForm::getValue( const OUString& aPropertyName ) +{ + uno::Any aResult; + + // in case the dialog is already closed the VBA implementation should not throw exceptions + if ( m_xDialog.is() ) + { + uno::Reference< awt::XControl > xDialogControl( m_xDialog, uno::UNO_QUERY_THROW ); + uno::Reference< awt::XControlContainer > xContainer( m_xDialog, uno::UNO_QUERY_THROW ); + uno::Reference< awt::XControl > xControl = nestedSearch( aPropertyName, xContainer ); + xContainer->getControl( aPropertyName ); + if ( xControl.is() ) + { + uno::Reference< msforms::XControl > xVBAControl = ScVbaControlFactory::createUserformControl( mxContext, xControl, xDialogControl, m_xModel, mpGeometryHelper->getOffsetX(), mpGeometryHelper->getOffsetY() ); + ScVbaControl* pControl = dynamic_cast< ScVbaControl* >( xVBAControl.get() ); + if (pControl && !m_sLibName.isEmpty()) + pControl->setLibraryAndCodeName( m_sLibName.concat( "." ).concat( getName() ) ); + aResult <<= xVBAControl; + } + } + + return aResult; +} + +sal_Bool SAL_CALL +ScVbaUserForm::hasMethod( const OUString& /*aName*/ ) +{ + return false; +} +uno::Any SAL_CALL +ScVbaUserForm::Controls( const uno::Any& index ) +{ + // if the dialog already closed we should do nothing, but the VBA will call methods of the Controls objects + // thus we have to provide a dummy object in this case + uno::Reference< awt::XControl > xDialogControl( m_xDialog, uno::UNO_QUERY ); + uno::Reference< XCollection > xControls( new ScVbaControls( this, mxContext, xDialogControl, m_xModel, mpGeometryHelper->getOffsetX(), mpGeometryHelper->getOffsetY() ) ); + if ( index.hasValue() ) + return xControls->Item( index, uno::Any() ); + return uno::makeAny( xControls ); +} + +sal_Bool SAL_CALL +ScVbaUserForm::hasProperty( const OUString& aName ) +{ + uno::Reference< awt::XControl > xControl( m_xDialog, uno::UNO_QUERY ); + + SAL_INFO("vbahelper", "ScVbaUserForm::hasProperty(" << aName << ") " << xControl.is() ); + if ( xControl.is() ) + { + uno::Reference< beans::XPropertySet > xDlgProps( xControl->getModel(), uno::UNO_QUERY ); + if ( xDlgProps.is() ) + { + uno::Reference< container::XNameContainer > xAllChildren( xDlgProps->getPropertyValue( "AllDialogChildren" ), uno::UNO_QUERY_THROW ); + bool bRes = xAllChildren->hasByName( aName ); + SAL_INFO("vbahelper", "ScVbaUserForm::hasProperty(" << aName << ") " << xAllChildren.is() << " ---> " << bRes ); + return bRes; + } + } + return false; +} + +namespace userform +{ +namespace sdecl = comphelper::service_decl; +sdecl::vba_service_class_<ScVbaUserForm, sdecl::with_args<true> > const serviceImpl; +sdecl::ServiceDecl const serviceDecl( + serviceImpl, + "ScVbaUserForm", + "ooo.vba.msforms.UserForm" ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/msforms/vbauserform.hxx b/vbahelper/source/msforms/vbauserform.hxx new file mode 100644 index 000000000..ded092bc1 --- /dev/null +++ b/vbahelper/source/msforms/vbauserform.hxx @@ -0,0 +1,72 @@ +/* -*- 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_VBAHELPER_SOURCE_MSFORMS_VBAUSERFORM_HXX +#define INCLUDED_VBAHELPER_SOURCE_MSFORMS_VBAUSERFORM_HXX + +#include <cppuhelper/implbase.hxx> +#include <ooo/vba/msforms/XUserForm.hpp> +#include <com/sun/star/awt/XDialog.hpp> +#include <com/sun/star/awt/XControlContainer.hpp> + +#include "vbacontrol.hxx" + +//typedef InheritedHelperInterfaceWeakImpl< ov::msforms::XUserForm > ScVbaUserForm_BASE; +typedef cppu::ImplInheritanceHelper< ScVbaControl, ov::msforms::XUserForm > ScVbaUserForm_BASE; + +class ScVbaUserForm : public ScVbaUserForm_BASE +{ +private: + css::uno::Reference< css::awt::XDialog > m_xDialog; + bool mbDispose; + OUString m_sLibName; +protected: +public: + /// @throws css::lang::IllegalArgumentException + /// @throws css::uno::RuntimeException + ScVbaUserForm( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext ); + virtual ~ScVbaUserForm() override; + static css::uno::Reference< css::awt::XControl > nestedSearch( const OUString& aPropertyName, css::uno::Reference< css::awt::XControlContainer > const & xContainer ); + // XUserForm + virtual void SAL_CALL RePaint( ) override; + virtual void SAL_CALL Show( ) 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 OUString SAL_CALL getCaption() override; + virtual void SAL_CALL setCaption( const OUString& _caption ) override; + virtual double SAL_CALL getInnerWidth() override; + virtual void SAL_CALL setInnerWidth( double fInnerWidth ) override; + virtual double SAL_CALL getInnerHeight() override; + virtual void SAL_CALL setInnerHeight( double fInnerHeight ) override; + virtual void SAL_CALL Hide( ) override; + virtual void SAL_CALL UnloadObject( ) override; + virtual css::uno::Any SAL_CALL Controls( const css::uno::Any& index ) override; + virtual sal_Bool SAL_CALL getVisible() override; + virtual void SAL_CALL setVisible( sal_Bool bVis ) override; + // XIntrospection + 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 sal_Bool SAL_CALL hasMethod( const OUString& aName ) override; + virtual sal_Bool SAL_CALL hasProperty( const OUString& aName ) override; + //XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbaapplicationbase.cxx b/vbahelper/source/vbahelper/vbaapplicationbase.cxx new file mode 100644 index 000000000..286b38bd4 --- /dev/null +++ b/vbahelper/source/vbahelper/vbaapplicationbase.cxx @@ -0,0 +1,485 @@ +/* -*- 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 <vbahelper/vbaapplicationbase.hxx> +#include <sal/macros.h> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <com/sun/star/awt/XWindow2.hpp> + +#include <filter/msfilter/msvbahelper.hxx> +#include <rtl/ref.hxx> +#include <tools/datetime.hxx> +#include <vcl/timer.hxx> +#include <vcl/svapp.hxx> + +#include <basic/sbstar.hxx> +#include <basic/sbmeth.hxx> +#include <basic/sbmod.hxx> +#include <basic/vbahelper.hxx> + +#include <comphelper/asyncquithandler.hxx> + +#include "vbacommandbars.hxx" + +#include <boost/functional/hash.hpp> +#include <unordered_map> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +#define OFFICEVERSION "11.0" + +typedef ::std::pair< OUString, ::std::pair< double, double > > VbaTimerInfo; + +namespace { + +class VbaTimer +{ + Timer m_aTimer; + VbaTimerInfo m_aTimerInfo; + ::rtl::Reference< VbaApplicationBase > m_xBase; + +public: + VbaTimer() + {} + + ~VbaTimer() + { + m_aTimer.Stop(); + } + + VbaTimer(const VbaTimer&) = delete; + VbaTimer& operator=(const VbaTimer&) = delete; + + static double GetNow() + { + DateTime aNow( DateTime::SYSTEM ); + Date aRefDate( 1,1,1900 ); + long nDiffDays = aNow - aRefDate; + nDiffDays += 2; // Change VisualBasic: 1.Jan.1900 == 2 + + long nDiffSeconds = aNow.GetHour() * 3600 + aNow.GetMin() * 60 + aNow.GetSec(); + return static_cast<double>(nDiffDays) + static_cast<double>(nDiffSeconds)/double(24*3600); + } + + static sal_Int32 GetTimerMiliseconds( double nFrom, double nTo ) + { + double nResult = nTo - nFrom; + if ( nResult > 0 ) + nResult *= 24*3600*1000; + else + nResult = 50; + + return static_cast<sal_Int32>(nResult); + } + + void Start( const ::rtl::Reference< VbaApplicationBase >& xBase, const OUString& aFunction, double nFrom, double nTo ) + { + if ( !xBase.is() || aFunction.isEmpty() ) + throw uno::RuntimeException( "Unexpected arguments!" ); + + m_xBase = xBase; + m_aTimerInfo = VbaTimerInfo( aFunction, ::std::pair< double, double >( nFrom, nTo ) ); + m_aTimer.SetInvokeHandler( LINK( this, VbaTimer, MacroCallHdl ) ); + m_aTimer.SetTimeout( GetTimerMiliseconds( GetNow(), nFrom ) ); + m_aTimer.Start(); + } + + DECL_LINK( MacroCallHdl, Timer*, void ); +}; + +} + +IMPL_LINK_NOARG(VbaTimer, MacroCallHdl, Timer *, void) +{ + if ( m_aTimerInfo.second.second == 0 || GetNow() < m_aTimerInfo.second.second ) + { + uno::Any aDummyArg; + try + { + m_xBase->Run( m_aTimerInfo.first, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg, aDummyArg ); + } + catch( uno::Exception& ) + {} + } + + // must be the last call in the method since it deletes the timer + try + { + m_xBase->OnTime( uno::makeAny( m_aTimerInfo.second.first ), m_aTimerInfo.first, uno::makeAny( m_aTimerInfo.second.second ), uno::makeAny( false ) ); + } catch( uno::Exception& ) + {} +} + +namespace { + +struct VbaTimerInfoHash +{ + size_t operator()( const VbaTimerInfo& rTimerInfo ) const + { + std::size_t seed = 0; + boost::hash_combine(seed, rTimerInfo.first.hashCode()); + boost::hash_combine(seed, rTimerInfo.second.first); + boost::hash_combine(seed, rTimerInfo.second.second); + return seed; + } +}; + +} + +typedef std::unordered_map< VbaTimerInfo, std::unique_ptr<VbaTimer>, VbaTimerInfoHash > VbaTimerHashMap; + +struct VbaApplicationBase_Impl final +{ + VbaTimerHashMap m_aTimerHash; + bool mbVisible; + OUString msCaption; + + VbaApplicationBase_Impl() : mbVisible( true ) {} +}; + +VbaApplicationBase::VbaApplicationBase( const uno::Reference< uno::XComponentContext >& xContext ) + : ApplicationBase_BASE( uno::Reference< XHelperInterface >(), xContext ) + , m_pImpl( new VbaApplicationBase_Impl ) +{ +} + +VbaApplicationBase::~VbaApplicationBase() +{ +} + +sal_Bool SAL_CALL +VbaApplicationBase::getScreenUpdating() +{ + uno::Reference< frame::XModel > xModel = getCurrentDocument(); + if (!xModel.is()) + return true; + return !xModel->hasControllersLocked(); +} + +void SAL_CALL +VbaApplicationBase::setScreenUpdating(sal_Bool bUpdate) +{ + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW ); + // #163808# use helper from module "basic" to lock all documents of this application + ::basic::vba::lockControllersOfAllDocuments( xModel, !bUpdate ); +} + +sal_Bool SAL_CALL +VbaApplicationBase::getDisplayStatusBar() +{ + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW ); + uno::Reference< frame::XFrame > xFrame( xModel->getCurrentController()->getFrame(), uno::UNO_SET_THROW ); + uno::Reference< beans::XPropertySet > xProps( xFrame, uno::UNO_QUERY_THROW ); + + uno::Reference< frame::XLayoutManager > xLayoutManager( xProps->getPropertyValue( "LayoutManager"), uno::UNO_QUERY_THROW ); + if( xLayoutManager->isElementVisible( "private:resource/statusbar/statusbar" ) ){ + return true; + } + return false; +} + +void SAL_CALL +VbaApplicationBase::setDisplayStatusBar(sal_Bool bDisplayStatusBar) +{ + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW ); + uno::Reference< frame::XFrame > xFrame( xModel->getCurrentController()->getFrame(), uno::UNO_SET_THROW ); + uno::Reference< beans::XPropertySet > xProps( xFrame, uno::UNO_QUERY_THROW ); + + uno::Reference< frame::XLayoutManager > xLayoutManager( xProps->getPropertyValue( "LayoutManager" ), uno::UNO_QUERY_THROW ); + OUString url( "private:resource/statusbar/statusbar" ); + if( bDisplayStatusBar && !xLayoutManager->isElementVisible( url ) ){ + if( !xLayoutManager->showElement( url ) ) + xLayoutManager->createElement( url ); + return; + } + else if( !bDisplayStatusBar && xLayoutManager->isElementVisible( url ) ){ + xLayoutManager->hideElement( url ); + return; + } +} + +sal_Bool SAL_CALL VbaApplicationBase::getInteractive() +{ + uno::Reference< frame::XModel > xModel = getCurrentDocument(); + if (!xModel.is()) + return true; + + uno::Reference< frame::XController > xController( xModel->getCurrentController() ); + if (!xController.is()) + return true; + + uno::Reference< frame::XFrame > xFrame( xController->getFrame() ); + if (!xFrame.is()) + return true; + + uno::Reference< awt::XWindow2 > xWindow( xFrame->getContainerWindow(), uno::UNO_QUERY ); + if (!xWindow.is()) + return true; + + return xWindow->isEnabled(); +} + +void SAL_CALL VbaApplicationBase::setInteractive( sal_Bool bInteractive ) +{ + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW ); + // #163808# use helper from module "basic" to enable/disable all container windows of all documents of this application + ::basic::vba::enableContainerWindowsOfAllDocuments( xModel, bInteractive ); +} + +sal_Bool SAL_CALL VbaApplicationBase::getVisible() +{ + return m_pImpl->mbVisible; // dummy implementation +} + +void SAL_CALL VbaApplicationBase::setVisible( sal_Bool bVisible ) +{ + m_pImpl->mbVisible = bVisible; // dummy implementation +} + +OUString SAL_CALL VbaApplicationBase::getCaption() +{ + SbMethod* pMeth = StarBASIC::GetActiveMethod(); + if (!pMeth) + { + // When called from Automation clients, we don't even try, as there doesn't seem to be any + // good way to get at the actual "caption" (title) of the application's window (any of them, + // if there are several). We just keep a copy of a fake caption in the VbaApplicationBase_Impl. + return m_pImpl->msCaption; + } + + // No idea if this code, which uses APIs that apparently are related to StarBasic (check + // getCurrentDoc() in vbahelper.cxx), actually works any better. + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW ); + uno::Reference< frame::XFrame > xFrame( xModel->getCurrentController()->getFrame(), uno::UNO_SET_THROW ); + return xFrame->getName(); +} + +void SAL_CALL VbaApplicationBase::setCaption( const OUString& sCaption ) +{ + // See comments in getCaption(). + + SbMethod* pMeth = StarBASIC::GetActiveMethod(); + if (!pMeth) + { + m_pImpl->msCaption = sCaption; + return; + } + + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW ); + uno::Reference< frame::XFrame > xFrame( xModel->getCurrentController()->getFrame(), uno::UNO_SET_THROW ); + xFrame->setName( sCaption ); +} + +void SAL_CALL +VbaApplicationBase::OnKey( const OUString& Key, const uno::Any& Procedure ) +{ + // parse the Key & modifiers + awt::KeyEvent aKeyEvent = parseKeyEvent( Key ); + OUString MacroName; + Procedure >>= MacroName; + uno::Reference< frame::XModel > xModel; + SbMethod* pMeth = StarBASIC::GetActiveMethod(); + if ( pMeth ) + { + SbModule* pMod = dynamic_cast< SbModule* >( pMeth->GetParent() ); + if ( pMod ) + xModel = StarBASIC::GetModelFromBasic( pMod ); + } + + if ( !xModel.is() ) + xModel = getCurrentDocument(); + + applyShortCutKeyBinding( xModel, aKeyEvent, MacroName ); +} + +uno::Any SAL_CALL +VbaApplicationBase::CommandBars( const uno::Any& aIndex ) +{ + uno::Reference< XCommandBars > xCommandBars( new ScVbaCommandBars( this, mxContext, uno::Reference< container::XIndexAccess >(), getCurrentDocument() ) ); + if( aIndex.hasValue() ) + return xCommandBars->Item( aIndex, uno::Any() ); + return uno::makeAny( xCommandBars ); +} + +OUString SAL_CALL +VbaApplicationBase::getVersion() +{ + return OFFICEVERSION; +} + +uno::Any SAL_CALL VbaApplicationBase::Run( const OUString& MacroName, const uno::Any& varg1, const uno::Any& varg2, const uno::Any& varg3, const uno::Any& varg4, const uno::Any& varg5, const uno::Any& varg6, const uno::Any& varg7, const uno::Any& varg8, const uno::Any& varg9, const uno::Any& varg10, const uno::Any& varg11, const uno::Any& varg12, const uno::Any& varg13, const uno::Any& varg14, const uno::Any& varg15, const uno::Any& varg16, const uno::Any& varg17, const uno::Any& varg18, const uno::Any& varg19, const uno::Any& varg20, const uno::Any& varg21, const uno::Any& varg22, const uno::Any& varg23, const uno::Any& varg24, const uno::Any& varg25, const uno::Any& varg26, const uno::Any& varg27, const uno::Any& varg28, const uno::Any& varg29, const uno::Any& varg30 ) +{ + OUString aMacroName = MacroName.trim(); + if( aMacroName.startsWith("!") ) + aMacroName = aMacroName.copy(1).trim(); + + uno::Reference< frame::XModel > xModel; + SbMethod* pMeth = StarBASIC::GetActiveMethod(); + if ( pMeth ) + { + SbModule* pMod = dynamic_cast< SbModule* >( pMeth->GetParent() ); + if ( pMod ) + xModel = StarBASIC::GetModelFromBasic( pMod ); + } + + if ( !xModel.is() ) + xModel = getCurrentDocument(); + + MacroResolvedInfo aMacroInfo = resolveVBAMacro( getSfxObjShell( xModel ), aMacroName ); + if( !aMacroInfo.mbFound ) + { + throw uno::RuntimeException( "The macro doesn't exist" ); + } + + // handle the arguments + const uno::Any* aArgsPtrArray[] = { &varg1, &varg2, &varg3, &varg4, &varg5, &varg6, &varg7, &varg8, &varg9, &varg10, &varg11, &varg12, &varg13, &varg14, &varg15, &varg16, &varg17, &varg18, &varg19, &varg20, &varg21, &varg22, &varg23, &varg24, &varg25, &varg26, &varg27, &varg28, &varg29, &varg30 }; + + int nArg = SAL_N_ELEMENTS( aArgsPtrArray ); + uno::Sequence< uno::Any > aArgs( nArg ); + + const uno::Any** pArg = aArgsPtrArray; + const uno::Any** pArgEnd = aArgsPtrArray + nArg; + + sal_Int32 nArgProcessed = 0; + + for ( ; pArg != pArgEnd; ++pArg, ++nArgProcessed ) + aArgs[ nArgProcessed ] = **pArg; + + // resize array to position of last param with value + aArgs.realloc( nArgProcessed + 1 ); + + uno::Any aRet; + uno::Any aDummyCaller; + executeMacro( aMacroInfo.mpDocContext, aMacroInfo.msResolvedMacro, aArgs, aRet, aDummyCaller ); + + return aRet; +} + +void SAL_CALL VbaApplicationBase::OnTime( const uno::Any& aEarliestTime, const OUString& aFunction, const uno::Any& aLatestTime, const uno::Any& aSchedule ) +{ + if ( aFunction.isEmpty() ) + throw uno::RuntimeException( "Unexpected function name!" ); + + double nEarliestTime = 0; + double nLatestTime = 0; + if ( !( aEarliestTime >>= nEarliestTime ) + || ( aLatestTime.hasValue() && !( aLatestTime >>= nLatestTime ) ) ) + throw uno::RuntimeException( "Only double is supported as time for now!" ); + + bool bSetTimer = true; + aSchedule >>= bSetTimer; + + VbaTimerInfo aTimerIndex( aFunction, ::std::pair< double, double >( nEarliestTime, nLatestTime ) ); + + VbaTimerHashMap::iterator aIter = m_pImpl->m_aTimerHash.find( aTimerIndex ); + if ( aIter != m_pImpl->m_aTimerHash.end() ) + { + m_pImpl->m_aTimerHash.erase( aIter ); + } + + if ( bSetTimer ) + { + VbaTimer* pTimer = new VbaTimer; + m_pImpl->m_aTimerHash[ aTimerIndex ].reset(pTimer); + pTimer->Start( this, aFunction, nEarliestTime, nLatestTime ); + } +} + +float SAL_CALL VbaApplicationBase::CentimetersToPoints( float Centimeters ) +{ + // i cm = 28.35 points + static const float rate = 28.35f; + return ( Centimeters * rate ); +} + +uno::Any SAL_CALL VbaApplicationBase::getVBE() +{ + try // return empty object on error + { + // "VBE" object does not have a parent, but pass document model to be able to determine application type + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= getCurrentDocument(); + uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< uno::XInterface > xVBE = xServiceManager->createInstanceWithArgumentsAndContext( + "ooo.vba.vbide.VBE" , aArgs, mxContext ); + return uno::Any( xVBE ); + } + catch( const uno::Exception& ) + { + } + return uno::Any(); +} + +OUString +VbaApplicationBase::getServiceImplName() +{ + return "VbaApplicationBase"; +} + +uno::Sequence<OUString> +VbaApplicationBase::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.VbaApplicationBase" + }; + return aServiceNames; +} + +void SAL_CALL VbaApplicationBase::Undo() +{ + uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW ); + dispatchRequests( xModel, ".uno:Undo" ); +} + +void VbaApplicationBase::Quit() +{ + // need to stop basic + SbMethod* pMeth = StarBASIC::GetActiveMethod(); + if ( pMeth ) + { + SbModule* pMod = dynamic_cast< SbModule* >( pMeth->GetParent() ); + if ( pMod ) + { + StarBASIC* pBasic = dynamic_cast< StarBASIC* >( pMod->GetParent() ); + if ( pBasic ) + pBasic->QuitAndExitApplication(); + } + } + else + { + // This is the case of a call from an (OLE) Automation client. + + // When an Automation client itself asks the process to quit, it should obey it. + AsyncQuitHandler::instance().SetForceQuit(); + + // TODO: Probably we should just close any document windows open by the "application" + // (Writer or Calc) the call being handled is for. And only then, if no document windows + // are left open, quit the actual LibreOffice application. + + Application::PostUserEvent( LINK( &AsyncQuitHandler::instance(), AsyncQuitHandler, OnAsyncQuit ) ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbacolorformat.cxx b/vbahelper/source/vbahelper/vbacolorformat.cxx new file mode 100644 index 000000000..49089f994 --- /dev/null +++ b/vbahelper/source/vbahelper/vbacolorformat.cxx @@ -0,0 +1,169 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <com/sun/star/beans/XPropertySet.hpp> +#include "vbacolorformat.hxx" + +using namespace ooo::vba; +using namespace com::sun::star; + +sal_Int32 +MsoColorIndices::getColorIndex( sal_Int32 nIndex ) +{ + const static sal_Int32 COLORINDICES[56] = + { HAPICOLOR_BLACK, HAPICOLOR_WHITE, HAPICOLOR_RED, HAPICOLOR_BRIGHTGREEN, HAPICOLOR_BLUE, HAPICOLOR_YELLOW, HAPICOLOR_PINK, + HAPICOLOR_TURQUOISE, HAPICOLOR_DARKRED, HAPICOLOR_GREEN, HAPICOLOR_DARKBLUE, HAPICOLOR_DARKYELLOW, HAPICOLOR_VIOLET, + HAPICOLOR_TEAL, HAPICOLOR_GRAY_25_PERCENT, HAPICOLOR_GRAY_50_PERCENT, HAPICOLOR_PERIWINCKLE, HAPICOLOR_PLUM, + HAPICOLOR_IVORY, HAPICOLOR_LIGHTTURQUOISE, HAPICOLOR_DARKPRUPLE, HAPICOLOR_CORAL, HAPICOLOR_OCEANBLUE, HAPICOLOR_ICEBLUE, + HAPICOLOR_GREEN, HAPICOLOR_PINK, HAPICOLOR_YELLOW, HAPICOLOR_TURQUOISE, HAPICOLOR_VIOLET, HAPICOLOR_DARKRED, HAPICOLOR_TEAL, + HAPICOLOR_BLUE, HAPICOLOR_SKYBLUE, HAPICOLOR_LIGHTTURQUOISE, HAPICOLOR_LIGHTGREEN, HAPICOLOR_LIGHTYELLOW, HAPICOLOR_PALEBLUE, + HAPICOLOR_ROSE, HAPICOLOR_LAVENDER, HAPICOLOR_TAN, HAPICOLOR_LIGHTBLUE, HAPICOLOR_AQUA, HAPICOLOR_LIME, HAPICOLOR_GOLD, + HAPICOLOR_LIGHTORANGE, HAPICOLOR_ORANGE, HAPICOLOR_BLUEGRAY, HAPICOLOR_GRAY_40_PERCENT, HAPICOLOR_DARKTEAL, + HAPICOLOR_SEAGREEN, HAPICOLOR_NONAME, HAPICOLOR_OLIVEGREEN, HAPICOLOR_BROWN, HAPICOLOR_PLUM, HAPICOLOR_INDIGO, + HAPICOLOR_GRAY_80_PERCENT + }; + return COLORINDICES[nIndex]; +} +ScVbaColorFormat::ScVbaColorFormat( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XHelperInterface >& xInternalParent, const uno::Reference< drawing::XShape >& xShape, const sal_Int16 nColorFormatType ) : ScVbaColorFormat_BASE( xParent, xContext ), m_nColorFormatType( nColorFormatType ) +{ + m_xPropertySet.set( xShape, uno::UNO_QUERY_THROW ); + m_nFillFormatBackColor = 0; + try + { + uno::Reference< ov::msforms::XFillFormat > xFillFormat( xInternalParent, uno::UNO_QUERY_THROW ); + m_pFillFormat = static_cast<ScVbaFillFormat*>( xFillFormat.get() ); + }catch ( uno::RuntimeException& ) + { + m_pFillFormat = nullptr; + } +} + +// Attribute +sal_Int32 SAL_CALL +ScVbaColorFormat::getRGB() +{ + sal_Int32 nRGB = 0; + switch( m_nColorFormatType ) + { + case ColorFormatType::LINEFORMAT_FORECOLOR: + m_xPropertySet->getPropertyValue( "LineColor" ) >>= nRGB; + break; + case ColorFormatType::LINEFORMAT_BACKCOLOR: + //TODO BackColor not supported + // m_xPropertySet->setPropertyValue("Color", uno::makeAny( nRGB ) ); + break; + case ColorFormatType::FILLFORMAT_FORECOLOR: + m_xPropertySet->getPropertyValue( "FillColor" ) >>= nRGB; + break; + case ColorFormatType::FILLFORMAT_BACKCOLOR: + nRGB = m_nFillFormatBackColor; + break; + default: + throw uno::RuntimeException( "Second parameter of ColorFormat is wrong." ); + } + nRGB = OORGBToXLRGB( Color(nRGB) ); + return nRGB; +} + +void SAL_CALL +ScVbaColorFormat::setRGB( sal_Int32 _rgb ) +{ + sal_Int32 nRGB = XLRGBToOORGB( _rgb ); + switch( m_nColorFormatType ) + { + case ColorFormatType::LINEFORMAT_FORECOLOR: + m_xPropertySet->setPropertyValue( "LineColor" , uno::makeAny( nRGB ) ); + break; + case ColorFormatType::LINEFORMAT_BACKCOLOR: + // TODO BackColor not supported + break; + case ColorFormatType::FILLFORMAT_FORECOLOR: + m_xPropertySet->setPropertyValue( "FillColor" , uno::makeAny( nRGB ) ); + if( m_pFillFormat ) + { + m_pFillFormat->setForeColorAndInternalStyle(nRGB); + } + break; + case ColorFormatType::FILLFORMAT_BACKCOLOR: + m_nFillFormatBackColor = nRGB; + if( m_pFillFormat ) + { + m_pFillFormat->setForeColorAndInternalStyle(nRGB); + } + break; + default: + throw uno::RuntimeException( "Second parameter of ColorFormat is wrong." ); + } +} + +sal_Int32 SAL_CALL +ScVbaColorFormat::getSchemeColor() +{ + sal_Int32 nColor = getRGB(); + // #TODO I guess the number of elements is determined by the correct scheme + // the implementation here seems to be a rehash of color index ( which seems to be a + // different thing ) - I would guess we need to know/import etc. the correct color scheme + // or at least find out a little more + sal_Int32 i = 0; + for( ; i < 56; i++ ) + { + if( nColor == MsoColorIndices::getColorIndex(i) ) + break; + } + + if( i == 56 ) // this is most likely an error condition + --i; + return i; + // #TODO figure out what craziness is this, + // the 56 colors seems incorrect, as in default XL ( 2003 ) there are 80 colors +/* + if( i == 56 ) + { + i = -2; + } + + return ( i + 2 ); +*/ +} + +void SAL_CALL +ScVbaColorFormat::setSchemeColor( sal_Int32 _schemecolor ) +{ + // the table is 0 based + sal_Int32 nColor = MsoColorIndices::getColorIndex( _schemecolor ); + // nColor is already xl RGB + setRGB( nColor ); +} + +OUString +ScVbaColorFormat::getServiceImplName() +{ + return "ScVbaColorFormat"; +} + +uno::Sequence< OUString > +ScVbaColorFormat::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.ColorFormat" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbacolorformat.hxx b/vbahelper/source/vbahelper/vbacolorformat.hxx new file mode 100644 index 000000000..0e94db6de --- /dev/null +++ b/vbahelper/source/vbahelper/vbacolorformat.hxx @@ -0,0 +1,115 @@ +/* -*- 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_VBAHELPER_SOURCE_VBAHELPER_VBACOLORFORMAT_HXX +#define INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOLORFORMAT_HXX + +#include <com/sun/star/drawing/XShape.hpp> +#include <ooo/vba/msforms/XColorFormat.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include "vbafillformat.hxx" + +typedef InheritedHelperInterfaceWeakImpl< ov::msforms::XColorFormat > ScVbaColorFormat_BASE; + +class ColorFormatType +{ +public: + const static sal_Int16 LINEFORMAT_FORECOLOR = 1; + const static sal_Int16 LINEFORMAT_BACKCOLOR = 2; + const static sal_Int16 FILLFORMAT_FORECOLOR = 3; + const static sal_Int16 FILLFORMAT_BACKCOLOR = 4; + const static sal_Int16 THREEDFORMAT_EXTRUSIONCOLOR = 5; +}; + +struct MsoColorIndices +{ + const static sal_Int32 HAPICOLOR_BLACK = 0; + const static sal_Int32 HAPICOLOR_WHITE = 16777215; + const static sal_Int32 HAPICOLOR_RED = 16711680; + const static sal_Int32 HAPICOLOR_BRIGHTGREEN = 65280; + const static sal_Int32 HAPICOLOR_BLUE = 255; + const static sal_Int32 HAPICOLOR_YELLOW = 16776960; + const static sal_Int32 HAPICOLOR_PINK = 16711935; + const static sal_Int32 HAPICOLOR_TURQUOISE = 65535; + const static sal_Int32 HAPICOLOR_DARKRED = 8388608; + const static sal_Int32 HAPICOLOR_GREEN = 32768; + const static sal_Int32 HAPICOLOR_DARKBLUE = 128; + const static sal_Int32 HAPICOLOR_DARKYELLOW = 8421376; + const static sal_Int32 HAPICOLOR_VIOLET = 8388736; + const static sal_Int32 HAPICOLOR_TEAL = 32896; + const static sal_Int32 HAPICOLOR_GRAY_25_PERCENT = 12632256; + const static sal_Int32 HAPICOLOR_GRAY_50_PERCENT = 8421504; + const static sal_Int32 HAPICOLOR_PERIWINCKLE = 10066431; + const static sal_Int32 HAPICOLOR_PLUM = 10040166; + const static sal_Int32 HAPICOLOR_IVORY = 16777164; + const static sal_Int32 HAPICOLOR_LIGHTTURQUOISE = 13434879; + const static sal_Int32 HAPICOLOR_DARKPRUPLE = 6684774; + const static sal_Int32 HAPICOLOR_CORAL = 16744576; + const static sal_Int32 HAPICOLOR_OCEANBLUE = 26316; + const static sal_Int32 HAPICOLOR_ICEBLUE = 13421823; + const static sal_Int32 HAPICOLOR_SKYBLUE = 52479; + const static sal_Int32 HAPICOLOR_LIGHTGREEN = 13434828; + const static sal_Int32 HAPICOLOR_LIGHTYELLOW = 16777113; + const static sal_Int32 HAPICOLOR_PALEBLUE = 10079487; + const static sal_Int32 HAPICOLOR_ROSE = 16751052; + const static sal_Int32 HAPICOLOR_LAVENDER = 13408767; + const static sal_Int32 HAPICOLOR_TAN = 16764057; + const static sal_Int32 HAPICOLOR_LIGHTBLUE = 3368703; + const static sal_Int32 HAPICOLOR_AQUA = 3394764; + const static sal_Int32 HAPICOLOR_LIME = 10079232; + const static sal_Int32 HAPICOLOR_GOLD = 16763904; + const static sal_Int32 HAPICOLOR_LIGHTORANGE = 16750848; + const static sal_Int32 HAPICOLOR_ORANGE = 16737792; + const static sal_Int32 HAPICOLOR_BLUEGRAY = 6710937; + const static sal_Int32 HAPICOLOR_GRAY_40_PERCENT = 9868950; + const static sal_Int32 HAPICOLOR_DARKTEAL = 13158; + const static sal_Int32 HAPICOLOR_SEAGREEN = 3381606; + const static sal_Int32 HAPICOLOR_NONAME = 13056; + const static sal_Int32 HAPICOLOR_OLIVEGREEN = 3355392; + const static sal_Int32 HAPICOLOR_BROWN = 10040064; + const static sal_Int32 HAPICOLOR_INDIGO = 3355545; + const static sal_Int32 HAPICOLOR_GRAY_80_PERCENT = 3355443; + + static sal_Int32 getColorIndex( sal_Int32 nIndex ); + +}; + +class ScVbaColorFormat : public ScVbaColorFormat_BASE +{ +private: + css::uno::Reference< css::beans::XPropertySet > m_xPropertySet; + ScVbaFillFormat *m_pFillFormat; + sal_Int16 m_nColorFormatType; + sal_Int32 m_nFillFormatBackColor; +protected: + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +public: + ScVbaColorFormat( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< ov::XHelperInterface >& xInternalParent, const css::uno::Reference< css::drawing::XShape >& xShape, const sal_Int16 nColorFormatType ); + + // Attributes + virtual sal_Int32 SAL_CALL getRGB() override; + virtual void SAL_CALL setRGB( sal_Int32 _rgb ) override; + virtual sal_Int32 SAL_CALL getSchemeColor() override; + virtual void SAL_CALL setSchemeColor( sal_Int32 _schemecolor ) override; + +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOLORFORMAT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbacommandbar.cxx b/vbahelper/source/vbahelper/vbacommandbar.cxx new file mode 100644 index 000000000..b9cb17e62 --- /dev/null +++ b/vbahelper/source/vbahelper/vbacommandbar.cxx @@ -0,0 +1,273 @@ +/* -*- 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 "vbacommandbar.hxx" +#include "vbacommandbarcontrols.hxx" +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <ooo/vba/office/MsoBarType.hpp> +#include <sal/log.hxx> + +using namespace com::sun::star; +using namespace ooo::vba; + +ScVbaCommandBar::ScVbaCommandBar( const uno::Reference< ov::XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + VbaCommandBarHelperRef const & pHelper, + const uno::Reference< container::XIndexAccess >& xBarSettings, + const OUString& sResourceUrl, bool bIsMenu ) + : CommandBar_BASE( xParent, xContext ), pCBarHelper( pHelper ), m_xBarSettings( xBarSettings ), m_sResourceUrl( sResourceUrl ), m_bIsMenu( bIsMenu ) +{ +} + +OUString SAL_CALL +ScVbaCommandBar::getName() +{ + // This will get a "NULL length string" when Name is not set. + uno::Reference< beans::XPropertySet > xPropertySet( m_xBarSettings, uno::UNO_QUERY_THROW ); + uno::Any aName = xPropertySet->getPropertyValue( "UIName" ); + OUString sName; + aName >>= sName; + if( sName.isEmpty() ) + { + if( m_bIsMenu ) + { + if( m_sResourceUrl == ITEM_MENUBAR_URL ) + { + if( pCBarHelper->getModuleId() == "com.sun.star.sheet.SpreadsheetDocument" ) + sName = "Worksheet Menu Bar"; + else if( pCBarHelper->getModuleId() == "com.sun.star.text.TextDocument" ) + sName = "Menu Bar"; + return sName; + } + } + // Toolbar name + uno::Reference< container::XNameAccess > xNameAccess = pCBarHelper->getPersistentWindowState(); + if( xNameAccess->hasByName( m_sResourceUrl ) ) + { + uno::Sequence< beans::PropertyValue > aToolBar; + xNameAccess->getByName( m_sResourceUrl ) >>= aToolBar; + getPropertyValue( aToolBar, "UIName" ) >>= sName; + } + } + return sName; +} +void SAL_CALL +ScVbaCommandBar::setName( const OUString& _name ) +{ + uno::Reference< beans::XPropertySet > xPropertySet( m_xBarSettings, uno::UNO_QUERY_THROW ); + xPropertySet->setPropertyValue( "UIName" , uno::makeAny( _name ) ); + + pCBarHelper->ApplyTempChange( m_sResourceUrl, m_xBarSettings ); +} +sal_Bool SAL_CALL +ScVbaCommandBar::getVisible() +{ + // menu bar is always visible in OOo + if( m_bIsMenu ) + return true; + + bool bVisible = false; + try + { + uno::Reference< container::XNameAccess > xNameAccess = pCBarHelper->getPersistentWindowState(); + if( xNameAccess->hasByName( m_sResourceUrl ) ) + { + uno::Sequence< beans::PropertyValue > aToolBar; + xNameAccess->getByName( m_sResourceUrl ) >>= aToolBar; + getPropertyValue( aToolBar, "Visible" ) >>= bVisible; + } + } + catch (const uno::Exception&) + { + } + return bVisible; +} +void SAL_CALL +ScVbaCommandBar::setVisible( sal_Bool _visible ) +{ + try + { + uno::Reference< frame::XLayoutManager > xLayoutManager = pCBarHelper->getLayoutManager(); + if( _visible ) + { + xLayoutManager->createElement( m_sResourceUrl ); + xLayoutManager->showElement( m_sResourceUrl ); + } + else + { + xLayoutManager->hideElement( m_sResourceUrl ); + xLayoutManager->destroyElement( m_sResourceUrl ); + } + } + catch(const uno::Exception&) + { + SAL_INFO("vbahelper", "SetVisible get an exception" ); + } +} + +sal_Bool SAL_CALL +ScVbaCommandBar::getEnabled() +{ + // emulated with Visible + return getVisible(); +} + +void SAL_CALL +ScVbaCommandBar::setEnabled( sal_Bool _enabled ) +{ + // emulated with Visible + setVisible( _enabled ); +} + +void SAL_CALL +ScVbaCommandBar::Delete( ) +{ + pCBarHelper->removeSettings( m_sResourceUrl ); + uno::Reference< container::XNameContainer > xNameContainer( pCBarHelper->getPersistentWindowState(), uno::UNO_QUERY_THROW ); + if( xNameContainer->hasByName( m_sResourceUrl ) ) + { + xNameContainer->removeByName( m_sResourceUrl ); + } +} +uno::Any SAL_CALL +ScVbaCommandBar::Controls( const uno::Any& aIndex ) +{ + uno::Reference< XCommandBarControls > xCommandBarControls( new ScVbaCommandBarControls( this, mxContext, m_xBarSettings, pCBarHelper, m_xBarSettings, m_sResourceUrl ) ); + if( aIndex.hasValue() ) + { + return xCommandBarControls->Item( aIndex, uno::Any() ); + } + return uno::makeAny( xCommandBarControls ); +} + +sal_Int32 SAL_CALL +ScVbaCommandBar::Type() +{ + // #FIXME support msoBarTypePopup + sal_Int32 nType + = m_bIsMenu ? office::MsoBarType::msoBarTypeNormal : office::MsoBarType::msoBarTypeMenuBar; + return nType; +} + +uno::Any SAL_CALL +ScVbaCommandBar::FindControl( const uno::Any& /*aType*/, const uno::Any& /*aId*/, const uno::Any& /*aTag*/, const uno::Any& /*aVisible*/, const uno::Any& /*aRecursive*/ ) +{ + // alwayse fail to find control + return uno::makeAny( uno::Reference< XCommandBarControl > () ); +} + +OUString +ScVbaCommandBar::getServiceImplName() +{ + return "ScVbaCommandBar"; +} + +uno::Sequence<OUString> +ScVbaCommandBar::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.CommandBar" + }; + return aServiceNames; +} + + +VbaDummyCommandBar::VbaDummyCommandBar( + const uno::Reference< ov::XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const OUString& rName ) : + CommandBar_BASE( xParent, xContext ), + maName( rName ) +{ +} + +OUString SAL_CALL VbaDummyCommandBar::getName() +{ + return maName; +} + +void SAL_CALL VbaDummyCommandBar::setName( const OUString& _name ) +{ + maName = _name; +} + +sal_Bool SAL_CALL VbaDummyCommandBar::getVisible() +{ + // #STUB + return true; +} + +void SAL_CALL VbaDummyCommandBar::setVisible( sal_Bool /*_visible*/ ) +{ + // #STUB +} + +sal_Bool SAL_CALL VbaDummyCommandBar::getEnabled() +{ + // emulated with Visible + return getVisible(); +} + +void SAL_CALL VbaDummyCommandBar::setEnabled( sal_Bool _enabled ) +{ + // emulated with Visible + setVisible( _enabled ); +} + +void SAL_CALL VbaDummyCommandBar::Delete( ) +{ + // no-op + // #STUB +} + +uno::Any SAL_CALL VbaDummyCommandBar::Controls( const uno::Any& aIndex ) +{ + uno::Reference< XCommandBarControls > xCommandBarControls( new VbaDummyCommandBarControls( this, mxContext ) ); + if( aIndex.hasValue() ) + return xCommandBarControls->Item( aIndex, uno::Any() ); + return uno::Any( xCommandBarControls ); +} + +sal_Int32 SAL_CALL VbaDummyCommandBar::Type() +{ + return office::MsoBarType::msoBarTypePopup; +} + +uno::Any SAL_CALL VbaDummyCommandBar::FindControl( const uno::Any& /*aType*/, const uno::Any& /*aId*/, const uno::Any& /*aTag*/, const uno::Any& /*aVisible*/, const uno::Any& /*aRecursive*/ ) +{ + return uno::Any( uno::Reference< XCommandBarControl >() ); +} + +OUString VbaDummyCommandBar::getServiceImplName() +{ + return "VbaDummyCommandBar"; +} + +uno::Sequence< OUString > VbaDummyCommandBar::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.CommandBar" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbacommandbar.hxx b/vbahelper/source/vbahelper/vbacommandbar.hxx new file mode 100644 index 000000000..8aa9675ad --- /dev/null +++ b/vbahelper/source/vbahelper/vbacommandbar.hxx @@ -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 . + */ +#ifndef INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBAR_HXX +#define INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBAR_HXX + +#include <ooo/vba/XCommandBar.hpp> + +#include <vbahelper/vbahelperinterface.hxx> +#include "vbacommandbarhelper.hxx" + +typedef InheritedHelperInterfaceWeakImpl< ov::XCommandBar > CommandBar_BASE; + +class ScVbaCommandBar : public CommandBar_BASE +{ +private: + VbaCommandBarHelperRef pCBarHelper; + css::uno::Reference< css::container::XIndexAccess > m_xBarSettings; + OUString m_sResourceUrl; + bool m_bIsMenu; + +public: + /// @throws css::uno::RuntimeException + ScVbaCommandBar( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, VbaCommandBarHelperRef const & pHelper, const css::uno::Reference< css::container::XIndexAccess >& xBarSettings, const OUString& sResourceUrl, bool bIsMenu ); + + // Attributes + virtual OUString SAL_CALL getName() override; + virtual void SAL_CALL setName( const OUString& _name ) override; + virtual sal_Bool SAL_CALL getVisible() override; + virtual void SAL_CALL setVisible( sal_Bool _visible ) override; + virtual sal_Bool SAL_CALL getEnabled() override; + virtual void SAL_CALL setEnabled( sal_Bool _enabled ) override; + + // Methods + virtual void SAL_CALL Delete( ) override; + virtual css::uno::Any SAL_CALL Controls( const css::uno::Any& aIndex ) override; + virtual sal_Int32 SAL_CALL Type( ) override; + virtual css::uno::Any SAL_CALL FindControl( const css::uno::Any& aType, const css::uno::Any& aId, const css::uno::Any& aTag, const css::uno::Any& aVisible, const css::uno::Any& aRecursive ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +/** Dummy command bar implementation. Does nothing but provide its name. */ +class VbaDummyCommandBar : public CommandBar_BASE +{ +public: + /// @throws css::uno::RuntimeException + VbaDummyCommandBar( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const OUString& rName ); + + // Attributes + virtual OUString SAL_CALL getName() override; + virtual void SAL_CALL setName( const OUString& _name ) override; + virtual sal_Bool SAL_CALL getVisible() override; + virtual void SAL_CALL setVisible( sal_Bool _visible ) override; + virtual sal_Bool SAL_CALL getEnabled() override; + virtual void SAL_CALL setEnabled( sal_Bool _enabled ) override; + + // Methods + virtual void SAL_CALL Delete( ) override; + virtual css::uno::Any SAL_CALL Controls( const css::uno::Any& aIndex ) override; + virtual sal_Int32 SAL_CALL Type( ) override; + virtual css::uno::Any SAL_CALL FindControl( const css::uno::Any& aType, const css::uno::Any& aId, const css::uno::Any& aTag, const css::uno::Any& aVisible, const css::uno::Any& aRecursive ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + +private: + OUString maName; +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBAR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbacommandbarcontrol.cxx b/vbahelper/source/vbahelper/vbacommandbarcontrol.cxx new file mode 100644 index 000000000..d7220f071 --- /dev/null +++ b/vbahelper/source/vbahelper/vbacommandbarcontrol.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/. + * + * 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 "vbacommandbarcontrol.hxx" +#include "vbacommandbarcontrols.hxx" +#include <vbahelper/vbahelper.hxx> +#include <filter/msfilter/msvbahelper.hxx> +#include <sal/log.hxx> + +using namespace com::sun::star; +using namespace ooo::vba; + +ScVbaCommandBarControl::ScVbaCommandBarControl( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xSettings, const VbaCommandBarHelperRef& pHelper, const css::uno::Reference< css::container::XIndexAccess >& xBarSettings, const OUString& sResourceUrl ) : CommandBarControl_BASE( xParent, xContext ), pCBarHelper( pHelper ), m_sResourceUrl( sResourceUrl ), m_xCurrentSettings( xSettings ), m_xBarSettings( xBarSettings ), m_nPosition( 0 ) +{ +} + +void ScVbaCommandBarControl::ApplyChange() +{ + uno::Reference< container::XIndexContainer > xIndexContainer( m_xCurrentSettings, uno::UNO_QUERY_THROW ); + xIndexContainer->replaceByIndex( m_nPosition, uno::makeAny( m_aPropertyValues ) ); + pCBarHelper->ApplyTempChange( m_sResourceUrl, m_xBarSettings ); +} + +OUString SAL_CALL +ScVbaCommandBarControl::getCaption() +{ + // "Label" always empty + OUString sCaption; + getPropertyValue( m_aPropertyValues, "Label" ) >>= sCaption; + return sCaption; +} + +void SAL_CALL +ScVbaCommandBarControl::setCaption( const OUString& _caption ) +{ + OUString sCaption = _caption.replace('&','~'); + setPropertyValue( m_aPropertyValues, "Label" , uno::makeAny( sCaption ) ); + ApplyChange(); +} + +OUString SAL_CALL +ScVbaCommandBarControl::getOnAction() +{ + OUString sCommandURL; + getPropertyValue( m_aPropertyValues, "CommandURL" ) >>= sCommandURL; + return sCommandURL; +} + +void SAL_CALL +ScVbaCommandBarControl::setOnAction( const OUString& _onaction ) +{ + // get the current model + uno::Reference< frame::XModel > xModel( pCBarHelper->getModel() ); + MacroResolvedInfo aResolvedMacro = ooo::vba::resolveVBAMacro( getSfxObjShell( xModel ), _onaction, true ); + if ( aResolvedMacro.mbFound ) + { + OUString aCommandURL = ooo::vba::makeMacroURL( aResolvedMacro.msResolvedMacro ); + SAL_INFO("vbahelper", "ScVbaCommandBarControl::setOnAction: " << aCommandURL); + setPropertyValue( m_aPropertyValues, "CommandURL" , uno::makeAny( aCommandURL ) ); + ApplyChange(); + } +} + +sal_Bool SAL_CALL +ScVbaCommandBarControl::getVisible() +{ + bool bVisible = true; + uno::Any aValue = getPropertyValue( m_aPropertyValues, ITEM_DESCRIPTOR_ISVISIBLE ); + if( aValue.hasValue() ) + aValue >>= bVisible; + return bVisible; +} +void SAL_CALL +ScVbaCommandBarControl::setVisible( sal_Bool _visible ) +{ + uno::Any aValue = getPropertyValue( m_aPropertyValues, ITEM_DESCRIPTOR_ISVISIBLE ); + if( aValue.hasValue() ) + { + setPropertyValue( m_aPropertyValues, ITEM_DESCRIPTOR_ISVISIBLE , uno::makeAny( _visible ) ); + ApplyChange(); + } +} + +sal_Bool SAL_CALL +ScVbaCommandBarControl::getEnabled() +{ + bool bEnabled = true; + + uno::Any aValue = getPropertyValue( m_aPropertyValues, ITEM_DESCRIPTOR_ENABLED ); + if( aValue.hasValue() ) + { + aValue >>= bEnabled; + } + else + { + // emulated with Visible + bEnabled = getVisible(); + } + return bEnabled; +} + +void SAL_CALL +ScVbaCommandBarControl::setEnabled( sal_Bool _enabled ) +{ + uno::Any aValue = getPropertyValue( m_aPropertyValues, ITEM_DESCRIPTOR_ENABLED ); + if( aValue.hasValue() ) + { + setPropertyValue( m_aPropertyValues, ITEM_DESCRIPTOR_ENABLED , uno::makeAny( _enabled ) ); + ApplyChange(); + } + else + { + // emulated with Visible + setVisible( _enabled ); + } +} + +sal_Bool SAL_CALL +ScVbaCommandBarControl::getBeginGroup() +{ + // TODO: need to check if the item before this item is of type 'separator' + //#STUB + return false; +} + +void SAL_CALL +ScVbaCommandBarControl::setBeginGroup( sal_Bool _begin ) +{ + if( getBeginGroup() != _begin ) + { + // TODO: need to insert or remove an item of type 'separator' before this item + } +} + +void SAL_CALL +ScVbaCommandBarControl::Delete( ) +{ + if( m_xCurrentSettings.is() ) + { + uno::Reference< container::XIndexContainer > xIndexContainer( m_xCurrentSettings, uno::UNO_QUERY_THROW ); + xIndexContainer->removeByIndex( m_nPosition ); + + pCBarHelper->ApplyTempChange( m_sResourceUrl, m_xBarSettings ); + } +} + +uno::Any SAL_CALL +ScVbaCommandBarControl::Controls( const uno::Any& aIndex ) +{ + // only Popup Menu has controls + uno::Reference< container::XIndexAccess > xSubMenu; + getPropertyValue( m_aPropertyValues, ITEM_DESCRIPTOR_CONTAINER ) >>= xSubMenu; + if( !xSubMenu.is() ) + throw uno::RuntimeException(); + + uno::Reference< XCommandBarControls > xCommandBarControls( new ScVbaCommandBarControls( this, mxContext, xSubMenu, pCBarHelper, m_xBarSettings, m_sResourceUrl ) ); + if( aIndex.hasValue() ) + { + return xCommandBarControls->Item( aIndex, uno::Any() ); + } + return uno::makeAny( xCommandBarControls ); +} + +OUString +ScVbaCommandBarControl::getServiceImplName() +{ + return "ScVbaCommandBarControl"; +} + +uno::Sequence<OUString> +ScVbaCommandBarControl::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.CommandBarControl" + }; + return aServiceNames; +} + +// ScVbaCommandBarPopup +ScVbaCommandBarPopup::ScVbaCommandBarPopup( const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::container::XIndexAccess >& xSettings, + const VbaCommandBarHelperRef& pHelper, + const css::uno::Reference< css::container::XIndexAccess >& xBarSettings, + const OUString& sResourceUrl, + sal_Int32 nPosition ) + : CommandBarPopup_BASE( xParent, xContext, xSettings, pHelper, xBarSettings, sResourceUrl ) +{ + m_nPosition = nPosition; + m_xCurrentSettings->getByIndex( m_nPosition ) >>= m_aPropertyValues; +} + +OUString +ScVbaCommandBarPopup::getServiceImplName() +{ + return "ScVbaCommandBarPopup"; +} + +uno::Sequence<OUString> +ScVbaCommandBarPopup::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.CommandBarPopup" + }; + return aServiceNames; +} + +// ScVbaCommandBarButton +ScVbaCommandBarButton::ScVbaCommandBarButton( const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::container::XIndexAccess >& xSettings, + const VbaCommandBarHelperRef& pHelper, + const css::uno::Reference< css::container::XIndexAccess >& xBarSettings, + const OUString& sResourceUrl, + sal_Int32 nPosition ) + : CommandBarButton_BASE( xParent, xContext, xSettings, pHelper, xBarSettings, sResourceUrl ) +{ + m_nPosition = nPosition; + m_xCurrentSettings->getByIndex( m_nPosition ) >>= m_aPropertyValues; +} + +OUString +ScVbaCommandBarButton::getServiceImplName() +{ + return "ScVbaCommandBarButton"; +} + +uno::Sequence<OUString> +ScVbaCommandBarButton::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.CommandBarButton" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbacommandbarcontrol.hxx b/vbahelper/source/vbahelper/vbacommandbarcontrol.hxx new file mode 100644 index 000000000..348518b5b --- /dev/null +++ b/vbahelper/source/vbahelper/vbacommandbarcontrol.hxx @@ -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 . + */ +#ifndef INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBARCONTROL_HXX +#define INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBARCONTROL_HXX + +#include <ooo/vba/XCommandBarControl.hpp> +#include <ooo/vba/XCommandBarPopup.hpp> +#include <ooo/vba/XCommandBarButton.hpp> +#include <ooo/vba/office/MsoControlType.hpp> +#include <com/sun/star/awt/XMenu.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include "vbacommandbarhelper.hxx" +#include <cppuhelper/implbase.hxx> + +typedef InheritedHelperInterfaceWeakImpl< ov::XCommandBarControl > CommandBarControl_BASE; + +class ScVbaCommandBarControl : public CommandBarControl_BASE +{ +protected: + VbaCommandBarHelperRef pCBarHelper; + OUString m_sResourceUrl; + css::uno::Reference< css::container::XIndexAccess > m_xCurrentSettings; + css::uno::Reference< css::container::XIndexAccess > m_xBarSettings; + css::uno::Sequence< css::beans::PropertyValue > m_aPropertyValues; + + sal_Int32 m_nPosition; + +private: + /// @throws css::uno::RuntimeException + void ApplyChange(); + +public: + /// @throws css::uno::RuntimeException + ScVbaCommandBarControl( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xSettings, const VbaCommandBarHelperRef& pHelper, const css::uno::Reference< css::container::XIndexAccess >& xBarSettings, const OUString& sResourceUrl ); + + // Attributes + virtual OUString SAL_CALL getCaption() override; + virtual void SAL_CALL setCaption( const OUString& _caption ) override; + virtual OUString SAL_CALL getOnAction() override; + virtual void SAL_CALL setOnAction( const OUString& _onaction ) override; + virtual sal_Bool SAL_CALL getVisible() override; + virtual void SAL_CALL setVisible( sal_Bool _visible ) override; + virtual sal_Bool SAL_CALL getEnabled() override; + virtual void SAL_CALL setEnabled( sal_Bool _enabled ) override; + virtual sal_Bool SAL_CALL getBeginGroup() override; + virtual void SAL_CALL setBeginGroup( sal_Bool _begin ) override; + virtual sal_Int32 SAL_CALL getType() override + { + return ov::office::MsoControlType::msoControlButton; + } + + // Methods + virtual void SAL_CALL Delete( ) override; + virtual css::uno::Any SAL_CALL Controls( const css::uno::Any& aIndex ) override; + + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +typedef cppu::ImplInheritanceHelper< ScVbaCommandBarControl, ov::XCommandBarPopup > CommandBarPopup_BASE; +class ScVbaCommandBarPopup : public CommandBarPopup_BASE +{ +public: + /// @throws css::uno::RuntimeException + ScVbaCommandBarPopup( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xSettings, const VbaCommandBarHelperRef& pHelper, const css::uno::Reference< css::container::XIndexAccess >& xBarSettings, const OUString& sResourceUrl, sal_Int32 nPosition ); + + virtual sal_Int32 SAL_CALL getType() override + { + return ov::office::MsoControlType::msoControlPopup; + } + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +typedef cppu::ImplInheritanceHelper< ScVbaCommandBarControl, ov::XCommandBarButton > CommandBarButton_BASE; +class ScVbaCommandBarButton : public CommandBarButton_BASE +{ +public: + /// @throws css::uno::RuntimeException + ScVbaCommandBarButton( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xSettings, const VbaCommandBarHelperRef& pHelper, const css::uno::Reference< css::container::XIndexAccess >& xBarSettings, const OUString& sResourceUrl, sal_Int32 nPosition ); + + virtual sal_Int32 SAL_CALL getType() override + { + return ov::office::MsoControlType::msoControlButton; + } + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBARCONTROL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbacommandbarcontrols.cxx b/vbahelper/source/vbahelper/vbacommandbarcontrols.cxx new file mode 100644 index 000000000..cb83e51c8 --- /dev/null +++ b/vbahelper/source/vbahelper/vbacommandbarcontrols.cxx @@ -0,0 +1,320 @@ +/* -*- 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 "vbacommandbarcontrols.hxx" +#include "vbacommandbarcontrol.hxx" +#include <com/sun/star/lang/XSingleComponentFactory.hpp> + +using namespace com::sun::star; +using namespace ooo::vba; + +namespace { + +class CommandBarControlEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration > +{ + //uno::Reference< uno::XComponentContext > m_xContext; + CommandBarControls_BASE* m_pCommandBarControls; + sal_Int32 m_nCurrentPosition; +public: + explicit CommandBarControlEnumeration( CommandBarControls_BASE* pCommandBarControls ) : m_pCommandBarControls( pCommandBarControls ), m_nCurrentPosition( 0 ) {} + virtual sal_Bool SAL_CALL hasMoreElements() override + { + if( m_nCurrentPosition < m_pCommandBarControls->getCount() ) + return true; + return false; + } + virtual uno::Any SAL_CALL nextElement() override + { + if( !hasMoreElements() ) + throw container::NoSuchElementException(); + + return m_pCommandBarControls->createCollectionObject( uno::makeAny( m_nCurrentPosition++ ) ); + } +}; + +} + +ScVbaCommandBarControls::ScVbaCommandBarControls( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess>& xIndexAccess, VbaCommandBarHelperRef const & pHelper, const uno::Reference< container::XIndexAccess>& xBarSettings, const OUString& sResourceUrl ) : CommandBarControls_BASE( xParent, xContext, xIndexAccess ), pCBarHelper( pHelper ), m_xBarSettings( xBarSettings ), m_sResourceUrl( sResourceUrl ) +{ + m_bIsMenu = sResourceUrl == ITEM_MENUBAR_URL; +} + +uno::Sequence< beans::PropertyValue > ScVbaCommandBarControls::CreateMenuItemData( const OUString& sCommandURL, + const OUString& sHelpURL, + const OUString& sLabel, + sal_uInt16 nType, + const uno::Any& aSubMenu, + bool isVisible, + bool isEnabled ) +{ + uno::Sequence< beans::PropertyValue > aProps(7); + + aProps[0].Name = ITEM_DESCRIPTOR_COMMANDURL; + aProps[0].Value <<= sCommandURL; + aProps[1].Name = ITEM_DESCRIPTOR_HELPURL; + aProps[1].Value <<= sHelpURL; + aProps[2].Name = ITEM_DESCRIPTOR_LABEL; + aProps[2].Value <<= sLabel; + aProps[3].Name = ITEM_DESCRIPTOR_TYPE; + aProps[3].Value <<= nType; + aProps[4].Name = ITEM_DESCRIPTOR_CONTAINER; + aProps[4].Value = aSubMenu; + aProps[5].Name = ITEM_DESCRIPTOR_ISVISIBLE; + aProps[5].Value <<= isVisible; + aProps[6].Name = ITEM_DESCRIPTOR_ENABLED; + aProps[6].Value <<= isEnabled; + + return aProps; +} + +uno::Sequence< beans::PropertyValue > ScVbaCommandBarControls::CreateToolbarItemData( const OUString& sCommandURL, + const OUString& sHelpURL, + const OUString& sLabel, + sal_uInt16 nType, + const uno::Any& aSubMenu, + bool isVisible, + sal_Int32 nStyle ) +{ + uno::Sequence< beans::PropertyValue > aProps(7); + + aProps[0].Name = ITEM_DESCRIPTOR_COMMANDURL; + aProps[0].Value <<= sCommandURL; + aProps[1].Name = ITEM_DESCRIPTOR_HELPURL; + aProps[1].Value <<= sHelpURL; + aProps[2].Name = ITEM_DESCRIPTOR_LABEL; + aProps[2].Value <<= sLabel; + aProps[3].Name = ITEM_DESCRIPTOR_TYPE; + aProps[3].Value <<= nType; + aProps[4].Name = ITEM_DESCRIPTOR_CONTAINER; + aProps[4].Value = aSubMenu; + aProps[5].Name = ITEM_DESCRIPTOR_ISVISIBLE; + aProps[5].Value <<= isVisible; + aProps[6].Name = ITEM_DESCRIPTOR_STYLE; + aProps[6].Value <<= nStyle; + + return aProps; +} + +// XEnumerationAccess +uno::Type SAL_CALL +ScVbaCommandBarControls::getElementType() +{ + return cppu::UnoType<XCommandBarControl>::get(); +} + +uno::Reference< container::XEnumeration > +ScVbaCommandBarControls::createEnumeration() +{ + return uno::Reference< container::XEnumeration >( new CommandBarControlEnumeration( this ) ); +} + +uno::Any +ScVbaCommandBarControls::createCollectionObject( const uno::Any& aSource ) +{ + sal_Int32 nPosition = -1; + aSource >>= nPosition; + uno::Sequence< beans::PropertyValue > aProps; + m_xIndexAccess->getByIndex( nPosition ) >>= aProps; + uno::Reference< container::XIndexAccess > xSubMenu; + getPropertyValue( aProps, ITEM_DESCRIPTOR_CONTAINER ) >>= xSubMenu; + ScVbaCommandBarControl* pNewCommandBarControl = nullptr; + if( xSubMenu.is() ) + pNewCommandBarControl = new ScVbaCommandBarPopup( this, mxContext, m_xIndexAccess, pCBarHelper, m_xBarSettings, m_sResourceUrl, nPosition ); + else + pNewCommandBarControl = new ScVbaCommandBarButton( this, mxContext, m_xIndexAccess, pCBarHelper, m_xBarSettings, m_sResourceUrl, nPosition ); + + return uno::makeAny( uno::Reference< XCommandBarControl > ( pNewCommandBarControl ) ); +} + +// Methods +uno::Any SAL_CALL +ScVbaCommandBarControls::Item( const uno::Any& aIndex, const uno::Any& /*aIndex*/ ) +{ + sal_Int32 nPosition = -1; + if( aIndex.getValueTypeClass() == uno::TypeClass_STRING ) + { + OUString sName; + aIndex >>= sName; + nPosition = VbaCommandBarHelper::findControlByName( m_xIndexAccess, sName, m_bIsMenu ); + } + else + { + aIndex >>= nPosition; + } + + if( nPosition < 0 || nPosition >= getCount() ) + { + throw uno::RuntimeException(); + } + + return createCollectionObject( uno::makeAny( nPosition ) ); +} + +uno::Reference< XCommandBarControl > SAL_CALL +ScVbaCommandBarControls::Add( const uno::Any& Type, const uno::Any& Id, const uno::Any& Parameter, const uno::Any& Before, SAL_UNUSED_PARAMETER const uno::Any& ) +{ + // Parameter is not supported + // the following name needs to be individually created; + OUString sLabel("Custom"); + OUString sCommandUrl( CUSTOM_MENU_STR + sLabel); + sal_Int32 nType = office::MsoControlType::msoControlButton; + sal_Int32 nPosition = 0; + + if( Type.hasValue() ) + { + Type >>= nType; + } + + if( nType != office::MsoControlType::msoControlButton && + nType != office::MsoControlType::msoControlPopup ) + throw uno::RuntimeException( "Not implemented" ); + + if( Id.hasValue() || Parameter.hasValue( ) ) + { + throw uno::RuntimeException( "Not implemented" ); + } + + if( Before.hasValue() ) + Before >>= nPosition; + else + nPosition = m_xIndexAccess->getCount(); + + uno::Any aSubMenu; + if( nType == office::MsoControlType::msoControlPopup ) + { + // it is a Popmenu + uno::Reference< lang::XSingleComponentFactory > xSCF( m_xBarSettings, uno::UNO_QUERY_THROW ); + aSubMenu <<= xSCF->createInstanceWithContext( mxContext ); + } + + // create control + uno::Sequence< beans::PropertyValue > aProps; + OUString sHelpUrl; + sal_uInt16 nItemType = 0; + if( m_bIsMenu ) + { + aProps = CreateMenuItemData( sCommandUrl, sHelpUrl, sLabel, nItemType, aSubMenu, true, true ); + } + else + { + aProps = CreateToolbarItemData( sCommandUrl, sHelpUrl, sLabel, nItemType, aSubMenu, true/*isVisible*/, 0/*nStyle*/ ); + } + + + uno::Reference< container::XIndexContainer > xIndexContainer( m_xIndexAccess, uno::UNO_QUERY_THROW ); + xIndexContainer->insertByIndex( nPosition, uno::makeAny( aProps ) ); + + pCBarHelper->ApplyTempChange( m_sResourceUrl, m_xBarSettings ); + + ScVbaCommandBarControl* pNewCommandBarControl = nullptr; + if( nType == office::MsoControlType::msoControlPopup ) + pNewCommandBarControl = new ScVbaCommandBarPopup( this, mxContext, m_xIndexAccess, pCBarHelper, m_xBarSettings, m_sResourceUrl, nPosition ); + else + pNewCommandBarControl = new ScVbaCommandBarButton( this, mxContext, m_xIndexAccess, pCBarHelper, m_xBarSettings, m_sResourceUrl, nPosition ); + + return uno::Reference< XCommandBarControl >( pNewCommandBarControl ); +} + +// XHelperInterface +OUString +ScVbaCommandBarControls::getServiceImplName() +{ + return "ScVbaCommandBarControls"; +} + +uno::Sequence<OUString> +ScVbaCommandBarControls::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.CommandBarControls" + }; + return aServiceNames; +} + +namespace { + +class VbaDummyIndexAccess : public ::cppu::WeakImplHelper< container::XIndexAccess > +{ +public: + VbaDummyIndexAccess() {} + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override + { return 0; } + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 /*Index*/ ) override + { throw lang::IndexOutOfBoundsException(); } + // XElementAccess + virtual uno::Type SAL_CALL getElementType( ) override + { return cppu::UnoType<XCommandBarControl>::get(); } + virtual sal_Bool SAL_CALL hasElements( ) override + { return false; } +}; + +} + +VbaDummyCommandBarControls::VbaDummyCommandBarControls( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext ) : + CommandBarControls_BASE( xParent, xContext, new VbaDummyIndexAccess ) +{ +} + +// XEnumerationAccess +uno::Type SAL_CALL VbaDummyCommandBarControls::getElementType() +{ + return cppu::UnoType<XCommandBarControl>::get(); +} + +uno::Reference< container::XEnumeration > VbaDummyCommandBarControls::createEnumeration() +{ + return uno::Reference< container::XEnumeration >( new CommandBarControlEnumeration( this ) ); +} + +uno::Any VbaDummyCommandBarControls::createCollectionObject( const uno::Any& /*aSource*/ ) +{ + return uno::Any( uno::Reference< XCommandBarControl >() ); +} + +// Methods +uno::Any SAL_CALL VbaDummyCommandBarControls::Item( const uno::Any& /*aIndex*/, const uno::Any& /*aIndex*/ ) +{ + return uno::Any( uno::Reference< XCommandBarControl >() ); +} + +uno::Reference< XCommandBarControl > SAL_CALL VbaDummyCommandBarControls::Add( + const uno::Any& /*Type*/, const uno::Any& /*Id*/, const uno::Any& /*Parameter*/, const uno::Any& /*Before*/, const uno::Any& /*Temporary*/ ) +{ + return uno::Reference< XCommandBarControl >(); +} + +// XHelperInterface +OUString VbaDummyCommandBarControls::getServiceImplName() +{ + return "VbaDummyCommandBarControls"; +} + +uno::Sequence<OUString> VbaDummyCommandBarControls::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.CommandBarControls" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbacommandbarcontrols.hxx b/vbahelper/source/vbahelper/vbacommandbarcontrols.hxx new file mode 100644 index 000000000..5e86b359f --- /dev/null +++ b/vbahelper/source/vbahelper/vbacommandbarcontrols.hxx @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBARCONTROLS_HXX +#define INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBARCONTROLS_HXX + +#include <ooo/vba/XCommandBarControls.hpp> +#include <vbahelper/vbacollectionimpl.hxx> +#include "vbacommandbarhelper.hxx" + +typedef CollTestImplHelper< ov::XCommandBarControls > CommandBarControls_BASE; + +class ScVbaCommandBarControls : public CommandBarControls_BASE +{ +private: + VbaCommandBarHelperRef pCBarHelper; + css::uno::Reference< css::container::XIndexAccess > m_xBarSettings; + OUString m_sResourceUrl; + bool m_bIsMenu; + + static css::uno::Sequence< css::beans::PropertyValue > CreateMenuItemData( const OUString& sCommandURL, + const OUString& sHelpURL, + const OUString& sLabel, + sal_uInt16 nType, + const css::uno::Any& aSubMenu, + bool isVisible, + bool isEnabled ); + static css::uno::Sequence< css::beans::PropertyValue > CreateToolbarItemData( const OUString& sCommandURL, const OUString& sHelpURL, const OUString& sLabel, sal_uInt16 nType, const css::uno::Any& aSubMenu, bool isVisible, sal_Int32 nStyle ); + +public: + /// @throws css::uno::RuntimeException + ScVbaCommandBarControls( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, VbaCommandBarHelperRef const & pHelper, const css::uno::Reference< css::container::XIndexAccess >& xBarSettings, const OUString& sResourceUrl ); + + // 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& aSource ) override; + + // Methods + virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index, const css::uno::Any& /*Index2*/ ) override; + virtual css::uno::Reference< ov::XCommandBarControl > SAL_CALL Add( const css::uno::Any& Type, const css::uno::Any& Id, const css::uno::Any& Parameter, const css::uno::Any& Before, const css::uno::Any& Temporary ) override; + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +class VbaDummyCommandBarControls : public CommandBarControls_BASE +{ +public: + /// @throws css::uno::RuntimeException + VbaDummyCommandBarControls( + 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; + virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override; + + // Methods + virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index, const css::uno::Any& /*Index2*/ ) override; + virtual css::uno::Reference< ov::XCommandBarControl > SAL_CALL Add( const css::uno::Any& Type, const css::uno::Any& Id, const css::uno::Any& Parameter, const css::uno::Any& Before, const css::uno::Any& Temporary ) override; + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBARCONTROLS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbacommandbarhelper.cxx b/vbahelper/source/vbahelper/vbacommandbarhelper.cxx new file mode 100644 index 000000000..d61a3c3dd --- /dev/null +++ b/vbahelper/source/vbahelper/vbacommandbarhelper.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 "vbacommandbarhelper.hxx" +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp> +#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> +#include <com/sun/star/ui/theWindowStateConfiguration.hpp> +#include <comphelper/random.hxx> +#include <vbahelper/vbahelper.hxx> +#include <rtl/ustrbuf.hxx> +#include <sal/log.hxx> +#include <map> +#include <string_view> + +using namespace com::sun::star; +using namespace ooo::vba; + +typedef std::map< OUString, OUString > MSO2OOCommandbarMap; + +namespace { + +class MSO2OOCommandbarHelper final +{ +private: + static MSO2OOCommandbarHelper* pMSO2OOCommandbarHelper; + MSO2OOCommandbarMap maBuildinToolbarMap; + + MSO2OOCommandbarHelper() + { + // Buildin toolbars + maBuildinToolbarMap.insert( std::make_pair( OUString("Standard") , OUString("private:resource/toolbar/standardbar" ) ) ); + maBuildinToolbarMap.insert( std::make_pair( OUString("Formatting"), OUString("private:resource/toolbar/formatobjectbar") ) ); + maBuildinToolbarMap.insert( std::make_pair( OUString("Drawing"), OUString("private:resource/toolbar/drawbar") ) ); + maBuildinToolbarMap.insert( std::make_pair( OUString("Toolbar List"), OUString("private:resource/toolbar/toolbar") ) ); + maBuildinToolbarMap.insert( std::make_pair( OUString("Forms"), OUString("private:resource/toolbar/formcontrols") ) ); + maBuildinToolbarMap.insert( std::make_pair( OUString("Form Controls"),OUString("private:resource/toolbar/formcontrols") ) ); + maBuildinToolbarMap.insert( std::make_pair( OUString("Full Screen"), OUString("private:resource/toolbar/fullscreenbar") ) ); + maBuildinToolbarMap.insert( std::make_pair( OUString("Chart"), OUString("private:resource/toolbar/flowchartshapes") ) ); + maBuildinToolbarMap.insert( std::make_pair( OUString("Picture"), OUString("private:resource/toolbar/graphicobjectbar") ) ); + maBuildinToolbarMap.insert( std::make_pair( OUString("WordArt"), OUString("private:resource/toolbar/fontworkobjectbar") ) ); + maBuildinToolbarMap.insert( std::make_pair( OUString("3-D Settings"), OUString("private:resource/toolbar/extrusionobjectbar") ) ); + } + +public: + static MSO2OOCommandbarHelper* getMSO2OOCommandbarHelper() + { + if( pMSO2OOCommandbarHelper == nullptr ) + { + pMSO2OOCommandbarHelper = new MSO2OOCommandbarHelper(); + } + return pMSO2OOCommandbarHelper; + } + + OUString findBuildinToolbar( const OUString& sToolbarName ) + { + auto it = std::find_if(maBuildinToolbarMap.begin(), maBuildinToolbarMap.end(), + [&sToolbarName](const MSO2OOCommandbarMap::value_type& rItem) { return rItem.first.equalsIgnoreAsciiCase( sToolbarName ); }); + if( it != maBuildinToolbarMap.end() ) + return it->second; + return OUString(); + } +}; + +} + +MSO2OOCommandbarHelper* MSO2OOCommandbarHelper::pMSO2OOCommandbarHelper = nullptr; + + +VbaCommandBarHelper::VbaCommandBarHelper( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::frame::XModel >& xModel ) : mxContext( xContext ), mxModel( xModel ) +{ + Init(); +} + +void VbaCommandBarHelper::Init( ) +{ + uno::Reference< css::ui::XUIConfigurationManagerSupplier > xUICfgSupplier( mxModel, uno::UNO_QUERY_THROW ); + m_xDocCfgMgr = xUICfgSupplier->getUIConfigurationManager(); + + uno::Reference< lang::XServiceInfo > xServiceInfo( mxModel, uno::UNO_QUERY_THROW ); + if( xServiceInfo->supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) ) + { + maModuleId = "com.sun.star.sheet.SpreadsheetDocument"; + } + else if( xServiceInfo->supportsService( "com.sun.star.text.TextDocument" ) ) + { + maModuleId = "com.sun.star.text.TextDocument"; + } + + if( maModuleId.isEmpty() ) + { + throw uno::RuntimeException( "Not implemented" ); + } + + css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xUICfgMgrSupp( + css::ui::theModuleUIConfigurationManagerSupplier::get(mxContext) ); + + m_xAppCfgMgr.set( xUICfgMgrSupp->getUIConfigurationManager( maModuleId ), uno::UNO_SET_THROW ); + + css::uno::Reference< css::container::XNameAccess > xNameAccess = css::ui::theWindowStateConfiguration::get( mxContext ); + + m_xWindowState.set( xNameAccess->getByName( maModuleId ), uno::UNO_QUERY_THROW ); +} + +css::uno::Reference< css::container::XIndexAccess > VbaCommandBarHelper::getSettings( const OUString& sResourceUrl ) +{ + if( m_xDocCfgMgr->hasSettings( sResourceUrl ) ) + return m_xDocCfgMgr->getSettings( sResourceUrl, true ); + else if( m_xAppCfgMgr->hasSettings( sResourceUrl ) ) + return m_xAppCfgMgr->getSettings( sResourceUrl, true ); + else + { + css::uno::Reference< css::container::XIndexAccess > xSettings( m_xAppCfgMgr->createSettings( ), uno::UNO_QUERY_THROW ); + return xSettings; + } +} + +void VbaCommandBarHelper::removeSettings( const OUString& sResourceUrl ) +{ + if( m_xDocCfgMgr->hasSettings( sResourceUrl ) ) + m_xDocCfgMgr->removeSettings( sResourceUrl ); + else if( m_xAppCfgMgr->hasSettings( sResourceUrl ) ) + m_xAppCfgMgr->removeSettings( sResourceUrl ); + + // persistChanges(); +} + +void VbaCommandBarHelper::ApplyTempChange( const OUString& sResourceUrl, const css::uno::Reference< css::container::XIndexAccess >& xSettings ) +{ + if( m_xDocCfgMgr->hasSettings( sResourceUrl ) ) + { + m_xDocCfgMgr->replaceSettings( sResourceUrl, xSettings ); + } + else + { + m_xDocCfgMgr->insertSettings( sResourceUrl, xSettings ); + } +} + +uno::Reference< frame::XLayoutManager > VbaCommandBarHelper::getLayoutManager() const +{ + uno::Reference< frame::XFrame > xFrame( getModel()->getCurrentController()->getFrame(), uno::UNO_SET_THROW ); + uno::Reference< beans::XPropertySet > xPropertySet( xFrame, uno::UNO_QUERY_THROW ); + uno::Reference< frame::XLayoutManager > xLayoutManager( xPropertySet->getPropertyValue( "LayoutManager" ), uno::UNO_QUERY_THROW ); + return xLayoutManager; +} + +bool VbaCommandBarHelper::hasToolbar( const OUString& sResourceUrl, const OUString& sName ) +{ + if( m_xDocCfgMgr->hasSettings( sResourceUrl ) ) + { + OUString sUIName; + uno::Reference< beans::XPropertySet > xPropertySet( m_xDocCfgMgr->getSettings( sResourceUrl, false ), uno::UNO_QUERY_THROW ); + xPropertySet->getPropertyValue( ITEM_DESCRIPTOR_UINAME ) >>= sUIName; + if( sName.equalsIgnoreAsciiCase( sUIName ) ) + return true; + } + return false; +} + +// return the resource url if found +OUString VbaCommandBarHelper::findToolbarByName( const css::uno::Reference< css::container::XNameAccess >& xNameAccess, const OUString& sName ) +{ + // check if it is a buildin toolbar + OUString sResourceUrl = MSO2OOCommandbarHelper::getMSO2OOCommandbarHelper()->findBuildinToolbar( sName ); + if( !sResourceUrl.isEmpty() ) + return sResourceUrl; + + uno::Sequence< OUString > allNames = xNameAccess->getElementNames(); + auto pName = std::find_if(allNames.begin(), allNames.end(), + [this, &sName](const OUString& rName) { + return rName.startsWith( ITEM_TOOLBAR_URL ) + && hasToolbar( rName, sName ); + }); + if (pName != allNames.end()) + return *pName; + + // the customize toolbars creating during importing, should found there. + sResourceUrl = "private:resource/toolbar/custom_" + sName; + if( hasToolbar( sResourceUrl, sName ) ) + return sResourceUrl; + + return OUString(); +} + +// if found, return the position of the control. if not found, return -1 +sal_Int32 VbaCommandBarHelper::findControlByName( const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, const OUString& sName, bool bMenu ) +{ + sal_Int32 nCount = xIndexAccess->getCount(); + css::uno::Sequence< css::beans::PropertyValue > aProps; + for( sal_Int32 i = 0; i < nCount; i++ ) + { + OUString sLabel; + xIndexAccess->getByIndex( i ) >>= aProps; + getPropertyValue( aProps, ITEM_DESCRIPTOR_LABEL ) >>= sLabel; + // handle the hotkey marker '~' (remove in toolbars (?), replace by '&' in menus) + OUStringBuffer aBuffer; + sal_Int32 index = sLabel.indexOf( '~' ); + if( index < 0 ) + { + aBuffer = sLabel; + } + else + { + aBuffer.append( std::u16string_view(sLabel).substr(0, index) ); + if( bMenu ) + aBuffer.append( '&' ); + aBuffer.append( std::u16string_view(sLabel).substr(index + 1) ); + } + OUString sNewLabel = aBuffer.makeStringAndClear(); + SAL_INFO("vbahelper", "VbaCommandBarHelper::findControlByName, control name: " << sNewLabel); + if( sName.equalsIgnoreAsciiCase( sNewLabel ) ) + return i; + } + + // not found + return -1; +} + +OUString VbaCommandBarHelper::generateCustomURL() +{ + return OUStringLiteral(ITEM_TOOLBAR_URL) + CUSTOM_TOOLBAR_STR + + // use a random number to minimize possible clash with existing custom toolbars + OUString::number(comphelper::rng::uniform_int_distribution(0, std::numeric_limits<int>::max()), 16); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbacommandbarhelper.hxx b/vbahelper/source/vbahelper/vbacommandbarhelper.hxx new file mode 100644 index 000000000..545dc7318 --- /dev/null +++ b/vbahelper/source/vbahelper/vbacommandbarhelper.hxx @@ -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 . + */ +#ifndef INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBARHELPER_HXX +#define INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBARHELPER_HXX + +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/ui/XUIConfigurationManager.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <memory> + +static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL"; +static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL"; +static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer"; +static const char ITEM_DESCRIPTOR_LABEL[] = "Label"; +static const char ITEM_DESCRIPTOR_TYPE[] = "Type"; +static const char ITEM_DESCRIPTOR_STYLE[] = "Style"; +static const char ITEM_DESCRIPTOR_ISVISIBLE[] = "IsVisible"; +static const char ITEM_DESCRIPTOR_UINAME[] = "UIName"; +static const char ITEM_DESCRIPTOR_ENABLED[] = "Enabled"; + +static const char ITEM_MENUBAR_URL[] = "private:resource/menubar/menubar"; +static const char ITEM_TOOLBAR_URL[] = "private:resource/toolbar/"; + +static const char CUSTOM_TOOLBAR_STR[] = "custom_toolbar_"; +static const char CUSTOM_MENU_STR[] = "vnd.openoffice.org:CustomMenu"; + +class VbaCommandBarHelper; +typedef std::shared_ptr< VbaCommandBarHelper > VbaCommandBarHelperRef; + +class VbaCommandBarHelper +{ +private: + css::uno::Reference< css::uno::XComponentContext > mxContext; + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::ui::XUIConfigurationManager > m_xDocCfgMgr; // current document + css::uno::Reference< css::ui::XUIConfigurationManager > m_xAppCfgMgr; + css::uno::Reference< css::container::XNameAccess > m_xWindowState; + OUString maModuleId; + + /// @throws css::uno::RuntimeException + void Init(); + /// @throws css::uno::RuntimeException + bool hasToolbar( const OUString& sResourceUrl, const OUString& sName ); +public: + /// @throws css::uno::RuntimeException + VbaCommandBarHelper( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::frame::XModel >& xModel ); + + const css::uno::Reference< css::frame::XModel >& getModel() const { return mxModel; } + + /// @throws css::uno::RuntimeException + const css::uno::Reference< css::container::XNameAccess >& getPersistentWindowState() const + { + return m_xWindowState; + } + /// @throws css::uno::RuntimeException + css::uno::Reference< css::container::XIndexAccess > getSettings( const OUString& sResourceUrl ); + /// @throws css::uno::RuntimeException + void removeSettings( const OUString& sResourceUrl ); + /// @throws css::uno::RuntimeException + void ApplyTempChange( const OUString& sResourceUrl, const css::uno::Reference< css::container::XIndexAccess >& xSettings); + + /// @throws css::uno::RuntimeException + css::uno::Reference< css::frame::XLayoutManager > getLayoutManager() const; + + const OUString& getModuleId() const { return maModuleId; } + /// @throws css::uno::RuntimeException + OUString findToolbarByName( const css::uno::Reference< css::container::XNameAccess >& xNameAccess, const OUString& sName ); + /// @throws css::uno::RuntimeException + static sal_Int32 findControlByName( const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, const OUString& sName, bool bMenu ); + static OUString generateCustomURL(); +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBARHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbacommandbars.cxx b/vbahelper/source/vbahelper/vbacommandbars.cxx new file mode 100644 index 000000000..a864339fd --- /dev/null +++ b/vbahelper/source/vbahelper/vbacommandbars.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 <com/sun/star/container/XNameAccess.hpp> +#include <ooo/vba/office/MsoBarType.hpp> +#include <cppuhelper/implbase.hxx> + +#include "vbacommandbars.hxx" +#include "vbacommandbar.hxx" + +using namespace com::sun::star; +using namespace ooo::vba; + +namespace { + +class CommandBarEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration > +{ + uno::Reference< XHelperInterface > m_xParent; + uno::Reference< uno::XComponentContext > m_xContext; + VbaCommandBarHelperRef m_pCBarHelper; + uno::Sequence< OUString > m_sNames; + sal_Int32 m_nCurrentPosition; +public: + /// @throws uno::RuntimeException + CommandBarEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const VbaCommandBarHelperRef& pHelper) : m_xParent( xParent ), m_xContext( xContext ), m_pCBarHelper( pHelper ) , m_nCurrentPosition( 0 ) + { + uno::Reference< container::XNameAccess > xNameAccess = m_pCBarHelper->getPersistentWindowState(); + m_sNames = xNameAccess->getElementNames(); + } + virtual sal_Bool SAL_CALL hasMoreElements() override + { + return m_nCurrentPosition < m_sNames.getLength(); + } + virtual uno::Any SAL_CALL nextElement() override + { + // FIXME: should be add menubar + if( !hasMoreElements() ) + throw container::NoSuchElementException(); + + OUString sResourceUrl( m_sNames[ m_nCurrentPosition++ ] ); + if( sResourceUrl.indexOf( "private:resource/toolbar/" ) != -1 ) + { + uno::Reference< container::XIndexAccess > xCBarSetting = m_pCBarHelper->getSettings( sResourceUrl ); + uno::Reference< XCommandBar > xCommandBar( new ScVbaCommandBar( m_xParent, m_xContext, m_pCBarHelper, xCBarSetting, sResourceUrl, false ) ); + // Strange, shouldn't the Enumeration support match/share the + // iteration code? ( e.g. ScVbaCommandBars::Item(...) ) + // and we at least should return here ( something ) it seems + return uno::makeAny( xCommandBar ); + } + else + return nextElement(); + } +}; + +} + +ScVbaCommandBars::ScVbaCommandBars( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess, const uno::Reference< frame::XModel >& xModel ) : CommandBars_BASE( xParent, xContext, xIndexAccess ) +{ + m_pCBarHelper = std::make_shared<VbaCommandBarHelper>( mxContext, xModel ); + m_xNameAccess = m_pCBarHelper->getPersistentWindowState(); +} + +ScVbaCommandBars::~ScVbaCommandBars() +{ +} + +// XEnumerationAccess +uno::Type SAL_CALL +ScVbaCommandBars::getElementType() +{ + return cppu::UnoType<XCommandBar>::get(); +} + +uno::Reference< container::XEnumeration > +ScVbaCommandBars::createEnumeration() +{ + return uno::Reference< container::XEnumeration >( new CommandBarEnumeration( this, mxContext, m_pCBarHelper ) ); +} + +uno::Any +ScVbaCommandBars::createCollectionObject( const uno::Any& aSource ) +{ + // aSource should be a name at this time, because of the class is API wrapper. + OUString sResourceUrl; + uno::Reference< container::XIndexAccess > xBarSettings; + OUString sBarName; + bool bMenu = false; + uno::Any aRet; + + if( aSource >>= sBarName ) + { + // some built-in command bars + if( m_pCBarHelper->getModuleId() == "com.sun.star.sheet.SpreadsheetDocument" ) + { + if( sBarName.equalsIgnoreAsciiCase( "Worksheet Menu Bar" ) ) + { + // spreadsheet menu bar + sResourceUrl = ITEM_MENUBAR_URL; + bMenu = true; + } + else if( sBarName.equalsIgnoreAsciiCase( "Cell" ) ) + { + // EVIL HACK (tm): spreadsheet cell context menu as dummy object without functionality + aRet <<= uno::Reference< XCommandBar >( new VbaDummyCommandBar( this, mxContext, sBarName ) ); + } + } + else if( m_pCBarHelper->getModuleId() == "com.sun.star.text.TextDocument" ) + { + if( sBarName.equalsIgnoreAsciiCase( "Menu Bar" ) ) + { + // text processor menu bar + sResourceUrl = ITEM_MENUBAR_URL; + bMenu = true; + } + } + + // nothing found - try to resolve from name + if( !aRet.hasValue() && sResourceUrl.isEmpty() ) + { + sResourceUrl = m_pCBarHelper->findToolbarByName( m_xNameAccess, sBarName ); + bMenu = false; + } + } + + if( !sResourceUrl.isEmpty() ) + { + xBarSettings = m_pCBarHelper->getSettings( sResourceUrl ); + aRet <<= uno::Reference< XCommandBar >( new ScVbaCommandBar( this, mxContext, m_pCBarHelper, xBarSettings, sResourceUrl, bMenu ) ); + } + + if( !aRet.hasValue() ) + throw uno::RuntimeException( "Toolbar do not exist" ); + + return aRet; +} + +// XCommandBars +uno::Reference< XCommandBar > SAL_CALL +ScVbaCommandBars::Add( const css::uno::Any& Name, const css::uno::Any& /*Position*/, const css::uno::Any& /*MenuBar*/, const css::uno::Any& /*Temporary*/ ) +{ + // FIXME: only support to add Toolbar + // Position - MsoBar MenuBar - sal_Bool + // Currently only the Name is supported. + OUString sName; + if( Name.hasValue() ) + Name >>= sName; + + OUString sResourceUrl; + if( !sName.isEmpty() ) + { + sResourceUrl = m_pCBarHelper->findToolbarByName( m_xNameAccess, sName ); + if( !sResourceUrl.isEmpty() ) + throw uno::RuntimeException( "Toolbar exists" ); + } + else + { + sName = "Custom1"; + } + + sResourceUrl = VbaCommandBarHelper::generateCustomURL(); + uno::Reference< container::XIndexAccess > xBarSettings( m_pCBarHelper->getSettings( sResourceUrl ), uno::UNO_SET_THROW ); + uno::Reference< XCommandBar > xCBar( new ScVbaCommandBar( this, mxContext, m_pCBarHelper, xBarSettings, sResourceUrl, false ) ); + xCBar->setName( sName ); + return xCBar; +} +sal_Int32 SAL_CALL +ScVbaCommandBars::getCount() +{ + // Filter out all toolbars from the window collection + sal_Int32 nCount = 1; // there is a Menubar in OOo + uno::Sequence< ::OUString > allNames = m_xNameAccess->getElementNames(); + nCount += std::count_if(allNames.begin(), allNames.end(), + [](const OUString& rName) { return rName.indexOf( "private:resource/toolbar/" ) != -1; }); + return nCount; +} + +// ScVbaCollectionBaseImpl +uno::Any SAL_CALL +ScVbaCommandBars::Item( const uno::Any& aIndex, const uno::Any& /*aIndex2*/ ) +{ + if( aIndex.getValueTypeClass() == uno::TypeClass_STRING ) + { + return createCollectionObject( aIndex ); + } + + // hardcode if "aIndex = 1" that would return "main menu". + sal_Int32 nIndex = 0; + aIndex >>= nIndex; + if( nIndex == 1 ) + { + uno::Any aSource; + if( m_pCBarHelper->getModuleId() == "com.sun.star.sheet.SpreadsheetDocument" ) + aSource <<= OUString("Worksheet Menu Bar"); + else if( m_pCBarHelper->getModuleId() == "com.sun.star.text.TextDocument" ) + aSource <<= OUString("Menu Bar"); + if( aSource.hasValue() ) + return createCollectionObject( aSource ); + } + return uno::Any(); +} + +// XHelperInterface +OUString +ScVbaCommandBars::getServiceImplName() +{ + return "ScVbaCommandBars"; +} + +uno::Sequence<OUString> +ScVbaCommandBars::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.CommandBars" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbacommandbars.hxx b/vbahelper/source/vbahelper/vbacommandbars.hxx new file mode 100644 index 000000000..ba7c8cbcd --- /dev/null +++ b/vbahelper/source/vbahelper/vbacommandbars.hxx @@ -0,0 +1,55 @@ +/* -*- 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_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBARS_HXX +#define INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBARS_HXX + +#include <ooo/vba/XCommandBar.hpp> +#include <ooo/vba/XCommandBars.hpp> +#include <vbahelper/vbacollectionimpl.hxx> +#include "vbacommandbarhelper.hxx" + +typedef CollTestImplHelper< ov::XCommandBars > CommandBars_BASE; + +class ScVbaCommandBars : public CommandBars_BASE +{ +private: + VbaCommandBarHelperRef m_pCBarHelper; + +public: + /// @throws css::uno::RuntimeException + ScVbaCommandBars( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, const css::uno::Reference< css::frame::XModel >& xModel ); + virtual ~ScVbaCommandBars() override; + + // XCommandBars + virtual css::uno::Reference< ov::XCommandBar > SAL_CALL Add( const css::uno::Any& Name, const css::uno::Any& Position, const css::uno::Any& MenuBar, const css::uno::Any& Temporary ) 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& aSource ) override; + + virtual sal_Int32 SAL_CALL getCount() override; + virtual css::uno::Any SAL_CALL Item( const css::uno::Any& aIndex, const css::uno::Any& /*aIndex2*/ ) override; + // XHelperInterface + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBACOMMANDBARS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbadialogbase.cxx b/vbahelper/source/vbahelper/vbadialogbase.cxx new file mode 100644 index 000000000..605a9c76f --- /dev/null +++ b/vbahelper/source/vbahelper/vbadialogbase.cxx @@ -0,0 +1,39 @@ +/* -*- 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 <vbahelper/vbadialogbase.hxx> +#include <vbahelper/vbahelper.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +void SAL_CALL VbaDialogBase::Show() +{ + OUString aURL; + if ( m_xModel.is() ) + { + aURL = mapIndexToName( mnIndex ); + if( aURL.isEmpty() ) + throw uno::RuntimeException( "Unable to open the specified dialog" ); + + uno::Sequence< beans::PropertyValue > dispatchProps(0); + dispatchRequests( m_xModel, aURL, dispatchProps ); + } +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbadialogsbase.cxx b/vbahelper/source/vbahelper/vbadialogsbase.cxx new file mode 100644 index 000000000..d73ac6c06 --- /dev/null +++ b/vbahelper/source/vbahelper/vbadialogsbase.cxx @@ -0,0 +1,38 @@ +/* -*- 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 <vbahelper/vbadialogsbase.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +::sal_Int32 +VbaDialogsBase::getCount() +{ + //#STUB + return 0; +} + +uno::Any +VbaDialogsBase::Item( const uno::Any& /* &aItem */) +{ + //#STUB + return uno::Any(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbadocumentbase.cxx b/vbahelper/source/vbahelper/vbadocumentbase.cxx new file mode 100644 index 000000000..58210a335 --- /dev/null +++ b/vbahelper/source/vbahelper/vbadocumentbase.cxx @@ -0,0 +1,310 @@ +/* -*- 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 <vbahelper/vbadocumentbase.hxx> + +#include <com/sun/star/beans/PropertyVetoException.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> +#include <com/sun/star/util/XModifiable.hpp> +#include <com/sun/star/util/XProtectable.hpp> +#include <com/sun/star/util/XCloseable.hpp> +#include <com/sun/star/util/URLTransformer.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XTitle.hpp> +#include <ooo/vba/XApplicationBase.hpp> + +#include <comphelper/automationinvokedzone.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <tools/urlobj.hxx> +#include <osl/file.hxx> +#include <sal/log.hxx> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +VbaDocumentBase::VbaDocumentBase( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, uno::Reference< frame::XModel > const & xModel ) : VbaDocumentBase_BASE( xParent, xContext ), mxModel( xModel ) +{ +} + +VbaDocumentBase::VbaDocumentBase( uno::Sequence< uno::Any> const & args, + uno::Reference< uno::XComponentContext> const & xContext ) : VbaDocumentBase_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxModel( getXSomethingFromArgs< frame::XModel >( args, 1 ) ) +{ +} + +OUString +VbaDocumentBase::getName() +{ + OUString sName = VbaDocumentBase::getNameFromModel( getModel() ); + SAL_INFO("vbahelper", "VbaDocumentBase::getName: '" << sName << "'"); + + return sName; +} + +OUString VbaDocumentBase::getNameFromModel( const uno::Reference< frame::XModel >& xModel ) +{ + OUString sName = xModel.is() ? xModel->getURL() : OUString(); + if ( !sName.isEmpty() ) + { + + INetURLObject aURL( xModel->getURL() ); + ::osl::File::getSystemPathFromFileURL( aURL.GetLastName(), sName ); + } + else + { + uno::Reference< frame::XTitle > xTitle( xModel, uno::UNO_QUERY_THROW ); + sName = xTitle->getTitle(); + sName = sName.trim(); + } + return sName; +} +OUString +VbaDocumentBase::getPath() +{ + INetURLObject aURL( getModel()->getURL() ); + OUString sURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ); + OUString sPath; + if( !sURL.isEmpty() ) + { + sURL = sURL.copy( 0, sURL.getLength() - aURL.GetLastName().getLength() - 1 ); + ::osl::File::getSystemPathFromFileURL( sURL, sPath ); + } + SAL_INFO("vbahelper", "VbaDocumentBase::getPath: '" << sPath << "'"); + + return sPath; +} + +OUString +VbaDocumentBase::getFullName() +{ + // In the Automation case, follow the specs. + if (comphelper::Automation::AutomationInvokedZone::isActive()) + { + // We know that Automation is relevant only on Windows, so hardcode "\\". + OUString sPath = getPath() + "\\" + getName(); + SAL_INFO("vbahelper", "VbaDocumentBase::getFullName: '" << sPath << "'"); + return sPath; + } + + OUString sPath = getName(); + //::osl::File::getSystemPathFromFileURL( getModel()->getURL(), sPath ); + SAL_INFO("vbahelper", "VbaDocumentBase::getFullName: '" << sPath << "'"); + return sPath; +} + +void +VbaDocumentBase::Close( const uno::Any &rSaveArg, const uno::Any &rFileArg, + const uno::Any &rRouteArg ) +{ + bool bSaveChanges = false; + OUString aFileName; + bool bRouteWorkbook = true; + + rSaveArg >>= bSaveChanges; + bool bFileName = ( rFileArg >>= aFileName ); + rRouteArg >>= bRouteWorkbook; + uno::Reference< frame::XStorable > xStorable( getModel(), uno::UNO_QUERY_THROW ); + uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW ); + + if( bSaveChanges ) + { + if( xStorable->isReadonly() ) + { + throw uno::RuntimeException("Unable to save to a read only file " ); + } + if( bFileName ) + xStorable->storeAsURL( aFileName, uno::Sequence< beans::PropertyValue >(0) ); + else + xStorable->store(); + } + else + xModifiable->setModified( false ); + + // first try to close the document using UI dispatch functionality + bool bUIClose = false; + try + { + uno::Reference< frame::XController > xController( getModel()->getCurrentController(), uno::UNO_SET_THROW ); + uno::Reference< frame::XDispatchProvider > xDispatchProvider( xController->getFrame(), uno::UNO_QUERY_THROW ); + + uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< util::XURLTransformer > xURLTransformer( util::URLTransformer::create(mxContext) ); + + util::URL aURL; + aURL.Complete = ".uno:CloseDoc"; + xURLTransformer->parseStrict( aURL ); + + uno::Reference< css::frame::XDispatch > xDispatch( + xDispatchProvider->queryDispatch( aURL, "_self" , 0 ), + uno::UNO_SET_THROW ); + xDispatch->dispatch( aURL, uno::Sequence< beans::PropertyValue >() ); + bUIClose = true; + } + catch(const uno::Exception&) + { + } + + if ( !bUIClose ) + { + // if it is not possible to use UI dispatch, try to close the model directly + bool bCloseable = false; + uno::Reference< frame::XModel > xModel = getModel(); + try + { + uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY ); + + // use close(boolean DeliverOwnership) + // The boolean parameter DeliverOwnership tells objects vetoing the close + // process that they may assume ownership if they object the closure by + // throwing a CloseVetoException. Here we give up ownership. To be on the + // safe side, catch possible veto exception anyway. + if ( xCloseable.is() ) + { + bCloseable = true; + xCloseable->close(true); + } + } + catch (const uno::Exception &) + { + // vetoed + } + if (!bCloseable) + { + try { + // If close is not supported by this model - try to dispose it. + // But if the model disagree with a reset request for the modify state + // we shouldn't do so. Otherwise some strange things can happen. + uno::Reference< lang::XComponent > xDisposable ( xModel, uno::UNO_QUERY_THROW ); + xDisposable->dispose(); + } + catch(const uno::Exception&) + { + } + } + } +} + +void +VbaDocumentBase::Protect( const uno::Any &aPassword ) +{ + OUString rPassword; + uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW ); + SAL_INFO("vbahelper", "Workbook::Protect stub"); + if( aPassword >>= rPassword ) + xProt->protect( rPassword ); + else + xProt->protect( OUString() ); +} + +void +VbaDocumentBase::Unprotect( const uno::Any &aPassword ) +{ + OUString rPassword; + uno::Reference< util::XProtectable > xProt( getModel(), uno::UNO_QUERY_THROW ); + if( !xProt->isProtected() ) + throw uno::RuntimeException("File is already unprotected" ); + if( aPassword >>= rPassword ) + xProt->unprotect( rPassword ); + else + xProt->unprotect( OUString() ); +} + +void +VbaDocumentBase::setSaved( sal_Bool bSave ) +{ + uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW ); + try + { + xModifiable->setModified( !bSave ); + } + catch (const lang::DisposedException&) + { + // impossibility to set the modified state on disposed document should not trigger an error + } + catch (const beans::PropertyVetoException&) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw lang::WrappedTargetRuntimeException( + "Can't change modified state of model!", + uno::Reference< uno::XInterface >(), + aCaught ); + } +} + +sal_Bool +VbaDocumentBase::getSaved() +{ + uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY_THROW ); + return !xModifiable->isModified(); +} + +void +VbaDocumentBase::Save() +{ + uno::Reference< frame::XModel > xModel = getModel(); + dispatchRequests(xModel,".uno:Save"); +} + +void +VbaDocumentBase::Activate() +{ + uno::Reference< frame::XFrame > xFrame( getModel()->getCurrentController()->getFrame(), uno::UNO_SET_THROW ); + xFrame->activate(); +} + +uno::Any SAL_CALL +VbaDocumentBase::getVBProject() +{ + if( !mxVBProject.is() ) try + { + uno::Reference< XApplicationBase > xApp( Application(), uno::UNO_QUERY_THROW ); + uno::Reference< XInterface > xVBE( xApp->getVBE(), uno::UNO_QUERY_THROW ); + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= xVBE; // the VBE + aArgs[ 1 ] <<= getModel(); // document model for script container access + uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + mxVBProject = xServiceManager->createInstanceWithArgumentsAndContext( + "ooo.vba.vbide.VBProject", aArgs, mxContext ); + } + catch(const uno::Exception&) + { + } + return uno::Any( mxVBProject ); +} + +OUString +VbaDocumentBase::getServiceImplName() +{ + return "VbaDocumentBase"; +} + +uno::Sequence< OUString > +VbaDocumentBase::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.VbaDocumentBase" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbadocumentsbase.cxx b/vbahelper/source/vbahelper/vbadocumentsbase.cxx new file mode 100644 index 000000000..b7b8124c2 --- /dev/null +++ b/vbahelper/source/vbahelper/vbadocumentsbase.cxx @@ -0,0 +1,317 @@ +/* -*- 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 <vbahelper/vbadocumentsbase.hxx> + +#include <unotools/mediadescriptor.hxx> +#include <comphelper/sequence.hxx> +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/FrameSearchFlag.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/document/MacroExecMode.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <tools/urlobj.hxx> +#include <o3tl/safeint.hxx> +#include <osl/file.hxx> +#include <unordered_map> + +#include <vbahelper/vbadocumentbase.hxx> +#include <ooo/vba/XApplicationBase.hpp> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +typedef std::unordered_map< OUString, + sal_Int32 > NameIndexHash; + +typedef std::vector < uno::Reference< frame::XModel > > Documents; + +// #FIXME clearly this is a candidate for some sort of helper base class as +// this is a copy of SelectedSheetsEnum ( vbawindow.cxx ) + +namespace { + +class DocumentsEnumImpl : public ::cppu::WeakImplHelper< container::XEnumeration > +{ + uno::Reference< uno::XComponentContext > m_xContext; + Documents m_documents; + Documents::const_iterator m_it; + +public: + /// @throws uno::RuntimeException + DocumentsEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const Documents& docs ) : m_xContext( xContext ), m_documents( docs ) + { + m_it = m_documents.begin(); + } + /// @throws uno::RuntimeException + explicit DocumentsEnumImpl( const uno::Reference< uno::XComponentContext >& xContext ) : m_xContext( xContext ) + { + uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( m_xContext ); + uno::Reference< container::XEnumeration > xComponents = xDesktop->getComponents()->createEnumeration(); + while( xComponents->hasMoreElements() ) + { + uno::Reference< frame::XModel > xNext( xComponents->nextElement(), uno::UNO_QUERY ); + if ( xNext.is() ) + m_documents.push_back( xNext ); + } + m_it = m_documents.begin(); + } + // XEnumeration + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return m_it != m_documents.end(); + } + + virtual uno::Any SAL_CALL nextElement( ) override + { + if ( !hasMoreElements() ) + { + throw container::NoSuchElementException(); + } + return makeAny( *(m_it++) ); + } +}; + +} + +// #FIXME clearly this is also a candidate for some sort of helper base class as +// a very similar one is used in vbawindow ( SelectedSheetsEnumAccess ) +// Maybe a template base class that does all of the operations on the hashmap +// and vector only, and the sub-class does everything else +// => ctor, createEnumeration & factory method need be defined ( to be called +// by getByIndex, getByName ) +typedef ::cppu::WeakImplHelper< container::XEnumerationAccess + , css::container::XIndexAccess + , css::container::XNameAccess + > DocumentsAccessImpl_BASE; + +namespace { + +class DocumentsAccessImpl : public DocumentsAccessImpl_BASE +{ + uno::Reference< uno::XComponentContext > m_xContext; + Documents m_documents; + NameIndexHash namesToIndices; +public: + /// @throws uno::RuntimeException + DocumentsAccessImpl( const uno::Reference< uno::XComponentContext >& xContext, VbaDocumentsBase::DOCUMENT_TYPE eDocType ) :m_xContext( xContext ) + { + uno::Reference< container::XEnumeration > xEnum = new DocumentsEnumImpl( m_xContext ); + sal_Int32 nIndex=0; + while( xEnum->hasMoreElements() ) + { + uno::Reference< lang::XServiceInfo > xServiceInfo( xEnum->nextElement(), uno::UNO_QUERY ); + if ( xServiceInfo.is() + && ( ( xServiceInfo->supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) && eDocType == VbaDocumentsBase::EXCEL_DOCUMENT ) + || ( xServiceInfo->supportsService( "com.sun.star.text.TextDocument" ) && eDocType == VbaDocumentsBase::WORD_DOCUMENT ) ) ) + { + uno::Reference< frame::XModel > xModel( xServiceInfo, uno::UNO_QUERY_THROW ); // that the spreadsheetdocument is a xmodel is a given + m_documents.push_back( xModel ); + OUString sName = VbaDocumentBase::getNameFromModel( xModel ); + namesToIndices[ sName ] = nIndex++; + } + } + + } + + //XEnumerationAccess + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override + { + return new DocumentsEnumImpl( m_xContext, m_documents ); + } + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override + { + return m_documents.size(); + } + virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override + { + if ( Index < 0 + || o3tl::make_unsigned(Index) >= m_documents.size() ) + throw lang::IndexOutOfBoundsException(); + return makeAny( m_documents[ Index ] ); // returns xspreadsheetdoc + } + + //XElementAccess + virtual uno::Type SAL_CALL getElementType( ) override + { + return cppu::UnoType<frame::XModel>::get(); + } + + virtual sal_Bool SAL_CALL hasElements( ) override + { + return (!m_documents.empty()); + } + + //XNameAccess + virtual uno::Any SAL_CALL getByName( const OUString& aName ) override + { + NameIndexHash::const_iterator it = namesToIndices.find( aName ); + if ( it == namesToIndices.end() ) + throw container::NoSuchElementException(); + return makeAny( m_documents[ it->second ] ); + + } + + virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override + { + return comphelper::mapKeysToSequence( namesToIndices ); + } + + virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override + { + NameIndexHash::const_iterator it = namesToIndices.find( aName ); + return (it != namesToIndices.end()); + } + +}; + +} + +VbaDocumentsBase::VbaDocumentsBase( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext >& xContext, DOCUMENT_TYPE eDocType ) : VbaDocumentsBase_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new DocumentsAccessImpl( xContext, eDocType ) ) ), meDocType( eDocType ) +{ +} + +namespace { + +void lclSetupComponent( const uno::Reference< lang::XComponent >& rxComponent, bool bScreenUpdating, bool bInteractive ) +{ + if( !bScreenUpdating ) try + { + uno::Reference< frame::XModel >( rxComponent, uno::UNO_QUERY_THROW )->lockControllers(); + } + catch( uno::Exception& ) + { + } + + if( !bInteractive ) try + { + uno::Reference< frame::XModel > xModel( rxComponent, uno::UNO_QUERY_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 >( xFrame->getContainerWindow(), uno::UNO_SET_THROW )->setEnable( false ); + } + catch( uno::Exception& ) + { + } +} + +} // namespace + +uno::Any VbaDocumentsBase::createDocument() +{ + // #163808# determine state of Application.ScreenUpdating and Application.Interactive symbols (before new document is opened) + uno::Reference< XApplicationBase > xApplication( Application(), uno::UNO_QUERY ); + bool bScreenUpdating = !xApplication.is() || xApplication->getScreenUpdating(); + bool bInteractive = true; + + try + { + bInteractive = !xApplication.is() || xApplication->getInteractive(); + } + catch( const uno::Exception& ) + { + } + + uno::Reference< frame::XDesktop2 > xLoader = frame::Desktop::create(mxContext); + OUString sURL; + if( meDocType == WORD_DOCUMENT ) + sURL = "private:factory/swriter"; + else if( meDocType == EXCEL_DOCUMENT ) + sURL = "private:factory/scalc"; + else + throw uno::RuntimeException( "Not implemented" ); + + // prepare the media descriptor + utl::MediaDescriptor aMediaDesc; + aMediaDesc[ utl::MediaDescriptor::PROP_MACROEXECUTIONMODE() ] <<= document::MacroExecMode::USE_CONFIG; + aMediaDesc.setComponentDataEntry( "ApplyFormDesignMode" , uno::Any( false ) ); + + // create the new document + uno::Reference< lang::XComponent > xComponent = xLoader->loadComponentFromURL( + sURL , "_blank", 0, + aMediaDesc.getAsConstPropertyValueList() ); + + // #163808# lock document controllers and container window if specified by application + lclSetupComponent( xComponent, bScreenUpdating, bInteractive ); + + return uno::makeAny( xComponent ); +} + +// #TODO# #FIXME# can any of the unused params below be used? +uno::Any VbaDocumentsBase::openDocument( const OUString& rFileName, const uno::Any& ReadOnly, const uno::Sequence< beans::PropertyValue >& rProps ) +{ + // #163808# determine state of Application.ScreenUpdating and Application.Interactive symbols (before new document is opened) + uno::Reference< XApplicationBase > xApplication( Application(), uno::UNO_QUERY ); + bool bScreenUpdating = !xApplication.is() || xApplication->getScreenUpdating(); + bool bInteractive = true; + + try + { + bInteractive = !xApplication.is() || xApplication->getInteractive(); + } + catch( const uno::Exception& ) + { + } + + // we need to detect if this is a URL, if not then assume it's a file path + OUString aURL; + INetURLObject aObj; + aObj.SetURL( rFileName ); + bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid; + if ( bIsURL ) + aURL = rFileName; + else + osl::FileBase::getFileURLFromSystemPath( rFileName, aURL ); + uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( mxContext ); + + uno::Sequence< beans::PropertyValue > sProps( rProps ); + sProps.realloc( sProps.getLength() + 1 ); + sProps[ sProps.getLength() - 1 ].Name = "MacroExecutionMode"; + sProps[ sProps.getLength() - 1 ].Value <<= document::MacroExecMode::ALWAYS_EXECUTE_NO_WARN; + + if ( ReadOnly.hasValue() ) + { + bool bIsReadOnly = false; + ReadOnly >>= bIsReadOnly; + if ( bIsReadOnly ) + { + sProps.realloc( sProps.getLength() + 1 ); + sProps[ sProps.getLength() - 1 ].Name = "ReadOnly"; + sProps[ sProps.getLength() - 1 ].Value <<= true; + } + } + + uno::Reference< lang::XComponent > xComponent = xDesktop->loadComponentFromURL( aURL, + "_default" , + frame::FrameSearchFlag::CREATE, + sProps); + + // #163808# lock document controllers and container window if specified by application + lclSetupComponent( xComponent, bScreenUpdating, bInteractive ); + + return uno::makeAny( xComponent ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbaeventshelperbase.cxx b/vbahelper/source/vbahelper/vbaeventshelperbase.cxx new file mode 100644 index 000000000..83b047ea8 --- /dev/null +++ b/vbahelper/source/vbahelper/vbaeventshelperbase.cxx @@ -0,0 +1,357 @@ +/* -*- 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 <vbahelper/vbaeventshelperbase.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/script/ModuleType.hpp> +#include <com/sun/star/script/vba/XVBAModuleInfo.hpp> +#include <com/sun/star/script/XLibraryContainer.hpp> +#include <com/sun/star/util/VetoException.hpp> +#include <com/sun/star/util/XChangesNotifier.hpp> +#include <cppuhelper/supportsservice.hxx> +#include <filter/msfilter/msvbahelper.hxx> +#include <unotools/eventcfg.hxx> +#include <vbahelper/vbahelper.hxx> +#include <sal/log.hxx> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + + +VbaEventsHelperBase::VbaEventsHelperBase( const uno::Sequence< uno::Any >& rArgs ) : + mpShell( nullptr ), + mbDisposed( true ) +{ + try + { + mxModel = getXSomethingFromArgs< frame::XModel >( rArgs, 0, false ); + mpShell = getSfxObjShell( mxModel ); + } + catch( uno::Exception& ) + { + } + mbDisposed = mpShell == nullptr; + startListening(); +} + +VbaEventsHelperBase::~VbaEventsHelperBase() +{ + SAL_WARN_IF( !mbDisposed, "vbahelper", "VbaEventsHelperBase::~VbaEventsHelperBase - missing disposing notification" ); +} + +sal_Bool SAL_CALL VbaEventsHelperBase::processVbaEvent( sal_Int32 nEventId, const uno::Sequence< uno::Any >& rArgs ) +{ + /* Derived classes may add new event identifiers to be processed while + processing the original event. All unprocessed events are collected in + a queue. First element in the queue is the next event to be processed. */ + EventQueue aEventQueue; + aEventQueue.emplace_back( nEventId, rArgs ); + + /* bCancel will contain the current Cancel value. It is possible that + multiple events will try to modify the Cancel value. Every event + handler receives the Cancel value of the previous event handler. */ + bool bCancel = false; + + /* bExecuted will change to true if at least one event handler has been + found and executed. */ + bool bExecuted = false; + + /* Loop as long as there are more events to be processed. Derived classes + may add new events to be processed in the virtual implPrepareEvent() + function. */ + while( !aEventQueue.empty() ) + { + /* Check that all class members are available, and that we are not + disposed (this may have happened at any time during execution of + the last event handler). */ + if( mbDisposed || !mxModel.is() || !mpShell ) + throw uno::RuntimeException(); + + // get info for next event + const EventHandlerInfo& rInfo = getEventHandlerInfo( aEventQueue.front().mnEventId ); + uno::Sequence< uno::Any > aEventArgs = aEventQueue.front().maArgs; + aEventQueue.pop_front(); + SAL_INFO("vbahelper", "VbaEventsHelperBase::processVbaEvent( \"" << rInfo.maMacroName << "\" )"); + + /* Let derived classes prepare the event, they may add new events for + next iteration. If false is returned, the event handler must not be + called. */ + if( implPrepareEvent( aEventQueue, rInfo, aEventArgs ) ) + { + // search the event handler macro in the document + OUString aMacroPath = getEventHandlerPath( rInfo, aEventArgs ); + if( !aMacroPath.isEmpty() ) + { + // build the argument list + uno::Sequence< uno::Any > aVbaArgs = implBuildArgumentList( rInfo, aEventArgs ); + // insert current cancel value + if( rInfo.mnCancelIndex >= 0 ) + { + if( rInfo.mnCancelIndex >= aVbaArgs.getLength() ) + throw lang::IllegalArgumentException(); + aVbaArgs[ rInfo.mnCancelIndex ] <<= bCancel; + } + // execute the event handler + uno::Any aRet, aCaller; + executeMacro( mpShell, aMacroPath, aVbaArgs, aRet, aCaller ); + // extract new cancel value (may be boolean or any integer type) + if( rInfo.mnCancelIndex >= 0 ) + { + checkArgument( aVbaArgs, rInfo.mnCancelIndex ); + bCancel = extractBoolFromAny( aVbaArgs[ rInfo.mnCancelIndex ] ); + } + // event handler has been found + bExecuted = true; + } + } + // post processing (also, if event handler does not exist, or disabled, or on error + implPostProcessEvent( aEventQueue, rInfo, bCancel ); + } + + // if event handlers want to cancel the event, do so regardless of any errors + if( bCancel ) + throw util::VetoException(); + + // return true, if at least one event handler has been found + return bExecuted; +} + +void SAL_CALL VbaEventsHelperBase::notifyEvent( const document::EventObject& rEvent ) +{ + SAL_INFO("vbahelper", "VbaEventsHelperBase::notifyEvent( \"" << rEvent.EventName << "\" )"); + if( rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::CLOSEDOC ) ) + stopListening(); +} + +void SAL_CALL VbaEventsHelperBase::changesOccurred( const util::ChangesEvent& rEvent ) +{ + // make sure the VBA library exists + try + { + ensureVBALibrary(); + } + catch( uno::Exception& ) + { + return; + } + + // check that the sender of the event is the VBA library + uno::Reference< script::vba::XVBAModuleInfo > xSender( rEvent.Base, uno::UNO_QUERY ); + if( mxModuleInfos.get() != xSender.get() ) + return; + + // process all changed modules + for( const util::ElementChange& rChange : rEvent.Changes ) + { + OUString aModuleName; + if( (rChange.Accessor >>= aModuleName) && !aModuleName.isEmpty() ) try + { + // invalidate event handler path map depending on module type + if( getModuleType( aModuleName ) == script::ModuleType::NORMAL ) + // paths to global event handlers are stored with empty key (will be searched in all normal code modules) + maEventPaths.erase( OUString() ); + else + // paths to class/form/document event handlers are keyed by module name + maEventPaths.erase( aModuleName ); + } + catch( uno::Exception& ) + { + } + } +} + +void SAL_CALL VbaEventsHelperBase::disposing( const lang::EventObject& rEvent ) +{ + uno::Reference< frame::XModel > xSender( rEvent.Source, uno::UNO_QUERY ); + if( xSender.is() ) + stopListening(); +} + +sal_Bool VbaEventsHelperBase::supportsService(OUString const & ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +void VbaEventsHelperBase::processVbaEventNoThrow( sal_Int32 nEventId, const uno::Sequence< uno::Any >& rArgs ) +{ + try + { + processVbaEvent( nEventId, rArgs ); + } + catch( uno::Exception& ) + { + } +} + +// protected ------------------------------------------------------------------ + +void VbaEventsHelperBase::registerEventHandler( sal_Int32 nEventId, sal_Int32 nModuleType, + const char* pcMacroName, sal_Int32 nCancelIndex, const uno::Any& rUserData ) +{ + EventHandlerInfo& rInfo = maEventInfos[ nEventId ]; + rInfo.mnEventId = nEventId; + rInfo.mnModuleType = nModuleType; + rInfo.maMacroName = OUString::createFromAscii( pcMacroName ); + rInfo.mnCancelIndex = nCancelIndex; + rInfo.maUserData = rUserData; +} + +// private -------------------------------------------------------------------- + +void VbaEventsHelperBase::startListening() +{ + if( mbDisposed ) + return; + + uno::Reference< document::XEventBroadcaster > xEventBroadcaster( mxModel, uno::UNO_QUERY ); + if( xEventBroadcaster.is() ) + try { xEventBroadcaster->addEventListener( this ); } catch( uno::Exception& ) {} +} + +void VbaEventsHelperBase::stopListening() +{ + if( mbDisposed ) + return; + + uno::Reference< document::XEventBroadcaster > xEventBroadcaster( mxModel, uno::UNO_QUERY ); + if( xEventBroadcaster.is() ) + try { xEventBroadcaster->removeEventListener( this ); } catch( uno::Exception& ) {} + + mxModel.clear(); + mpShell = nullptr; + maEventInfos.clear(); + mbDisposed = true; +} + +sal_Bool SAL_CALL VbaEventsHelperBase::hasVbaEventHandler( sal_Int32 nEventId, const uno::Sequence< uno::Any >& rArgs ) +{ + EventHandlerInfoMap::const_iterator aIt = maEventInfos.find( nEventId ); + if( aIt == maEventInfos.end() ) + return false; // throwing a lot of exceptions is slow. + else // getEventHandlerPath() searches for the macro in the document + return !getEventHandlerPath( aIt->second, rArgs ).isEmpty(); +} + +const VbaEventsHelperBase::EventHandlerInfo& VbaEventsHelperBase::getEventHandlerInfo( + sal_Int32 nEventId ) const +{ + EventHandlerInfoMap::const_iterator aIt = maEventInfos.find( nEventId ); + if( aIt == maEventInfos.end() ) + throw lang::IllegalArgumentException(); + return aIt->second; +} + +OUString VbaEventsHelperBase::getEventHandlerPath( const EventHandlerInfo& rInfo, + const uno::Sequence< uno::Any >& rArgs ) +{ + OUString aModuleName; + switch( rInfo.mnModuleType ) + { + // global event handlers may exist in any standard code module + case script::ModuleType::NORMAL: + break; + + // document event: get name of the code module associated to the event sender + case script::ModuleType::DOCUMENT: + aModuleName = implGetDocumentModuleName( rInfo, rArgs ); + if( aModuleName.isEmpty() ) + throw lang::IllegalArgumentException(); + break; + + default: + throw uno::RuntimeException(); // unsupported module type + } + + /* Performance improvement: Check the list of existing event handlers + instead of searching in Basic source code every time. */ + EventHandlerPathMap::iterator aIt = maEventPaths.find( aModuleName ); + ModulePathMap& rPathMap = (aIt == maEventPaths.end()) ? updateModulePathMap( aModuleName ) : aIt->second; + return rPathMap[ rInfo.mnEventId ]; +} + +void VbaEventsHelperBase::ensureVBALibrary() +{ + if( !mxModuleInfos.is() ) try + { + maLibraryName = getDefaultProjectName( mpShell ); + if( maLibraryName.isEmpty() ) + throw uno::RuntimeException(); + uno::Reference< beans::XPropertySet > xModelProps( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameAccess > xBasicLibs( xModelProps->getPropertyValue( + "BasicLibraries" ), uno::UNO_QUERY_THROW ); + + if(!xBasicLibs->hasByName(maLibraryName) ) + { + uno::Reference< script::XLibraryContainer > xLibContainer( + xModelProps->getPropertyValue("BasicLibraries"), uno::UNO_QUERY_THROW); + xLibContainer->createLibrary(maLibraryName); + } + + mxModuleInfos.set( xBasicLibs->getByName( maLibraryName ), uno::UNO_QUERY_THROW ); + // listen to changes in the VBA source code + uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModuleInfos, uno::UNO_QUERY_THROW ); + xChangesNotifier->addChangesListener( this ); + } + catch( uno::Exception& ) + { + // error accessing the Basic library, so this object is useless + stopListening(); + throw uno::RuntimeException(); + } +} + +sal_Int32 VbaEventsHelperBase::getModuleType( const OUString& rModuleName ) +{ + // make sure the VBA library exists + ensureVBALibrary(); + + // no module specified: global event handler in standard code modules + if( rModuleName.isEmpty() ) + return script::ModuleType::NORMAL; + + // get module type from module info + try + { + return mxModuleInfos->getModuleInfo( rModuleName ).ModuleType; + } + catch( uno::Exception& ) + { + } + throw uno::RuntimeException(); +} + +VbaEventsHelperBase::ModulePathMap& VbaEventsHelperBase::updateModulePathMap( const OUString& rModuleName ) +{ + // get type of the specified module (throws on error) + sal_Int32 nModuleType = getModuleType( rModuleName ); + // search for all event handlers + ModulePathMap& rPathMap = maEventPaths[ rModuleName ]; + for( const auto& rEventInfo : maEventInfos ) + { + const EventHandlerInfo& rInfo = rEventInfo.second; + if( rInfo.mnModuleType == nModuleType ) + rPathMap[ rInfo.mnEventId ] = resolveVBAMacro( mpShell, maLibraryName, rModuleName, rInfo.maMacroName ); + } + return rPathMap; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbafillformat.cxx b/vbahelper/source/vbahelper/vbafillformat.cxx new file mode 100644 index 000000000..e72be2c90 --- /dev/null +++ b/vbahelper/source/vbahelper/vbafillformat.cxx @@ -0,0 +1,187 @@ +/* -*- 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/beans/XPropertySet.hpp> +#include <com/sun/star/awt/Gradient.hpp> +#include <com/sun/star/awt/GradientStyle.hpp> +#include <ooo/vba/office/MsoGradientStyle.hpp> +#include "vbafillformat.hxx" +#include "vbacolorformat.hxx" + +using namespace ooo::vba; +using namespace com::sun::star; + +ScVbaFillFormat::ScVbaFillFormat( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< drawing::XShape >& xShape ) : ScVbaFillFormat_BASE( xParent, xContext ), m_xShape( xShape ) +{ + m_xPropertySet.set( xShape, uno::UNO_QUERY_THROW ); + m_nFillStyle = drawing::FillStyle_SOLID; + m_nForeColor = 0; + m_nGradientAngle = 0; +} + +void +ScVbaFillFormat::setFillStyle( drawing::FillStyle nFillStyle ) +{ + m_nFillStyle = nFillStyle; + if( m_nFillStyle == drawing::FillStyle_GRADIENT ) + { + m_xPropertySet->setPropertyValue( "FillStyle" , uno::makeAny( drawing::FillStyle_GRADIENT ) ); + awt::Gradient aGradient; + // AXIAL + // RADIAL + // ELLIPTICAL + // SQUARE + // RECT + aGradient.Style = awt::GradientStyle_LINEAR; + aGradient.StartColor = ForeColor()->getRGB(); + aGradient.EndColor = BackColor()->getRGB(); + aGradient.Angle = m_nGradientAngle; + aGradient.Border = 0; + aGradient.XOffset = 0; + aGradient.YOffset = 0; + aGradient.StartIntensity = 100; + aGradient.EndIntensity = 100; + aGradient.StepCount = 1; + m_xPropertySet->setPropertyValue( "FillGradient" , uno::makeAny( aGradient ) ); + } + else if( m_nFillStyle == drawing::FillStyle_SOLID ) + { + m_xPropertySet->setPropertyValue( "FillStyle" , uno::makeAny(drawing::FillStyle_SOLID) ); + } +} + +void +ScVbaFillFormat::setForeColorAndInternalStyle( sal_Int32 nForeColor ) +{ + m_nForeColor = nForeColor; + setFillStyle( m_nFillStyle ); +} + +// Attributes +sal_Bool SAL_CALL +ScVbaFillFormat::getVisible() +{ + drawing::FillStyle nFillStyle; + m_xPropertySet->getPropertyValue( "FillStyle" ) >>= nFillStyle; + if( nFillStyle == drawing::FillStyle_NONE ) + return false; + return true; +} + +void SAL_CALL +ScVbaFillFormat::setVisible( sal_Bool _visible ) +{ + drawing::FillStyle aFillStyle; + m_xPropertySet->getPropertyValue( "FillStyle" ) >>= aFillStyle; + if( !_visible ) + { + m_xPropertySet->setPropertyValue( "FillStyle" , uno::makeAny( drawing::FillStyle_NONE ) ); + } + else + { + if( aFillStyle == drawing::FillStyle_NONE ) + { + setFillStyle( m_nFillStyle ); + } + } +} + +double SAL_CALL +ScVbaFillFormat::getTransparency() +{ + sal_Int16 nTransparence = 0; + double dTransparence = 0; + m_xPropertySet->getPropertyValue( "FillTransparence" ) >>= nTransparence; + dTransparence = static_cast<double>( nTransparence ); + dTransparence /= 100; + return dTransparence; +} + +void SAL_CALL +ScVbaFillFormat::setTransparency( double _transparency ) +{ + sal_Int16 nTransparence = static_cast< sal_Int16 >( _transparency * 100 ); + m_xPropertySet->setPropertyValue( "FillTransparence" , uno::makeAny( nTransparence ) ); +} + + +// Methods +void SAL_CALL +ScVbaFillFormat::Solid() +{ + setFillStyle( drawing::FillStyle_SOLID ); +} + +void SAL_CALL +ScVbaFillFormat::TwoColorGradient( sal_Int32 style, sal_Int32 /*variant*/ ) +{ + if( style == office::MsoGradientStyle::msoGradientHorizontal ) + { + m_nGradientAngle = 0; + setFillStyle( drawing::FillStyle_GRADIENT ); + } + else if( style == office::MsoGradientStyle::msoGradientVertical ) + { + m_nGradientAngle = 900; + setFillStyle( drawing::FillStyle_GRADIENT ); + } + else if( style == office::MsoGradientStyle::msoGradientDiagonalDown ) + { + m_nGradientAngle = 450; + setFillStyle( drawing::FillStyle_GRADIENT ); + } + else if( style == office::MsoGradientStyle::msoGradientDiagonalUp ) + { + m_nGradientAngle = 900 + 450; + setFillStyle( drawing::FillStyle_GRADIENT ); + } +} + +uno::Reference< msforms::XColorFormat > SAL_CALL +ScVbaFillFormat::BackColor() +{ + if( !m_xColorFormat.is() ) + m_xColorFormat.set( new ScVbaColorFormat( getParent(), mxContext, this, m_xShape, ColorFormatType::FILLFORMAT_BACKCOLOR ) ); + return m_xColorFormat; +} + +uno::Reference< msforms::XColorFormat > SAL_CALL +ScVbaFillFormat::ForeColor() +{ + if( !m_xColorFormat.is() ) + m_xColorFormat.set( new ScVbaColorFormat( getParent(), mxContext, this, m_xShape, ColorFormatType::FILLFORMAT_FORECOLOR ) ); + return m_xColorFormat; +} + +OUString +ScVbaFillFormat::getServiceImplName() +{ + return "ScVbaFillFormat"; +} + +uno::Sequence< OUString > +ScVbaFillFormat::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.FillFormat" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbafillformat.hxx b/vbahelper/source/vbahelper/vbafillformat.hxx new file mode 100644 index 000000000..e1635a80d --- /dev/null +++ b/vbahelper/source/vbahelper/vbafillformat.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_VBAHELPER_SOURCE_VBAHELPER_VBAFILLFORMAT_HXX +#define INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBAFILLFORMAT_HXX + +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/drawing/FillStyle.hpp> +#include <ooo/vba/msforms/XFillFormat.hpp> +#include <vbahelper/vbahelperinterface.hxx> + +typedef InheritedHelperInterfaceWeakImpl< ov::msforms::XFillFormat > ScVbaFillFormat_BASE; + +class ScVbaFillFormat : public ScVbaFillFormat_BASE +{ +private: + css::uno::Reference< css::drawing::XShape > m_xShape; + css::uno::Reference< css::beans::XPropertySet > m_xPropertySet; + css::uno::Reference< ov::msforms::XColorFormat > m_xColorFormat; + css::drawing::FillStyle m_nFillStyle; + sal_Int32 m_nForeColor; + sal_Int16 m_nGradientAngle; +private: + /// @throws css::uno::RuntimeException + void setFillStyle( css::drawing::FillStyle nFillStyle ); +protected: + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + +public: + ScVbaFillFormat( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::drawing::XShape >& xShape ); + + /// @throws css::uno::RuntimeException + void setForeColorAndInternalStyle( sal_Int32 nForeColor ); + // Attributes + virtual sal_Bool SAL_CALL getVisible() override; + virtual void SAL_CALL setVisible( sal_Bool _visible ) override; + virtual double SAL_CALL getTransparency() override; + virtual void SAL_CALL setTransparency( double _transparency ) override; + + // Methods + virtual void SAL_CALL Solid() override; + virtual void SAL_CALL TwoColorGradient( sal_Int32 style, sal_Int32 variant ) override; + virtual css::uno::Reference< ov::msforms::XColorFormat > SAL_CALL BackColor() override; + virtual css::uno::Reference< ov::msforms::XColorFormat > SAL_CALL ForeColor() override; + +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBAFILLFORMAT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbafontbase.cxx b/vbahelper/source/vbahelper/vbafontbase.cxx new file mode 100644 index 000000000..ea4278a47 --- /dev/null +++ b/vbahelper/source/vbahelper/vbafontbase.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 <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/awt/FontWeight.hpp> +#include <com/sun/star/awt/FontStrikeout.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <vbahelper/vbafontbase.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + + +// form controls use other property name as the remaining OOo API +#define VBAFONTBASE_PROPNAME( ascii_normal, ascii_control ) \ + mbFormControl ? OUString( ascii_control ) : OUString( ascii_normal ) + +VbaFontBase::VbaFontBase( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< css::container::XIndexAccess >& xPalette, + const uno::Reference< beans::XPropertySet >& xPropertySet, + bool bFormControl ) : + VbaFontBase_BASE( xParent, xContext ), + mxFont( xPropertySet, uno::UNO_SET_THROW ), + mxPalette( xPalette, uno::UNO_SET_THROW ), + mbFormControl( bFormControl ) +{ +} + +VbaFontBase::~VbaFontBase() +{ +} + +void SAL_CALL +VbaFontBase::setSuperscript( const uno::Any& aValue ) +{ + // not supported in form controls + if( mbFormControl ) + return; + + bool bValue = false; + aValue >>= bValue; + sal_Int16 nValue = NORMAL; + sal_Int8 nValue2 = NORMALHEIGHT; + + if( bValue ) + { + nValue = SUPERSCRIPT; + nValue2 = SUPERSCRIPTHEIGHT; + } + mxFont->setPropertyValue( "CharEscapement" , uno::Any(nValue) ); + mxFont->setPropertyValue( "CharEscapementHeight" , uno::Any(nValue2) ); +} + +uno::Any SAL_CALL +VbaFontBase::getSuperscript() +{ + short nValue = NORMAL; + // not supported in form controls + if( !mbFormControl ) + mxFont->getPropertyValue( "CharEscapement" ) >>= nValue; + return uno::makeAny( nValue == SUPERSCRIPT ); +} + +void SAL_CALL +VbaFontBase::setSubscript( const uno::Any& aValue ) +{ + // not supported in form controls + if( mbFormControl ) + return; + + bool bValue = false; + aValue >>= bValue; + sal_Int16 nValue = NORMAL; + sal_Int8 nValue2 = NORMALHEIGHT; + + if( bValue ) + { + nValue= SUBSCRIPT; + nValue2 = SUBSCRIPTHEIGHT; + } + + mxFont->setPropertyValue( "CharEscapementHeight" , uno::Any(nValue2) ); + mxFont->setPropertyValue( "CharEscapement" , uno::Any(nValue) ); + +} + +uno::Any SAL_CALL +VbaFontBase::getSubscript() +{ + short nValue = NORMAL; + // not supported in form controls + if( !mbFormControl ) + mxFont->getPropertyValue( "CharEscapement" ) >>= nValue; + return uno::makeAny( nValue == SUBSCRIPT ); +} + +void SAL_CALL +VbaFontBase::setSize( const uno::Any& aValue ) +{ + // form controls need a sal_Int16 containing points, other APIs need a float + uno::Any aVal( aValue ); + if( mbFormControl ) + { + float fVal = 0.0; + aVal >>= fVal; + aVal <<= static_cast< sal_Int16 >( fVal ); + } + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharHeight", "FontHeight" ), aVal ); +} + +uno::Any SAL_CALL +VbaFontBase::getSize() +{ + return mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharHeight", "FontHeight" ) ); +} + +void SAL_CALL +VbaFontBase::setColorIndex( const uno::Any& _colorindex ) +{ + sal_Int32 nIndex = 0; + _colorindex >>= nIndex; + + --nIndex; // OOo indices are zero bases + + // setColor expects colors in XL RGB values + // #FIXME this is daft we convert OO RGB val to XL RGB val and + // then back again to OO RGB value + setColor( OORGBToXLRGB(mxPalette->getByIndex( nIndex )) ); +} + + +uno::Any SAL_CALL +VbaFontBase::getColorIndex() +{ + sal_Int32 nColor = 0; + + XLRGBToOORGB( getColor() ) >>= nColor; + sal_Int32 nElems = mxPalette->getCount(); + sal_Int32 nIndex = -1; + for ( sal_Int32 count=0; count<nElems; ++count ) + { + sal_Int32 nPaletteColor = 0; + mxPalette->getByIndex( count ) >>= nPaletteColor; + if ( nPaletteColor == nColor ) + { + nIndex = count + 1; // 1 based + break; + } + } + return uno::makeAny( nIndex ); +} + +void SAL_CALL +VbaFontBase::setBold( const uno::Any& aValue ) +{ + bool bValue = false; + aValue >>= bValue; + double fBoldValue = awt::FontWeight::NORMAL; + if( bValue ) + fBoldValue = awt::FontWeight::BOLD; + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharWeight", "FontWeight" ), uno::Any( fBoldValue ) ); + +} + +uno::Any SAL_CALL +VbaFontBase::getBold() +{ + double fValue = 0.0; + mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharWeight", "FontWeight" ) ) >>= fValue; + return uno::makeAny( fValue == awt::FontWeight::BOLD ); +} + +void SAL_CALL +VbaFontBase::setStrikethrough( const uno::Any& aValue ) +{ + bool bValue = false; + aValue >>= bValue; + short nValue = awt::FontStrikeout::NONE; + if( bValue ) + nValue = awt::FontStrikeout::SINGLE; + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharStrikeout", "FontStrikeout" ), uno::Any( nValue ) ); +} + +uno::Any SAL_CALL +VbaFontBase::getStrikethrough() +{ + short nValue = 0; + mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharStrikeout", "FontStrikeout" ) ) >>= nValue; + return uno::Any( nValue == awt::FontStrikeout::SINGLE ); +} + +void SAL_CALL +VbaFontBase::setShadow( const uno::Any& aValue ) +{ + if( !mbFormControl ) + mxFont->setPropertyValue( "CharShadowed" , aValue ); +} + +uno::Any SAL_CALL +VbaFontBase::getShadow() +{ + return mbFormControl ? uno::Any( false ) : mxFont->getPropertyValue( "CharShadowed" ); +} + +void SAL_CALL +VbaFontBase::setItalic( const uno::Any& aValue ) +{ + bool bValue = false; + aValue >>= bValue; + awt::FontSlant nValue = awt::FontSlant_NONE; + if( bValue ) + nValue = awt::FontSlant_ITALIC; + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharPosture", "FontSlant" ), uno::Any( static_cast<short>(nValue) ) ); +} + +uno::Any SAL_CALL +VbaFontBase::getItalic() +{ + awt::FontSlant aFS; + mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharPosture", "FontSlant" ) ) >>= aFS; + return uno::makeAny( aFS == awt::FontSlant_ITALIC ); +} + +void SAL_CALL +VbaFontBase::setName( const uno::Any& aValue ) +{ + OUString sString; + aValue >>= sString; + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharFontName", "FontName" ), aValue ); +} + +uno::Any SAL_CALL +VbaFontBase::getName() +{ + return mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharFontName", "FontName" ) ); +} + +uno::Any +VbaFontBase::getColor() +{ + uno::Any aAny = OORGBToXLRGB( mxFont->getPropertyValue( VBAFONTBASE_PROPNAME( "CharColor", "TextColor" ) ) ); + return aAny; +} + +void +VbaFontBase::setColor( const uno::Any& _color ) +{ + mxFont->setPropertyValue( VBAFONTBASE_PROPNAME( "CharColor", "TextColor" ), XLRGBToOORGB(_color) ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbaglobalbase.cxx b/vbahelper/source/vbahelper/vbaglobalbase.cxx new file mode 100644 index 000000000..902c07d82 --- /dev/null +++ b/vbahelper/source/vbahelper/vbaglobalbase.cxx @@ -0,0 +1,167 @@ +/* -*- 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 <vbahelper/vbaglobalbase.hxx> +#include <sal/macros.h> + +#include <comphelper/sequence.hxx> +#include <cppuhelper/component_context.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + +using namespace com::sun::star; +using namespace ooo::vba; + +// special key to return the Application +const char sAppService[] = "ooo.vba.Application"; +static const OUStringLiteral gsApplication( "Application" ); + +VbaGlobalsBase::VbaGlobalsBase( +const uno::Reference< ov::XHelperInterface >& xParent, +const uno::Reference< uno::XComponentContext >& xContext, const OUString& sDocCtxName ) + : Globals_BASE( xParent, xContext ) + , msDocCtxName( sDocCtxName ) +{ + // overwrite context with custom one ( that contains the application ) + // wrap the service manager as we don't want the disposing context to tear down the 'normal' ServiceManager ( or at least that's what the code appears like it wants to do ) + uno::Reference< uno::XInterface > aSrvMgr; + if ( xContext.is() && xContext->getServiceManager().is() ) + { + aSrvMgr = xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.comp.stoc.OServiceManagerWrapper" , xContext ); + } + + ::cppu::ContextEntry_Init aHandlerContextInfo[] = + { + ::cppu::ContextEntry_Init( gsApplication, uno::Any() ), + ::cppu::ContextEntry_Init( sDocCtxName, uno::Any() ), + ::cppu::ContextEntry_Init( "/singletons/com.sun.star.lang.theServiceManager" , uno::makeAny( aSrvMgr ) ) + }; + // don't pass a delegate, this seems to introduce yet another cyclic dependency ( and + // some strange behavior + mxContext = ::cppu::createComponentContext( + aHandlerContextInfo, + SAL_N_ELEMENTS( aHandlerContextInfo ), nullptr ); + if ( aSrvMgr.is() ) + { + try + { + uno::Reference< beans::XPropertySet >( + aSrvMgr, uno::UNO_QUERY_THROW )-> + setPropertyValue( "DefaultContext", uno::makeAny( mxContext ) ); + } + catch ( uno::RuntimeException & ) + { + throw; + } + catch ( uno::Exception & ) + { + uno::Any e(cppu::getCaughtException()); + throw lang::WrappedTargetRuntimeException( + ("VbaGlobalsBase ctor, setting OServiceManagerWrapper" + " DefaultContext failed"), + uno::Reference< uno::XInterface >(), e); + } + } +} + +VbaGlobalsBase::~VbaGlobalsBase() +{ + try + { + uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY ); + if ( xNameContainer.is() ) + { + // release document reference (we don't want the component context trying to dispose that) + xNameContainer->removeByName( msDocCtxName ); + // release application reference, as it is holding onto the context + xNameContainer->removeByName( gsApplication ); + } + } + catch ( const uno::Exception& ) + { + } +} + +void +VbaGlobalsBase::init( const uno::Sequence< beans::PropertyValue >& aInitArgs ) +{ + for ( const auto& rInitArg : aInitArgs ) + { + uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY_THROW ); + if ( rInitArg.Name == gsApplication ) + { + xNameContainer->replaceByName( gsApplication, rInitArg.Value ); + uno::Reference< XHelperInterface > xParent( rInitArg.Value, uno::UNO_QUERY ); + mxParent = xParent; + } + else + xNameContainer->replaceByName( rInitArg.Name, rInitArg.Value ); + } +} + +uno::Reference< uno::XInterface > SAL_CALL +VbaGlobalsBase::createInstance( const OUString& aServiceSpecifier ) +{ + uno::Reference< uno::XInterface > xReturn; + if ( aServiceSpecifier == sAppService ) + { + // try to extract the Application from the context + uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY ); + xNameContainer->getByName( gsApplication ) >>= xReturn; + } + else if ( hasServiceName( aServiceSpecifier ) ) + xReturn = mxContext->getServiceManager()->createInstanceWithContext( aServiceSpecifier, mxContext ); + return xReturn; +} + +uno::Reference< uno::XInterface > SAL_CALL +VbaGlobalsBase::createInstanceWithArguments( const OUString& aServiceSpecifier, const uno::Sequence< uno::Any >& Arguments ) +{ + + uno::Reference< uno::XInterface > xReturn; + if ( aServiceSpecifier == sAppService ) + { + // try to extract the Application from the context + uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY ); + xNameContainer->getByName( gsApplication ) >>= xReturn; + } + else if ( hasServiceName( aServiceSpecifier ) ) + xReturn = mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( aServiceSpecifier, Arguments, mxContext ); + return xReturn; +} + +uno::Sequence< OUString > SAL_CALL +VbaGlobalsBase::getAvailableServiceNames( ) +{ + uno::Sequence< OUString > serviceNames { "ooo.vba.msforms.UserForm" }; + return serviceNames; +} + +bool +VbaGlobalsBase::hasServiceName( const OUString& serviceName ) +{ + uno::Sequence< OUString > sServiceNames( getAvailableServiceNames() ); + return comphelper::findValue(sServiceNames, serviceName) != -1; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbahelper.cxx b/vbahelper/source/vbahelper/vbahelper.cxx new file mode 100644 index 000000000..f99701866 --- /dev/null +++ b/vbahelper/source/vbahelper/vbahelper.cxx @@ -0,0 +1,1125 @@ +/* -*- 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/util/URLTransformer.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XModel2.hpp> +#include <com/sun/star/script/BasicErrorException.hpp> +#include <com/sun/star/script/XDefaultProperty.hpp> +#include <com/sun/star/script/XInvocation.hpp> +#include <com/sun/star/script/Converter.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/theIntrospection.hpp> +#include <com/sun/star/util/MeasureUnit.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/awt/XDialog.hpp> +#include <com/sun/star/awt/XUnitConversion.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include <ooo/vba/XHelperInterface.hpp> + +#include <comphelper/automationinvokedzone.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/sequence.hxx> + +#include <sfx2/objsh.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/app.hxx> +#include <sfx2/sfxsids.hrc> +#include <svl/stritem.hxx> +#include <svl/eitem.hxx> +#include <svl/intitem.hxx> +#include <svl/itemset.hxx> +#include <sfx2/docfac.hxx> +#include <sfx2/viewfac.hxx> + +#include <basic/sbstar.hxx> +#include <basic/basmgr.hxx> +#include <basic/sbmod.hxx> +#include <basic/sbuno.hxx> +#include <basic/sberrors.hxx> +#include <rtl/ustrbuf.hxx> +#include <sfx2/viewsh.hxx> +#include <sal/log.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <vcl/syswin.hxx> +#include <tools/diagnose_ex.h> +#include <vbahelper/vbahelper.hxx> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + + +namespace ooo::vba +{ + +namespace { const double factor = 2540.0 / 72.0; } + +// helper method to determine if the view ( calc ) is in print-preview mode +static bool isInPrintPreview( SfxViewFrame* pView ) +{ + sal_uInt16 nViewNo = SID_VIEWSHELL1 - SID_VIEWSHELL0; + if ( pView->GetObjectShell()->GetFactory().GetViewFactoryCount() > +nViewNo && !pView->GetObjectShell()->IsInPlaceActive() ) + { + SfxViewFactory &rViewFactory = + pView->GetObjectShell()->GetFactory().GetViewFactory(nViewNo); + if ( pView->GetCurViewId() == rViewFactory.GetOrdinal() ) + return true; + } + return false; +} + +uno::Reference< beans::XIntrospectionAccess > +getIntrospectionAccess( const uno::Any& aObject ) +{ + static uno::Reference< beans::XIntrospection > xIntrospection( beans::theIntrospection::get( comphelper::getProcessComponentContext() ) ); + return xIntrospection->inspect( aObject ); +} + +uno::Reference< script::XTypeConverter > const & +getTypeConverter( const uno::Reference< uno::XComponentContext >& xContext ) +{ + static uno::Reference< script::XTypeConverter > xTypeConv( script::Converter::create(xContext) ); + return xTypeConv; +} +const uno::Any& +aNULL() +{ + static uno::Any aNULLL = uno::makeAny( uno::Reference< uno::XInterface >() ); + return aNULLL; +} + +void dispatchExecute(SfxViewShell const * pViewShell, sal_uInt16 nSlot) +{ + SfxViewFrame* pViewFrame = nullptr; + if ( pViewShell ) + pViewFrame = pViewShell->GetViewFrame(); + if ( pViewFrame ) + { + SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher(); + if( pDispatcher ) + { + pDispatcher->Execute( nSlot , SfxCallMode::SYNCHRON ); + } + } +} + +void +dispatchRequests (const uno::Reference< frame::XModel>& xModel, const OUString & aUrl, const uno::Sequence< beans::PropertyValue >& sProps ) +{ + util::URL url; + url.Complete = aUrl; + uno::Reference<frame::XController> xController = xModel->getCurrentController(); + uno::Reference<frame::XFrame> xFrame = xController->getFrame(); + uno::Reference<frame::XDispatchProvider> xDispatchProvider (xFrame,uno::UNO_QUERY_THROW); + try + { + uno::Reference<uno::XComponentContext > xContext( + comphelper::getProcessComponentContext() ); + uno::Reference<util::XURLTransformer> xParser( util::URLTransformer::create(xContext) ); + xParser->parseStrict (url); + } + catch (const uno::Exception&) + { + return; + } + + uno::Reference<frame::XDispatch> xDispatcher = xDispatchProvider->queryDispatch(url,"",0); + + uno::Sequence<beans::PropertyValue> dispatchProps(1); + + sal_Int32 nProps = sProps.getLength(); + if ( nProps ) + { + dispatchProps.realloc( nProps + 1 ); + std::copy(sProps.begin(), sProps.end(), dispatchProps.begin()); + } + + if ( xDispatcher.is() ) + { + xDispatcher->dispatch( url, dispatchProps ); + } +} + +void +dispatchRequests( const uno::Reference< frame::XModel>& xModel, const OUString& aUrl ) +{ + uno::Sequence<beans::PropertyValue> dispatchProps; + dispatchRequests( xModel, aUrl, dispatchProps ); +} + +uno::Reference< frame::XModel > +getCurrentDoc( const OUString& sKey ) +{ + uno::Reference< frame::XModel > xModel; + SbxObject* pBasic = dynamic_cast< SbxObject* > ( SfxApplication::GetBasic() ); + SbxObject* basicChosen = pBasic ; + if ( basicChosen == nullptr) + { + SAL_INFO("vbahelper", "getModelFromBasic() StarBASIC* is NULL" ); + return xModel; + } + SbxObject* p = pBasic; + SbxObject* pParent = p->GetParent(); + SbxObject* pParentParent = pParent ? pParent->GetParent() : nullptr; + + if( pParentParent ) + { + basicChosen = pParentParent; + } + else if( pParent ) + { + basicChosen = pParent; + } + + + uno::Any aModel; + SbxVariable *pCompVar = basicChosen->Find( sKey, SbxClassType::Object ); + + if ( pCompVar ) + { + aModel = sbxToUnoValue( pCompVar ); + if ( !( aModel >>= xModel ) || !xModel.is() ) + { + throw uno::RuntimeException( + "Can't extract model from basic ( it's obviously not set yet therefore don't know the current document context)" ); + } + SAL_INFO("vbahelper", "Have model points to url " << xModel->getURL()); + } + else + { + SAL_INFO("vbahelper", "Failed to get " << sKey); + throw uno::RuntimeException( "Can't determine the currently selected document" ); + } + return xModel; +} + +/// @throws uno::RuntimeException +static uno::Reference< frame::XModel > +getCurrentDocCtx( const OUString& ctxName, const uno::Reference< uno::XComponentContext >& xContext ) +{ + uno::Reference< frame::XModel > xModel; + // try fallback to calling doc + css::uno::Reference< css::container::XNameAccess > xNameAccess( xContext, css::uno::UNO_QUERY_THROW ); + xModel.set( xNameAccess->getByName( ctxName ), uno::UNO_QUERY_THROW ); + return xModel; +} + +uno::Reference< frame::XModel > +getThisExcelDoc( const uno::Reference< uno::XComponentContext >& xContext ) +{ + return getCurrentDocCtx( "ExcelDocumentContext" , xContext ); +} + +uno::Reference< frame::XModel > +getThisWordDoc( const uno::Reference< uno::XComponentContext >& xContext ) +{ + return getCurrentDocCtx( "WordDocumentContext" , xContext ); +} + + uno::Reference< frame::XModel > +getCurrentExcelDoc( const uno::Reference< uno::XComponentContext >& xContext ) +{ + uno::Reference< frame::XModel > xModel; + try + { + xModel = getCurrentDoc( "ThisExcelDoc" ); + } + catch (const uno::Exception&) + { + try + { + xModel = getThisExcelDoc( xContext ); + } + catch (const uno::Exception&) + { + } + } + return xModel; +} + + uno::Reference< frame::XModel > +getCurrentWordDoc( const uno::Reference< uno::XComponentContext >& xContext ) +{ + uno::Reference< frame::XModel > xModel; + try + { + xModel = getCurrentDoc( "ThisWordDoc" ); + } + catch (const uno::Exception&) + { + try + { + xModel = getThisWordDoc( xContext ); + } + catch (const uno::Exception&) + { + } + } + return xModel; +} + +sal_Int32 +OORGBToXLRGB( sal_Int32 nCol ) +{ + sal_Int32 nAutoBits = nCol; + nAutoBits &= 0xFF000000; + sal_Int32 nRed = nCol; + nRed &= 0x00FF0000; + nRed >>= 16; + sal_Int32 nGreen = nCol; + nGreen &= 0x0000FF00; + nGreen >>= 8; + sal_Int32 nBlue = nCol; + nBlue &= 0x000000FF; + sal_Int32 nRGB = ( nAutoBits | (nBlue << 16) | (nGreen << 8) | nRed ); + return nRGB; +} + +sal_Int32 +XLRGBToOORGB( sal_Int32 nCol ) +{ + sal_Int32 nAutoBits = nCol; + nAutoBits &= 0xFF000000; + + sal_Int32 nBlue = nCol; + nBlue &= 0x00FF0000; + nBlue >>= 16; + sal_Int32 nGreen = nCol; + nGreen &= 0x0000FF00; + nGreen >>= 8; + sal_Int32 nRed = nCol; + nRed &= 0x000000FF; + sal_Int32 nRGB = ( nAutoBits | (nRed << 16) | (nGreen << 8) | nBlue ); + return nRGB; +} +uno::Any +OORGBToXLRGB( const uno::Any& aCol ) +{ + sal_Int32 nCol(0); + aCol >>= nCol; + nCol = OORGBToXLRGB( nCol ); + return uno::makeAny( nCol ); +} +uno::Any +XLRGBToOORGB( const uno::Any& aCol ) +{ + sal_Int32 nCol(0); + aCol >>= nCol; + nCol = XLRGBToOORGB( nCol ); + return uno::makeAny( nCol ); +} + +void PrintOutHelper( SfxViewShell const * pViewShell, const uno::Any& From, const uno::Any& To, const uno::Any& Copies, const uno::Any& Preview, const uno::Any& /*ActivePrinter*/, const uno::Any& /*PrintToFile*/, const uno::Any& Collate, const uno::Any& PrToFileName, bool bUseSelection ) +{ + sal_Int32 nTo = 0; + sal_Int32 nFrom = 0; + sal_Int16 nCopies = 1; + bool bPreview = false; + bool bCollate = false; + bool bSelection = bUseSelection; + From >>= nFrom; + To >>= nTo; + Copies >>= nCopies; + Preview >>= bPreview; + if ( nCopies > 1 ) // Collate only useful when more that 1 copy + Collate >>= bCollate; + + OUString sRange( "-" ); + OUString sFileName; + + if ( nFrom || nTo ) + { + if ( nFrom ) + sRange = OUString::number( nFrom ) + sRange; + if ( nTo ) + sRange += OUString::number( nTo ); + } + + PrToFileName >>= sFileName; + SfxViewFrame* pViewFrame = nullptr; + if ( pViewShell ) + pViewFrame = pViewShell->GetViewFrame(); + if ( !pViewFrame ) + return; + + SfxAllItemSet aArgs( SfxGetpApp()->GetPool() ); + + SfxBoolItem sfxCollate( SID_PRINT_COLLATE, bCollate ); + aArgs.Put( sfxCollate, sfxCollate.Which() ); + SfxInt16Item sfxCopies( SID_PRINT_COPIES, nCopies ); + aArgs.Put( sfxCopies, sfxCopies.Which() ); + if ( !sFileName.isEmpty() ) + { + SfxStringItem sfxFileName( SID_FILE_NAME, sFileName); + aArgs.Put( sfxFileName, sfxFileName.Which() ); + + } + if ( !sRange.isEmpty() ) + { + SfxStringItem sfxRange( SID_PRINT_PAGES, sRange ); + aArgs.Put( sfxRange, sfxRange.Which() ); + } + SfxBoolItem sfxSelection( SID_SELECTION, bSelection ); + aArgs.Put( sfxSelection, sfxSelection.Which() ); + SfxBoolItem sfxAsync( SID_ASYNCHRON, false ); + aArgs.Put( sfxAsync, sfxAsync.Which() ); + SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher(); + + if ( pDispatcher ) + { + if ( bPreview ) + { + if ( !pViewFrame->GetFrame().IsInPlace() ) + { + // #TODO is this necessary ( calc specific ) +// SC_MOD()->InputEnterHandler(); + pViewFrame->GetDispatcher()->Execute( SID_VIEWSHELL1, SfxCallMode::SYNCHRON ); + WaitUntilPreviewIsClosed( pViewFrame ); + } + } + else + pDispatcher->Execute( sal_uInt16(SID_PRINTDOC), SfxCallMode::SYNCHRON, aArgs ); + } + + + // #FIXME #TODO + // 1 ActivePrinter ( how/can we switch a printer via API? ) + // 2 PrintToFile ( ms behaviour if this option is specified but no + // filename supplied 'PrToFileName' then the user will be prompted ) + // 3 Need to check behaviour of Selected sheets with range ( e.g. From & To + // values ) in oOO these options are mutually exclusive + // 4 There is a pop up to do with transparent objects in the print source + // should be able to disable that via configuration for the duration + // of this method +} + +void PrintPreviewHelper( const css::uno::Any& /*EnableChanges*/, SfxViewShell const * pViewShell ) +{ + SfxViewFrame* pViewFrame = nullptr; + if ( pViewShell ) + pViewFrame = pViewShell->GetViewFrame(); + if ( pViewFrame ) + { + if ( !pViewFrame->GetFrame().IsInPlace() ) + { + dispatchExecute( pViewShell, SID_VIEWSHELL1 ); + WaitUntilPreviewIsClosed( pViewFrame ); + } + } +} + +void WaitUntilPreviewIsClosed( SfxViewFrame* pViewFrame ) +{ + while ( pViewFrame && isInPrintPreview( pViewFrame ) ) + Application::Yield(); +} + +bool extractBoolFromAny( const uno::Any& rAny ) +{ + switch( rAny.getValueType().getTypeClass() ) + { + case uno::TypeClass_BOOLEAN: + return rAny.get< bool >(); + case uno::TypeClass_FLOAT: + return rAny.get< float >() != 0.0; + case uno::TypeClass_DOUBLE: + return rAny.get< double >() != 0.0; + case uno::TypeClass_BYTE: + case uno::TypeClass_SHORT: + case uno::TypeClass_LONG: + return rAny.get< sal_Int32 >() != 0; + case uno::TypeClass_HYPER: + return rAny.get< sal_Int64 >() != 0; + default:; + } + throw uno::RuntimeException( "Invalid type, cannot convert to boolean." , nullptr ); +} + +OUString extractStringFromAny( const uno::Any& rAny, bool bUppercaseBool ) +{ + switch( rAny.getValueType().getTypeClass() ) + { + case uno::TypeClass_STRING: + return rAny.get< OUString >(); + case uno::TypeClass_BOOLEAN: + return bUppercaseBool ? + (rAny.get< bool >() ? OUString( "TRUE" ) : OUString( "FALSE" )) : + OUString::boolean( rAny.get< bool >() ); + case uno::TypeClass_FLOAT: + return OUString::number( rAny.get< float >() ); + case uno::TypeClass_DOUBLE: + return OUString::number( rAny.get< double >() ); + case uno::TypeClass_BYTE: + case uno::TypeClass_SHORT: + case uno::TypeClass_LONG: + return OUString::number( rAny.get< sal_Int32 >() ); + case uno::TypeClass_HYPER: + return OUString::number( rAny.get< sal_Int64 >() ); + default:; + } + throw uno::RuntimeException( "Invalid type, cannot convert to string." , nullptr ); +} + +OUString extractStringFromAny( const uno::Any& rAny, const OUString& rDefault, bool bUppercaseBool ) +{ + return rAny.hasValue() ? extractStringFromAny( rAny, bUppercaseBool ) : rDefault; +} + +OUString getAnyAsString( const uno::Any& pvargItem ) +{ + return extractStringFromAny( pvargItem ); +} + + +OUString +ContainerUtilities::getUniqueName( const uno::Sequence< OUString >& _slist, const OUString& _sElementName, const OUString& _sSuffixSeparator) +{ + return getUniqueName(_slist, _sElementName, _sSuffixSeparator, sal_Int32(2)); +} + +OUString +ContainerUtilities::getUniqueName( const uno::Sequence< OUString >& _slist, const OUString& _sElementName, const OUString& _sSuffixSeparator, sal_Int32 _nStartSuffix) +{ + if ( !_slist.hasElements() ) + return _sElementName; + + OUString scompname = _sElementName; + sal_Int32 a = _nStartSuffix; + + for (;;) + { + if (FieldInList(_slist, scompname) == -1) + return scompname; + + scompname = _sElementName + _sSuffixSeparator + OUString::number( a++ ); + } +} + +sal_Int32 +ContainerUtilities::FieldInList( const uno::Sequence< OUString >& SearchList, const OUString& SearchString ) +{ + // I wonder why comparing lexicographically is done + // when it's a match, is it interesting? + return comphelper::findValue(SearchList, SearchString); +} + +static bool NeedEsc(sal_Unicode cCode) +{ + return OUString(".^$+\\|{}()").indexOf(cCode) != -1; +} + +OUString VBAToRegexp(const OUString &rIn) +{ + OUStringBuffer sResult; + const sal_Unicode *start = rIn.getStr(); + const sal_Unicode *end = start + rIn.getLength(); + + int seenright = 0; + + while (start < end) + { + switch (*start) + { + case '?': + sResult.append('.'); + start++; + break; + case '*': + sResult.append(".*"); + start++; + break; + case '#': + sResult.append("[0-9]"); + start++; + break; + case '~': + sResult.append('\\'); + sResult.append(*(++start)); + start++; + break; + // dump the ~ and escape the next character + case ']': + sResult.append('\\'); + sResult.append(*start++); + break; + case '[': + sResult.append(*start++); + seenright = 0; + while (start < end && !seenright) + { + switch (*start) + { + case '[': + case '?': + case '*': + sResult.append('\\'); + sResult.append(*start); + break; + case ']': + sResult.append(*start); + seenright = 1; + break; + case '!': + sResult.append('^'); + break; + default: + if (NeedEsc(*start)) + sResult.append('\\'); + sResult.append(*start); + break; + } + start++; + } + break; + default: + if (NeedEsc(*start)) + sResult.append('\\'); + sResult.append(*start++); + } + } + + return sResult.makeStringAndClear( ); +} + +double getPixelTo100thMillimeterConversionFactor( const css::uno::Reference< css::awt::XDevice >& xDevice, bool bVertical) +{ + double fConvertFactor = 1.0; + if( bVertical ) + { + fConvertFactor = xDevice->getInfo().PixelPerMeterY/100000; + } + else + { + fConvertFactor = xDevice->getInfo().PixelPerMeterX/100000; + } + return fConvertFactor; +} + +double PointsToPixels( const css::uno::Reference< css::awt::XDevice >& xDevice, double fPoints, bool bVertical) +{ + double fConvertFactor = getPixelTo100thMillimeterConversionFactor( xDevice, bVertical ); + return PointsToHmm( fPoints ) * fConvertFactor; +} +double PixelsToPoints( const css::uno::Reference< css::awt::XDevice >& xDevice, double fPixels, bool bVertical) +{ + double fConvertFactor = getPixelTo100thMillimeterConversionFactor( xDevice, bVertical ); + return HmmToPoints(static_cast<sal_Int32>(fPixels/fConvertFactor)); +} + +sal_Int32 PointsToHmm( double fPoints ) +{ + return static_cast<sal_Int32>( fPoints * factor + 0.5 ); +} + +double HmmToPoints( sal_Int32 nHmm ) +{ + return nHmm / factor; +} + +ConcreteXShapeGeometryAttributes::ConcreteXShapeGeometryAttributes( const css::uno::Reference< css::drawing::XShape >& xShape ) +{ + m_pShapeHelper.reset( new ShapeHelper( xShape ) ); +} +ConcreteXShapeGeometryAttributes::~ConcreteXShapeGeometryAttributes() +{ +} + +PointerStyle getPointerStyle( const uno::Reference< frame::XModel >& xModel ) +{ + + PointerStyle nPointerStyle( PointerStyle::Arrow ); + try + { + const uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); + const uno::Reference< frame::XFrame > xFrame ( xController->getFrame(), uno::UNO_SET_THROW ); + const uno::Reference< awt::XWindow > xWindow ( xFrame->getContainerWindow(), uno::UNO_SET_THROW ); + // why the heck isn't there an XWindowPeer::getPointer, but a setPointer only? + const vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + nPointerStyle = pWindow->GetSystemWindow()->GetPointer(); + } + catch (const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("vbahelper"); + } + return nPointerStyle; +} + +// #FIXME this method looks wrong, shouldn't it just affect calc *or* writer +// document/frame/window(s) but not both ( and depending on what api called +// this ) +void setCursorHelper( const uno::Reference< frame::XModel >& xModel, PointerStyle nPointer, bool bOverWrite ) +{ + ::std::vector< uno::Reference< frame::XController > > aControllers; + + uno::Reference< frame::XModel2 > xModel2( xModel, uno::UNO_QUERY ); + if ( xModel2.is() ) + { + const uno::Reference< container::XEnumeration > xEnumControllers( xModel2->getControllers(), uno::UNO_SET_THROW ); + while ( xEnumControllers->hasMoreElements() ) + { + const uno::Reference< frame::XController > xController( xEnumControllers->nextElement(), uno::UNO_QUERY_THROW ); + aControllers.push_back( xController ); + } + } + else + { + if ( xModel.is() ) + { + const uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); + aControllers.push_back( xController ); + } + } + + for ( const auto& rController : aControllers ) + { + const uno::Reference< frame::XFrame > xFrame ( rController->getFrame(), uno::UNO_SET_THROW ); + const uno::Reference< awt::XWindow > xWindow ( xFrame->getContainerWindow(), uno::UNO_SET_THROW ); + + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); + SAL_WARN_IF( !pWindow, "vbahelper", "ScVbaApplication::setCursor: no window!" ); + if ( !pWindow ) + continue; + + pWindow->GetSystemWindow()->SetPointer( nPointer ); + pWindow->GetSystemWindow()->EnableChildPointerOverwrite( bOverWrite ); + } +} + +void setDefaultPropByIntrospection( const uno::Any& aObj, const uno::Any& aValue ) +{ + uno::Reference< beans::XIntrospectionAccess > xUnoAccess( getIntrospectionAccess( aObj ) ); + + // #MAYBE #FIXME sort of a bit of a hack, + uno::Reference< script::XDefaultProperty > xDflt( aObj, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xPropSet; + + if ( xUnoAccess.is() ) + xPropSet.set( xUnoAccess->queryAdapter( cppu::UnoType<beans::XPropertySet>::get()), uno::UNO_QUERY); + + if ( !xPropSet.is() ) + throw uno::RuntimeException(); + + xPropSet->setPropertyValue( xDflt->getDefaultPropertyName(), aValue ); +} + +uno::Any getPropertyValue( const uno::Sequence< beans::PropertyValue >& aProp, const OUString& aName ) +{ + auto pProp = std::find_if(aProp.begin(), aProp.end(), + [&aName](const beans::PropertyValue& rProp) { return rProp.Name == aName; }); + if (pProp != aProp.end()) + return pProp->Value; + return uno::Any(); +} + +bool setPropertyValue( uno::Sequence< beans::PropertyValue >& aProp, const OUString& aName, const uno::Any& aValue ) +{ + auto pProp = std::find_if(aProp.begin(), aProp.end(), + [&aName](const beans::PropertyValue& rProp) { return rProp.Name == aName; }); + if (pProp != aProp.end()) + { + pProp->Value = aValue; + return true; + } + return false; +} + +void setOrAppendPropertyValue( uno::Sequence< beans::PropertyValue >& aProp, const OUString& aName, const uno::Any& aValue ) +{ + if( setPropertyValue( aProp, aName, aValue ) ) + return; + + // append the property + sal_Int32 nLength = aProp.getLength(); + aProp.realloc( nLength + 1 ); + aProp[ nLength ].Name = aName; + aProp[ nLength ].Value = aValue; +} + +// ====UserFormGeomentryHelper==== + +UserFormGeometryHelper::UserFormGeometryHelper( + const uno::Reference< awt::XControl >& xControl, + double fOffsetX, double fOffsetY ) : + mfOffsetX( fOffsetX ), + mfOffsetY( fOffsetY ), + mbDialog( uno::Reference< awt::XDialog >( xControl, uno::UNO_QUERY ).is() ) +{ + if ( !xControl.is() ) + throw uno::RuntimeException( "No control is provided!" ); + + mxWindow.set( xControl->getPeer(), uno::UNO_QUERY_THROW ); + mxModelProps.set( xControl->getModel(), uno::UNO_QUERY_THROW ); + mxUnitConv.set( mxWindow, uno::UNO_QUERY_THROW ); +} + +double UserFormGeometryHelper::getLeft() const +{ + return implGetPos( false ); +} + +void UserFormGeometryHelper::setLeft( double fLeft ) +{ + implSetPos( fLeft, false ); +} + +double UserFormGeometryHelper::getTop() const +{ + return implGetPos( true ); +} + +void UserFormGeometryHelper::setTop( double fTop ) +{ + implSetPos( fTop, true ); +} + +double UserFormGeometryHelper::getWidth() const +{ + return implGetSize( false, true ); +} + +void UserFormGeometryHelper::setWidth( double fWidth ) +{ + implSetSize( fWidth, false, true ); +} + +double UserFormGeometryHelper::getHeight() const +{ + return implGetSize( true, true ); +} + +void UserFormGeometryHelper::setHeight( double fHeight ) +{ + implSetSize( fHeight, true, true ); +} + +double UserFormGeometryHelper::getInnerWidth() const +{ + return implGetSize( false, false ); +} + +void UserFormGeometryHelper::setInnerWidth( double fWidth ) +{ + implSetSize( fWidth, false, false ); +} + +double UserFormGeometryHelper::getInnerHeight() const +{ + return implGetSize( true, false ); +} + +void UserFormGeometryHelper::setInnerHeight( double fHeight ) +{ + implSetSize( fHeight, true, false ); +} + +double UserFormGeometryHelper::getOffsetX() const +{ + return mfOffsetX; +} + +double UserFormGeometryHelper::getOffsetY() const +{ + return mfOffsetY; +} + + +static const char saPosXName[] = "PositionX"; +static const char saPosYName[] = "PositionY"; +static const char saWidthName[] = "Width"; +static const char saHeightName[] = "Height"; + +double UserFormGeometryHelper::implGetPos( bool bPosY ) const +{ + sal_Int32 nPosAppFont = mxModelProps->getPropertyValue( bPosY ? OUString(saPosYName) : OUString(saPosXName) ).get< sal_Int32 >(); + // appfont to pixel + awt::Point aPosPixel = mxUnitConv->convertPointToPixel( awt::Point( nPosAppFont, nPosAppFont ), util::MeasureUnit::APPFONT ); + // pixel to VBA points + awt::Point aPosPoint = mxUnitConv->convertPointToLogic( aPosPixel, util::MeasureUnit::POINT ); + return bPosY ? (aPosPoint.Y - mfOffsetY) : (aPosPoint.X - mfOffsetX); +} + +void UserFormGeometryHelper::implSetPos( double fPos, bool bPosY ) +{ + // convert passed VBA points to pixels + sal_Int32 nPosPixel = static_cast< sal_Int32 >( fPos + (bPosY ? mfOffsetY : mfOffsetX) ); + awt::Point aPosPixel = mxUnitConv->convertPointToPixel( awt::Point( nPosPixel, nPosPixel ), util::MeasureUnit::POINT ); + // pixel to appfont + awt::Point aPosAppFont = mxUnitConv->convertPointToLogic( aPosPixel, util::MeasureUnit::APPFONT ); + mxModelProps->setPropertyValue( bPosY ? OUString(saPosYName) : OUString(saPosXName), uno::Any( bPosY ? aPosAppFont.Y : aPosAppFont.X ) ); +} + +double UserFormGeometryHelper::implGetSize( bool bHeight, bool bOuter ) const +{ + sal_Int32 nSizeAppFont = mxModelProps->getPropertyValue( bHeight ? OUString(saHeightName) : OUString(saWidthName) ).get< sal_Int32 >(); + // appfont to pixel + awt::Size aSizePixel = mxUnitConv->convertSizeToPixel( awt::Size( nSizeAppFont, nSizeAppFont ), util::MeasureUnit::APPFONT ); + + /* The VBA symbols 'Width' and 'Height' return the outer size including + window decoration (in difference to the symbols 'InnerWidth' and + 'InnerHeight'), but the window API returns the inner size. */ + if( mbDialog && bOuter ) + { + if( const vcl::Window* pWindow = VCLUnoHelper::GetWindow( mxWindow ) ) + { + tools::Rectangle aOuterRect = pWindow->GetWindowExtentsRelative( nullptr ); + aSizePixel = awt::Size( aOuterRect.getWidth(), aOuterRect.getHeight() ); + } + } + + // pixel to VBA points + awt::Size aSizePoint = mxUnitConv->convertSizeToLogic( aSizePixel, util::MeasureUnit::POINT ); + return bHeight ? aSizePoint.Height : aSizePoint.Width; +} + +void UserFormGeometryHelper::implSetSize( double fSize, bool bHeight, bool bOuter ) +{ + // convert passed VBA points to pixels + sal_Int32 nSize = static_cast< sal_Int32 >( fSize ); + awt::Size aSizePixel = mxUnitConv->convertSizeToPixel( awt::Size( nSize, nSize ), util::MeasureUnit::POINT ); + + /* The VBA symbols 'Width' and 'Height' set the outer size (in difference + to the symbols 'InnerWidth' and 'InnerHeight'), but the dialog model + expects the inner size. We have to remove the window extents from the + pixel height to get the same result. */ + if ( mbDialog && bOuter ) + { + if( const vcl::Window* pWindow = VCLUnoHelper::GetWindow( mxWindow ) ) + { + tools::Rectangle aOuterRect = pWindow->GetWindowExtentsRelative( nullptr ); + if( !aOuterRect.IsEmpty() ) + { + awt::Rectangle aInnerRect = mxWindow->getPosSize(); + sal_Int32 nDecorWidth = aOuterRect.getWidth() - aInnerRect.Width; + sal_Int32 nDecorHeight = aOuterRect.getHeight() - aInnerRect.Height; + aSizePixel.Width = ::std::max< sal_Int32 >( aSizePixel.Width - nDecorWidth, 1 ); + aSizePixel.Height = ::std::max< sal_Int32 >( aSizePixel.Height - nDecorHeight, 1 ); + } + } + } + + awt::Size aSizeAppFont = mxUnitConv->convertSizeToLogic( aSizePixel, util::MeasureUnit::APPFONT ); + mxModelProps->setPropertyValue( bHeight ? OUString(saHeightName) : OUString(saWidthName), uno::Any( bHeight ? aSizeAppFont.Height : aSizeAppFont.Width ) ); +} + + +double ConcreteXShapeGeometryAttributes::getLeft() const +{ + return m_pShapeHelper->getLeft(); +} +void ConcreteXShapeGeometryAttributes::setLeft( double nLeft ) +{ + m_pShapeHelper->setLeft( nLeft ); +} +double ConcreteXShapeGeometryAttributes::getTop() const +{ + return m_pShapeHelper->getTop(); +} +void ConcreteXShapeGeometryAttributes::setTop( double nTop ) +{ + m_pShapeHelper->setTop( nTop ); +} + +double ConcreteXShapeGeometryAttributes::getHeight() const +{ + return m_pShapeHelper->getHeight(); +} +void ConcreteXShapeGeometryAttributes::setHeight( double nHeight ) +{ + m_pShapeHelper->setHeight( nHeight ); +} +double ConcreteXShapeGeometryAttributes::getWidth() const +{ + return m_pShapeHelper->getWidth(); +} +void ConcreteXShapeGeometryAttributes::setWidth( double nWidth) +{ + m_pShapeHelper->setWidth( nWidth ); +} + + +ShapeHelper::ShapeHelper( const css::uno::Reference< css::drawing::XShape >& _xShape) + : xShape( _xShape ) +{ + if( !xShape.is() ) + throw css::uno::RuntimeException( "No valid shape for helper" ); +} + +double ShapeHelper::getHeight() const +{ + return Millimeter::getInPoints(xShape->getSize().Height); +} + +void ShapeHelper::setHeight(double _fheight) +{ + css::awt::Size aSize = xShape->getSize(); + aSize.Height = Millimeter::getInHundredthsOfOneMillimeter(_fheight); + xShape->setSize(aSize); +} + +double ShapeHelper::getWidth() const +{ + return Millimeter::getInPoints(xShape->getSize().Width); +} + +void ShapeHelper::setWidth(double _fWidth) +{ + css::awt::Size aSize = xShape->getSize(); + aSize.Width = Millimeter::getInHundredthsOfOneMillimeter(_fWidth); + xShape->setSize(aSize); +} + +double ShapeHelper::getLeft() const +{ + return Millimeter::getInPoints(xShape->getPosition().X); +} + +void ShapeHelper::setLeft(double _fLeft) +{ + css::awt::Point aPoint = xShape->getPosition(); + aPoint.X = Millimeter::getInHundredthsOfOneMillimeter(_fLeft); + xShape->setPosition(aPoint); +} + +double ShapeHelper::getTop() const +{ + return Millimeter::getInPoints(xShape->getPosition().Y); +} + +void ShapeHelper::setTop(double _fTop) +{ + css::awt::Point aPoint = xShape->getPosition(); + aPoint.Y = Millimeter::getInHundredthsOfOneMillimeter(_fTop); + xShape->setPosition(aPoint); +} + +void DebugHelper::basicexception( const css::uno::Exception& ex, ErrCode err, const OUString& /*additionalArgument*/ ) +{ + // #TODO #FIXME ( do we want to support additionalArg here ) + throw css::script::BasicErrorException( ex.Message, css::uno::Reference< css::uno::XInterface >(), sal_uInt32(err), OUString() ); +} + +void DebugHelper::basicexception( ErrCode err, const OUString& additionalArgument ) +{ + basicexception( css::uno::Exception(), err, additionalArgument ); +} + +void DebugHelper::basicexception( const css::uno::Exception& ex ) +{ + basicexception( ex, ERRCODE_BASIC_INTERNAL_ERROR, OUString() ); +} + +void DebugHelper::runtimeexception( ErrCode err ) +{ + // #TODO #FIXME ( do we want to support additionalArg here ) + throw css::uno::RuntimeException( css::uno::Exception().Message + " " + OUString::number(sal_uInt32(err)), + css::uno::Reference< css::uno::XInterface >() ); +} + +Millimeter::Millimeter():m_nMillimeter(0) {} + +Millimeter::Millimeter(double mm):m_nMillimeter(mm) {} + +void Millimeter::setInPoints(double points) +{ + m_nMillimeter = points * factor / 100.0; +} + +double Millimeter::getInHundredthsOfOneMillimeter() const +{ + return m_nMillimeter * 100; +} + +sal_Int32 Millimeter::getInHundredthsOfOneMillimeter(double points) +{ + sal_Int32 mm = static_cast<sal_Int32>(points * factor); + return mm; +} + +double Millimeter::getInPoints(int _hmm) +{ + double points = double( static_cast<double>(_hmm) / factor); + return points; +} + +uno::Reference< XHelperInterface > getVBADocument( const uno::Reference< frame::XModel >& xModel ) +{ + uno::Reference< XHelperInterface > xIf; + try + { + uno::Reference< beans::XPropertySet > xDocProps( xModel, uno::UNO_QUERY_THROW ); + OUString aCodeName; + xDocProps->getPropertyValue( "CodeName" ) >>= aCodeName; + xIf = getUnoDocModule( aCodeName, getSfxObjShell( xModel ) ); + } + catch (const uno::Exception&) + { + } + return xIf; +} + +uno::Reference< XHelperInterface > getUnoDocModule( const OUString& aModName, SfxObjectShell const * pShell ) +{ + uno::Reference< XHelperInterface > xIf; + if ( pShell ) + { + OUString sProj( "Standard" ); + // GetBasicManager() causes a SolarMutex assertion failure in some use cases from + // Automation, at least when opening a Calc Document through ooo::vba::excel:: + // XWorkbooks::Open(). Let's see if this check is a good way around that. It does seem that + // callers are prepared for this to return null? + if (comphelper::Automation::AutomationInvokedZone::isActive()) + return xIf; + BasicManager* pBasMgr = pShell->GetBasicManager(); + if ( pBasMgr && !pBasMgr->GetName().isEmpty() ) + sProj = pBasMgr->GetName(); + if( StarBASIC* pBasic = pShell->GetBasicManager()->GetLib( sProj ) ) + if( SbModule* pMod = pBasic->FindModule( aModName ) ) + xIf.set( pMod->GetUnoModule(), uno::UNO_QUERY ); + } + return xIf; +} + +SfxObjectShell* getSfxObjShell( const uno::Reference< frame::XModel >& xModel ) +{ + SfxObjectShell* pFoundShell = nullptr; + if ( xModel.is() ) + { + uno::Reference< lang::XUnoTunnel > xObjShellTunnel( xModel, uno::UNO_QUERY_THROW ); + pFoundShell = reinterpret_cast<SfxObjectShell*>( xObjShellTunnel->getSomething(SfxObjectShell::getUnoTunnelId())); + } + if ( !pFoundShell ) + throw uno::RuntimeException(); + return pFoundShell; +} + +} //org + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbalineformat.cxx b/vbahelper/source/vbahelper/vbalineformat.cxx new file mode 100644 index 000000000..6ae69fff2 --- /dev/null +++ b/vbahelper/source/vbahelper/vbalineformat.cxx @@ -0,0 +1,442 @@ +/* -*- 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/office/MsoArrowheadStyle.hpp> +#include <ooo/vba/office/MsoLineDashStyle.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/drawing/LineDash.hpp> +#include "vbalineformat.hxx" +#include "vbacolorformat.hxx" + +using namespace ooo::vba; +using namespace com::sun::star; + +ScVbaLineFormat::ScVbaLineFormat( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< drawing::XShape >& xShape ) : ScVbaLineFormat_BASE( xParent, xContext ), m_xShape( xShape ) +{ + m_xPropertySet.set( xShape, uno::UNO_QUERY_THROW ); + m_nLineDashStyle = office::MsoLineDashStyle::msoLineSolid; + m_nLineWeight = 1; +} + +sal_Int32 +ScVbaLineFormat::convertLineStartEndNameToArrowheadStyle( const OUString& sLineName ) +{ + sal_Int32 nLineType = office::MsoArrowheadStyle::msoArrowheadNone; + if ( sLineName == "Small Arrow" || sLineName == "Arrow" || sLineName == "msArrowEnd" || sLineName == "Double Arrow") + { + // msoArrowheadTriangle + nLineType = office::MsoArrowheadStyle::msoArrowheadTriangle; + } + else if ( sLineName == "Square 45" || sLineName == "Square" || sLineName == "msArrowDiamondEnd") + { + // msoArrowheadDiamond + nLineType = office::MsoArrowheadStyle::msoArrowheadDiamond; + } + else if (sLineName == "Circle" || sLineName == "msArrowOvalEnd" || sLineName == "Dimension Lines" ) + { + // msoArrowheadOval + nLineType = office::MsoArrowheadStyle::msoArrowheadOval; + } + else if ( sLineName == "Arrow concave" || sLineName == "msArrowStealthEnd" ) + { + // msoArrowheadStealth + nLineType = office::MsoArrowheadStyle::msoArrowheadStealth; + } + else if ( sLineName == "Rounded short Arrow" || sLineName == "Rounded large Arrow" || sLineName == "Symmetric Arrow" + || sLineName == "msArrowOpenEnd" || sLineName == "Line Arrow" ) + { + // msoArrowheadOpen + nLineType = office::MsoArrowheadStyle::msoArrowheadOpen; + } + else + { + // msoArrowheadNone + nLineType = office::MsoArrowheadStyle::msoArrowheadNone; + } + return nLineType; +} + +OUString +ScVbaLineFormat::convertArrowheadStyleToLineStartEndName( sal_Int32 nArrowheadStyle ) +{ + switch( nArrowheadStyle ) + { + case office::MsoArrowheadStyle::msoArrowheadNone: + return OUString(); + case office::MsoArrowheadStyle::msoArrowheadStealth: + return "Arrow concave"; + case office::MsoArrowheadStyle::msoArrowheadOpen: + return "Line Arrow"; + case office::MsoArrowheadStyle::msoArrowheadOval: + return "Circle"; + case office::MsoArrowheadStyle::msoArrowheadDiamond: + return "Square 45"; + case office::MsoArrowheadStyle::msoArrowheadTriangle: + return "Arrow"; + default: + throw uno::RuntimeException( "Invalid Arrow Style!" ); + } +} + +// Attributes +sal_Int32 SAL_CALL +ScVbaLineFormat::getBeginArrowheadStyle() +{ + sal_Int32 nLineType = office::MsoArrowheadStyle::msoArrowheadNone; + OUString sLineName; + m_xPropertySet->getPropertyValue( "LineStartName" ) >>= sLineName; + if( ( sLineName.getLength() > 7 ) && ( sLineName.indexOf( "msArray" ) ) != -1 ) + { + sal_Int32 nIndex = sLineName.indexOf( ' ' ); + OUString sName = sLineName.copy( 0, nIndex ); + //sal_Int32 nSize = sLineName.copy( nIndex + 1 ).toInt32(); + nLineType = convertLineStartEndNameToArrowheadStyle( sName ); + } + else + { + nLineType = convertLineStartEndNameToArrowheadStyle( sLineName ); + } + return nLineType; +} + +void SAL_CALL +ScVbaLineFormat::setBeginArrowheadStyle( sal_Int32 _beginarrowheadstyle ) +{ + OUString sArrayName = convertArrowheadStyleToLineStartEndName( _beginarrowheadstyle ); + m_xPropertySet->setPropertyValue( "LineStartName" , uno::makeAny( sArrayName ) ); +} + +sal_Int32 SAL_CALL +ScVbaLineFormat::getBeginArrowheadLength() +{ + // #STUB + // force error + throw uno::RuntimeException( "Property 'EndArrowheadWidth' is not supported." ); +} + +void SAL_CALL +ScVbaLineFormat::setBeginArrowheadLength( sal_Int32 /*_beginarrowheadlength*/ ) +{ + // #STUB + // force error + throw uno::RuntimeException( "Property 'EndArrowheadWidth' is not supported." ); +} + +sal_Int32 SAL_CALL +ScVbaLineFormat::getBeginArrowheadWidth() +{ + // #STUB + // force error + throw uno::RuntimeException( "Property 'EndArrowheadWidth' is not supported." ); +} + +void SAL_CALL +ScVbaLineFormat::setBeginArrowheadWidth( sal_Int32 /*_beginarrowheadwidth*/ ) +{ + // #STUB + // force error + throw uno::RuntimeException( "Property 'EndArrowheadWidth' is not supported." ); +} + +sal_Int32 SAL_CALL +ScVbaLineFormat::getEndArrowheadStylel() +{ + // #STUB + return 0; +} + +void SAL_CALL +ScVbaLineFormat::setEndArrowheadStylel( sal_Int32 /*_endarrowheadstylel*/ ) +{ + // #STUB +} + +sal_Int32 SAL_CALL +ScVbaLineFormat::getEndArrowheadLength() +{ + // #STUB + // force error + throw uno::RuntimeException( "Property 'EndArrowheadWidth' is not supported." ); +} + +void SAL_CALL +ScVbaLineFormat::setEndArrowheadLength( sal_Int32 /*_endarrowheadlength*/ ) +{ + // #STUB + throw uno::RuntimeException( "Property 'EndArrowheadWidth' is not supported." ); +} + +sal_Int32 SAL_CALL +ScVbaLineFormat::getEndArrowheadWidth() +{ + // #STUB + throw uno::RuntimeException( "Property 'EndArrowheadWidth' is not supported." ); +} + +void SAL_CALL +ScVbaLineFormat::setEndArrowheadWidth( sal_Int32 /*_endarrowheadwidth*/ ) +{ + // #STUB + throw uno::RuntimeException( "Property 'EndArrowheadWidth' is not supported." ); +} + +double SAL_CALL +ScVbaLineFormat::getWeight() +{ + sal_Int32 nLineWidth=0; + m_xPropertySet->getPropertyValue( "LineWidth" ) >>= nLineWidth; + double dLineWidth = Millimeter::getInPoints( nLineWidth ); + return dLineWidth; +} + +void SAL_CALL +ScVbaLineFormat::setWeight( double _weight ) +{ + if( _weight < 0 ) + throw uno::RuntimeException( "Parameter: Must be positive." ); + if( _weight == 0 ) + _weight = 0.5; + m_nLineWeight = _weight; + Millimeter aMillimeter; + aMillimeter.setInPoints( _weight ); + + sal_Int32 nLineWidth = static_cast<sal_Int32>( aMillimeter.getInHundredthsOfOneMillimeter() ); + m_xPropertySet->setPropertyValue( "LineWidth" , uno::makeAny( nLineWidth ) ); + setDashStyle( m_nLineDashStyle ); +} + +sal_Bool SAL_CALL +ScVbaLineFormat::getVisible() +{ + drawing::LineStyle aLineStyle; + m_xPropertySet->getPropertyValue( "LineStyle" ) >>= aLineStyle; + if( aLineStyle == drawing::LineStyle_NONE ) + { + return false; + } + return true; +} + +void SAL_CALL +ScVbaLineFormat::setVisible( sal_Bool _visible ) +{ + drawing::LineStyle aLineStyle; + m_xPropertySet->getPropertyValue( "LineStyle" ) >>= aLineStyle; + if( !_visible ) + { + aLineStyle = drawing::LineStyle_NONE; + m_xPropertySet->setPropertyValue( "LineStyle" , uno::makeAny( aLineStyle ) ); + } + else + { + if( aLineStyle == drawing::LineStyle_NONE ) + { + setDashStyle( m_nLineDashStyle ); + } + } +} + +double SAL_CALL +ScVbaLineFormat::getTransparency() +{ + sal_Int16 nTransparency = 0; + m_xPropertySet->getPropertyValue( "LineTransparence" ) >>= nTransparency; + double fTransparency = static_cast<double>( nTransparency ); + return fTransparency / 100; +} + +void SAL_CALL +ScVbaLineFormat::setTransparency( double _transparency ) +{ + sal_Int16 nTransparency = static_cast<sal_Int16>( _transparency * 100 ); + m_xPropertySet->setPropertyValue( "LineTransparence" , uno::makeAny( nTransparency ) ); +} + +sal_Int16 SAL_CALL +ScVbaLineFormat::getStyle() +{ + //OpenOffice.org only supports one LineStyle (other than the DashStyles) + //Therefore we can only return the SingleLine + return 1; +} + +void SAL_CALL +ScVbaLineFormat::setStyle( sal_Int16 /*_style */) +{ + //OpenOffice.org only supports one LineStyle (other than the DashStyles) + //Therefore we do not set the LineStyle, because it maybe is already set + //to Dashed or Single Line. Setting the 'Visible' or 'DashStyle' properties + //will be done with the according methods. + + // #STUB +} + +sal_Int32 SAL_CALL +ScVbaLineFormat::getDashStyle() +{ + drawing::LineStyle eLineStyle; + //LineStyle integer in Xray + m_xPropertySet->getPropertyValue( "LineStyle" ) >>= eLineStyle; + if( eLineStyle == drawing::LineStyle_SOLID ) + m_nLineDashStyle = office::MsoLineDashStyle::msoLineSolid; + else + { + drawing::LineDash aLineDash; + m_xPropertySet->getPropertyValue( "LineDash" ) >>= aLineDash; + if( aLineDash.Dots == 0 ) + { + //LineDash + //LineLongDash + m_nLineDashStyle = office::MsoLineDashStyle::msoLineDash; + if( aLineDash.Distance > 0 && ( aLineDash.DashLen / aLineDash.Distance > 1 ) ) + { + m_nLineDashStyle = office::MsoLineDashStyle::msoLineLongDash; + } + } + else if( aLineDash.Dots == 1 ) + { + // LineDashDot + // LineLongDashDot + // LineSquareDot + // LineRoundDot ! not supported + m_nLineDashStyle = office::MsoLineDashStyle::msoLineDashDot; + if( aLineDash.Dashes == 0 ) + { + m_nLineDashStyle = office::MsoLineDashStyle::msoLineSquareDot; + } + else + { + if( aLineDash.Distance > 0 && ( aLineDash.DashLen / aLineDash.Distance > 1 ) ) + { + m_nLineDashStyle = office::MsoLineDashStyle::msoLineLongDashDot; + } + } + } + else if( aLineDash.Dots == 2 ) + { + // LineDashDotDot + m_nLineDashStyle = office::MsoLineDashStyle::msoLineDashDotDot; + } + } + + return m_nLineDashStyle; +} + +void SAL_CALL +ScVbaLineFormat::setDashStyle( sal_Int32 _dashstyle ) +{ + m_nLineDashStyle = _dashstyle; + if( _dashstyle == office::MsoLineDashStyle::msoLineSolid ) + { + m_xPropertySet->setPropertyValue( "LineStyle" , uno::makeAny( drawing::LineStyle_SOLID )); + } + else + { + m_xPropertySet->setPropertyValue( "LineStyle" , uno::makeAny( drawing::LineStyle_DASH ) ); + drawing::LineDash aLineDash; + Millimeter aMillimeter( m_nLineWeight ); + sal_Int32 nPixel = static_cast< sal_Int32 >( aMillimeter.getInHundredthsOfOneMillimeter() ); + switch( _dashstyle ) + { + case office::MsoLineDashStyle::msoLineDashDot: + aLineDash.Dots = 1; + aLineDash.DotLen = nPixel; + aLineDash.Dashes = 1; + aLineDash.DashLen = 5 * nPixel; + aLineDash.Distance = 4 * nPixel; + break; + case office::MsoLineDashStyle::msoLineLongDashDot: + aLineDash.Dots = 1; + aLineDash.DotLen = nPixel; + aLineDash.Dashes = 1; + aLineDash.DashLen = 10 * nPixel; + aLineDash.Distance = 4 * nPixel; + break; + case office::MsoLineDashStyle::msoLineDash: + aLineDash.Dots = 0; + aLineDash.DotLen = 0; + aLineDash.Dashes = 1; + aLineDash.DashLen = 6 * nPixel; + aLineDash.Distance = 4 * nPixel; + break; + case office::MsoLineDashStyle::msoLineDashDotDot: + aLineDash.Dots = 2; + aLineDash.DotLen = nPixel; + aLineDash.Dashes = 1; + aLineDash.DashLen = 10 * nPixel; + aLineDash.Distance = 3 * nPixel; + break; + case office::MsoLineDashStyle::msoLineLongDash: + aLineDash.Dots = 0; + aLineDash.DotLen = 0; + aLineDash.Dashes = 1; + aLineDash.DashLen = 10 * nPixel; + aLineDash.Distance = 4 * nPixel; + break; + case office::MsoLineDashStyle::msoLineSquareDot: + aLineDash.Dots = 1; + aLineDash.DotLen = nPixel; + aLineDash.Dashes = 0; + aLineDash.DashLen = 0; + aLineDash.Distance = nPixel; + break; + case office::MsoLineDashStyle::msoLineRoundDot: + aLineDash.Dots = 1; + aLineDash.DotLen = nPixel; + aLineDash.Dashes = 0; + aLineDash.DashLen = 0; + aLineDash.Distance = nPixel; + break; + default: + throw uno::RuntimeException( "this MsoLineDashStyle is not supported." ); + } + m_xPropertySet->setPropertyValue( "LineDash" , uno::makeAny( aLineDash ) ); + } +} + +// Methods +uno::Reference< msforms::XColorFormat > SAL_CALL +ScVbaLineFormat::BackColor() +{ + return uno::Reference< msforms::XColorFormat >( new ScVbaColorFormat( getParent(), mxContext, this, m_xShape, ::ColorFormatType::LINEFORMAT_BACKCOLOR ) ); +} + +uno::Reference< msforms::XColorFormat > SAL_CALL +ScVbaLineFormat::ForeColor() +{ + return uno::Reference< msforms::XColorFormat >( new ScVbaColorFormat( getParent(), mxContext, this, m_xShape, ::ColorFormatType::LINEFORMAT_FORECOLOR ) ); +} + +OUString +ScVbaLineFormat::getServiceImplName() +{ + return "ScVbaLineFormat"; +} + +uno::Sequence< OUString > +ScVbaLineFormat::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msform.LineFormat" + }; + return aServiceNames; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbalineformat.hxx b/vbahelper/source/vbahelper/vbalineformat.hxx new file mode 100644 index 000000000..858fb3e1e --- /dev/null +++ b/vbahelper/source/vbahelper/vbalineformat.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_VBAHELPER_SOURCE_VBAHELPER_VBALINEFORMAT_HXX +#define INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBALINEFORMAT_HXX + +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <ooo/vba/msforms/XLineFormat.hpp> +#include <vbahelper/vbahelperinterface.hxx> + +typedef InheritedHelperInterfaceWeakImpl< ov::msforms::XLineFormat > ScVbaLineFormat_BASE; + +class ScVbaLineFormat : public ScVbaLineFormat_BASE +{ +private: + css::uno::Reference< css::drawing::XShape > m_xShape; + css::uno::Reference< css::beans::XPropertySet > m_xPropertySet; + sal_Int32 m_nLineDashStyle; + double m_nLineWeight; + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; + static sal_Int32 convertLineStartEndNameToArrowheadStyle( const OUString& sLineName ); + /// @throws css::uno::RuntimeException + static OUString convertArrowheadStyleToLineStartEndName( sal_Int32 nArrowheadStyle ); +public: + ScVbaLineFormat( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::drawing::XShape >& xShape ); + + // Attributes + virtual sal_Int32 SAL_CALL getBeginArrowheadStyle() override; + virtual void SAL_CALL setBeginArrowheadStyle( sal_Int32 _beginarrowheadstyle ) override; + virtual sal_Int32 SAL_CALL getBeginArrowheadLength() override; + virtual void SAL_CALL setBeginArrowheadLength( sal_Int32 _beginarrowheadlength ) override; + virtual sal_Int32 SAL_CALL getBeginArrowheadWidth() override; + virtual void SAL_CALL setBeginArrowheadWidth( sal_Int32 _beginarrowheadwidth ) override; + virtual sal_Int32 SAL_CALL getEndArrowheadStylel() override; + virtual void SAL_CALL setEndArrowheadStylel( sal_Int32 _endarrowheadstylel ) override; + virtual sal_Int32 SAL_CALL getEndArrowheadLength() override; + virtual void SAL_CALL setEndArrowheadLength( sal_Int32 _endarrowheadlength ) override; + virtual sal_Int32 SAL_CALL getEndArrowheadWidth() override; + virtual void SAL_CALL setEndArrowheadWidth( sal_Int32 _endarrowheadwidth ) override; + virtual double SAL_CALL getWeight() override; + virtual void SAL_CALL setWeight( double _weight ) override; + virtual sal_Bool SAL_CALL getVisible() override; + virtual void SAL_CALL setVisible( sal_Bool _visible ) override; + virtual double SAL_CALL getTransparency() override; + virtual void SAL_CALL setTransparency( double _transparency ) override; + virtual sal_Int16 SAL_CALL getStyle() override; + virtual void SAL_CALL setStyle( sal_Int16 _style ) override; + virtual sal_Int32 SAL_CALL getDashStyle() override; + virtual void SAL_CALL setDashStyle( sal_Int32 _dashstyle ) override; + + // Methods + virtual css::uno::Reference< ov::msforms::XColorFormat > SAL_CALL BackColor() override; + virtual css::uno::Reference< ov::msforms::XColorFormat > SAL_CALL ForeColor() override; +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBALINEFORMAT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbapagesetupbase.cxx b/vbahelper/source/vbahelper/vbapagesetupbase.cxx new file mode 100644 index 000000000..c29b166c6 --- /dev/null +++ b/vbahelper/source/vbahelper/vbapagesetupbase.cxx @@ -0,0 +1,308 @@ +/* -*- 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 <vbahelper/vbapagesetupbase.hxx> +#include <basic/sberrors.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +VbaPageSetupBase::VbaPageSetupBase(const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext ) + : VbaPageSetupBase_BASE( xParent, xContext ) + , mnOrientLandscape(0) + , mnOrientPortrait(0) +{ +} + +double SAL_CALL VbaPageSetupBase::getTopMargin() +{ + sal_Int32 topMargin = 0; + + try + { + bool headerOn = false; + sal_Int32 headerHeight = 0; + + uno::Any aValue = mxPageProps->getPropertyValue( "HeaderIsOn" ); + aValue >>= headerOn; + + aValue = mxPageProps->getPropertyValue( "TopMargin" ); + aValue >>= topMargin; + + if( headerOn ) + { + aValue = mxPageProps->getPropertyValue( "HeaderHeight" ); + aValue >>= headerHeight; + topMargin = topMargin + headerHeight; + } + } + catch( uno::Exception& ) + { + } + + return Millimeter::getInPoints( topMargin ); +} + +void SAL_CALL VbaPageSetupBase::setTopMargin( double margin ) +{ + sal_Int32 topMargin = Millimeter::getInHundredthsOfOneMillimeter( margin ); + + try + { + bool headerOn = false; + sal_Int32 headerHeight = 0; + + uno::Any aValue = mxPageProps->getPropertyValue( "HeaderIsOn" ); + aValue >>= headerOn; + + if( headerOn ) + { + aValue = mxPageProps->getPropertyValue( "HeaderHeight" ); + aValue >>= headerHeight; + topMargin -= headerHeight; + } + + mxPageProps->setPropertyValue( "TopMargin" , uno::Any(topMargin) ); + } + catch( uno::Exception& ) + { + } +} + +double SAL_CALL VbaPageSetupBase::getBottomMargin() +{ + sal_Int32 bottomMargin = 0; + + try + { + bool footerOn = false; + sal_Int32 footerHeight = 0; + + uno::Any aValue = mxPageProps->getPropertyValue( "FooterIsOn" ); + aValue >>= footerOn; + + aValue = mxPageProps->getPropertyValue( "BottomMargin" ); + aValue >>= bottomMargin; + + if( footerOn ) + { + aValue = mxPageProps->getPropertyValue( "FooterHeight" ); + aValue >>= footerHeight; + bottomMargin += footerHeight; + } + } + catch( uno::Exception& ) + { + } + + return Millimeter::getInPoints( bottomMargin ); +} + +void SAL_CALL VbaPageSetupBase::setBottomMargin( double margin ) +{ + sal_Int32 bottomMargin = Millimeter::getInHundredthsOfOneMillimeter( margin ); + + try + { + bool footerOn = false; + sal_Int32 footerHeight = 0; + + uno::Any aValue = mxPageProps->getPropertyValue( "FooterIsOn" ); + aValue >>= footerOn; + + if( footerOn ) + { + aValue = mxPageProps->getPropertyValue( "FooterHeight" ); + aValue >>= footerHeight; + bottomMargin -= footerHeight; + } + + mxPageProps->setPropertyValue( "BottomMargin", uno::Any(bottomMargin) ); + } + catch( uno::Exception& ) + { + } +} + +double SAL_CALL VbaPageSetupBase::getRightMargin() +{ + sal_Int32 rightMargin = 0; + try + { + uno::Any aValue = mxPageProps->getPropertyValue( "RightMargin" ); + aValue >>= rightMargin; + } + catch( uno::Exception& ) + { + } + + return Millimeter::getInPoints( rightMargin ); +} + +void SAL_CALL VbaPageSetupBase::setRightMargin( double margin ) +{ + sal_Int32 rightMargin = Millimeter::getInHundredthsOfOneMillimeter( margin ); + try + { + mxPageProps->setPropertyValue( "RightMargin", uno::Any(rightMargin) ); + } + catch( uno::Exception& ) + { + } + +} + +double SAL_CALL VbaPageSetupBase::getLeftMargin() +{ + sal_Int32 leftMargin = 0; + try + { + uno::Any aValue = mxPageProps->getPropertyValue( "LeftMargin" ); + aValue >>= leftMargin; + } + catch( uno::Exception& ) + { + } + + return Millimeter::getInPoints( leftMargin ); +} + +void SAL_CALL VbaPageSetupBase::setLeftMargin( double margin ) +{ + sal_Int32 leftMargin = Millimeter::getInHundredthsOfOneMillimeter( margin ); + try + { + mxPageProps->setPropertyValue( "LeftMargin", uno::Any(leftMargin) ); + } + catch( uno::Exception& ) + { + } +} + +double VbaPageSetupBase::getHeaderMargin() +{ + sal_Int32 headerMargin = 0; + try + { + uno::Any aValue = mxPageProps->getPropertyValue( "TopMargin" ); + aValue >>= headerMargin; + } + catch( uno::Exception& ) + { + } + + return Millimeter::getInPoints( headerMargin ); +} + +void VbaPageSetupBase::setHeaderMargin( double margin ) +{ + sal_Int32 headerMargin = Millimeter::getInHundredthsOfOneMillimeter( margin ); + try + { + mxPageProps->setPropertyValue( "TopMargin", uno::Any(headerMargin) ); + } + catch( uno::Exception& ) + { + } +} + +double VbaPageSetupBase::getFooterMargin() +{ + sal_Int32 footerMargin = 0; + try + { + uno::Any aValue = mxPageProps->getPropertyValue( "BottomMargin" ); + aValue >>= footerMargin; + } + catch( uno::Exception& ) + { + } + + return Millimeter::getInPoints( footerMargin ); +} + +void VbaPageSetupBase::setFooterMargin( double margin ) +{ + sal_Int32 footerMargin = Millimeter::getInHundredthsOfOneMillimeter( margin ); + try + { + mxPageProps->setPropertyValue( "BottomMargin", uno::Any(footerMargin) ); + } + catch( uno::Exception& ) + { + } +} + +sal_Int32 SAL_CALL VbaPageSetupBase::getOrientation() +{ + sal_Int32 orientation = mnOrientPortrait; + try + { + bool isLandscape = false; + uno::Any aValue = mxPageProps->getPropertyValue( "IsLandscape" ); + aValue >>= isLandscape; + + if( isLandscape ) + { + orientation = mnOrientLandscape; + } + } + catch( uno::Exception& ) + { + } + return orientation; +} + +void SAL_CALL VbaPageSetupBase::setOrientation( sal_Int32 orientation ) +{ + if( ( orientation != mnOrientPortrait ) && + ( orientation != mnOrientLandscape ) ) + { + DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_PARAMETER ); + } + + try + { + bool isLandscape = false; + uno::Any aValue = mxPageProps->getPropertyValue( "IsLandscape" ); + aValue >>= isLandscape; + + bool switchOrientation = false; + if(( isLandscape && orientation != mnOrientLandscape ) || + ( !isLandscape && orientation != mnOrientPortrait )) + { + switchOrientation = true; + } + + if( switchOrientation ) + { + uno::Any aHeight = mxPageProps->getPropertyValue( "Height" ); + uno::Any aWidth = mxPageProps->getPropertyValue( "Width" ); + mxPageProps->setPropertyValue( "IsLandscape", uno::Any(!isLandscape) ); + mxPageProps->setPropertyValue( "Width" , aHeight ); + mxPageProps->setPropertyValue( "Height" , aWidth ); + } + } + catch( uno::Exception& ) + { + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbapictureformat.cxx b/vbahelper/source/vbahelper/vbapictureformat.cxx new file mode 100644 index 000000000..8e3578f1d --- /dev/null +++ b/vbahelper/source/vbahelper/vbapictureformat.cxx @@ -0,0 +1,134 @@ +/* -*- 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 "vbapictureformat.hxx" + +using namespace ooo::vba; +using namespace com::sun::star; + +ScVbaPictureFormat::ScVbaPictureFormat( const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + uno::Reference< drawing::XShape > const & xShape ) + : ScVbaPictureFormat_BASE( xParent, xContext ), m_xShape( xShape ) +{ + m_xPropertySet.set( m_xShape, uno::UNO_QUERY_THROW ); +} + +void +ScVbaPictureFormat::checkParameterRangeInDouble( double nRange, double nMin, double nMax ) +{ + if( nRange < nMin ) + { + throw uno::RuntimeException( "Parameter out of range, value is too small." ); + } + if( nRange > nMax ) + { + throw uno::RuntimeException( "Parameter out of range, value is too high." ); + } +} + +// Attributes +double SAL_CALL +ScVbaPictureFormat::getBrightness() +{ + sal_Int16 nLuminance = 0; + m_xPropertySet->getPropertyValue( "AdjustLuminance" ) >>= nLuminance; + double fBrightness = static_cast< double >( nLuminance ); + fBrightness = ( fBrightness +100 ) / 200; + return fBrightness; +} + +void SAL_CALL +ScVbaPictureFormat::setBrightness( double _brightness ) +{ + checkParameterRangeInDouble( _brightness, 0.0, 1.0 ); + double fLuminance = _brightness * 200 - 100; + sal_Int16 nLuminance = static_cast< sal_Int16 >( fLuminance ); + m_xPropertySet->setPropertyValue( "AdjustLuminance" , uno::makeAny( nLuminance ) ); +} + +double SAL_CALL +ScVbaPictureFormat::getContrast() +{ + sal_Int16 nContrast = 0; + m_xPropertySet->getPropertyValue( "AdjustContrast" ) >>= nContrast; + double fContrast = static_cast< double >( nContrast ); + fContrast = ( fContrast + 100 ) / 200; + return fContrast; +} + +void SAL_CALL +ScVbaPictureFormat::setContrast( double _contrast ) +{ + checkParameterRangeInDouble( _contrast, 0.0, 1.0 ); + double fContrast = _contrast * 200 - 100; + sal_Int16 nContrast = static_cast< sal_Int16 >( fContrast ); + m_xPropertySet->setPropertyValue( "AdjustContrast" , uno::makeAny( nContrast ) ); +} + + +// Methods +void SAL_CALL +ScVbaPictureFormat::IncrementBrightness( double increment ) +{ + double fBrightness = getBrightness(); + fBrightness += increment; + if( fBrightness < 0 ) + { + fBrightness = 0.0; + } + if( fBrightness > 1 ) + { + fBrightness = 1; + } + setBrightness( fBrightness ); +} + +void SAL_CALL +ScVbaPictureFormat::IncrementContrast( double increment ) +{ + double nContrast = getContrast(); + nContrast += increment; + if( nContrast < 0 ) + { + nContrast = 0.0; + } + if( nContrast > 1 ) + { + nContrast = 1.0; + } + setContrast( nContrast ); +} + +OUString +ScVbaPictureFormat::getServiceImplName() +{ + return "ScVbaPictureFormat"; +} + +uno::Sequence< OUString > +ScVbaPictureFormat::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msform.PictureFormat" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbapictureformat.hxx b/vbahelper/source/vbahelper/vbapictureformat.hxx new file mode 100644 index 000000000..8ee2dba53 --- /dev/null +++ b/vbahelper/source/vbahelper/vbapictureformat.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_VBAHELPER_SOURCE_VBAHELPER_VBAPICTUREFORMAT_HXX +#define INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBAPICTUREFORMAT_HXX + +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <ooo/vba/msforms/XPictureFormat.hpp> +#include <vbahelper/vbahelperinterface.hxx> + +typedef InheritedHelperInterfaceWeakImpl< ov::msforms::XPictureFormat > ScVbaPictureFormat_BASE; + +class ScVbaPictureFormat : public ScVbaPictureFormat_BASE +{ +private: + css::uno::Reference< css::drawing::XShape > m_xShape; + css::uno::Reference< css::beans::XPropertySet > m_xPropertySet; +protected: + virtual OUString getServiceImplName() override; + virtual css::uno::Sequence<OUString> getServiceNames() override; +private: + /// @throws css::uno::RuntimeException + static void checkParameterRangeInDouble( double nRange, double nMin, double nMax ); +public: + /// @throws css::lang::IllegalArgumentException + /// @throws css::uno::RuntimeException + ScVbaPictureFormat( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, css::uno::Reference< css::drawing::XShape > const & xShape ); + + // Attributes + virtual double SAL_CALL getBrightness() override; + virtual void SAL_CALL setBrightness( double _brightness ) override; + virtual double SAL_CALL getContrast() override; + virtual void SAL_CALL setContrast( double _contrast ) override; + + // Methods + virtual void SAL_CALL IncrementBrightness( double increment ) override; + virtual void SAL_CALL IncrementContrast( double increment ) override; +}; + +#endif // INCLUDED_VBAHELPER_SOURCE_VBAHELPER_VBAPICTUREFORMAT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbapropvalue.cxx b/vbahelper/source/vbahelper/vbapropvalue.cxx new file mode 100644 index 000000000..f5249ec6d --- /dev/null +++ b/vbahelper/source/vbahelper/vbapropvalue.cxx @@ -0,0 +1,39 @@ +/* -*- 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 <vbahelper/vbapropvalue.hxx> + +using namespace com::sun::star; + +ScVbaPropValue::ScVbaPropValue( PropListener* pListener ) : m_pListener( pListener ) +{ +} + +css::uno::Any SAL_CALL +ScVbaPropValue::getValue() +{ + return m_pListener->getValueEvent(); +} + +void SAL_CALL +ScVbaPropValue::setValue( const css::uno::Any& _value ) +{ + m_pListener->setValueEvent( _value ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbashape.cxx b/vbahelper/source/vbahelper/vbashape.cxx new file mode 100644 index 000000000..8f16865ef --- /dev/null +++ b/vbahelper/source/vbahelper/vbashape.cxx @@ -0,0 +1,754 @@ +/* -*- 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/office/MsoZOrderCmd.hpp> +#include <ooo/vba/office/MsoScaleFrom.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/drawing/ConnectorType.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/text/RelOrientation.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <ooo/vba/office/MsoShapeType.hpp> +#include <ooo/vba/office/MsoAutoShapeType.hpp> +#include <ooo/vba/word/WdRelativeHorizontalPosition.hpp> +#include <ooo/vba/word/WdRelativeVerticalPosition.hpp> + +#include <basic/sberrors.hxx> +#include <comphelper/processfactory.hxx> +#include <vcl/svapp.hxx> +#include <sal/log.hxx> + +#include <vbahelper/vbashape.hxx> +#include <vbahelper/vbatextframe.hxx> +#include "vbalineformat.hxx" +#include "vbafillformat.hxx" +#include "vbapictureformat.hxx" +#include <vbahelper/vbashaperange.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +ScVbaShape::ScVbaShape( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< drawing::XShape >& xShape, const uno::Reference< drawing::XShapes >& xShapes, const uno::Reference< frame::XModel >& xModel, sal_Int32 nType ) + : ScVbaShape_BASE( xParent, xContext ), m_xShape( xShape ), m_xShapes( xShapes ), m_nType( nType ), m_xModel( xModel ) +{ + m_xPropertySet.set( m_xShape, uno::UNO_QUERY_THROW ); + m_pShapeHelper.reset( new ShapeHelper( m_xShape ) ); + addListeners(); +} + +ScVbaShape::~ScVbaShape() +{ +} + +void SAL_CALL +ScVbaShape::disposing( const lang::EventObject& rEventObject ) +{ + try + { + uno::Reference< drawing::XShapes > xShapes( rEventObject.Source, uno::UNO_QUERY ); + uno::Reference< drawing::XShape > xShape( rEventObject.Source, uno::UNO_QUERY ); + if ( xShapes.is() ) + removeShapesListener(); + if ( xShape.is() ) + removeShapeListener(); + } + catch( uno::Exception& ) + { + } +} + + +void ScVbaShape::addListeners() +{ + uno::Reference< lang::XComponent > xComponent( m_xShape, uno::UNO_QUERY ); + if ( xComponent.is() ) + xComponent->addEventListener( this ); + + xComponent.set( m_xShapes, uno::UNO_QUERY ); + if ( xComponent.is() ) + xComponent->addEventListener( this ); +} + +void +ScVbaShape::removeShapeListener() +{ + if( m_xShape.is() ) + { + uno::Reference< lang::XComponent > xComponent( m_xShape, uno::UNO_QUERY_THROW ); + xComponent->removeEventListener( this ); + } + m_xShape = nullptr; + m_xPropertySet = nullptr; +} + +void +ScVbaShape::removeShapesListener() +{ + if( m_xShapes.is() ) + { + uno::Reference< lang::XComponent > xComponent( m_xShapes, uno::UNO_QUERY_THROW ); + xComponent->removeEventListener( this ); + } + m_xShapes = nullptr; +} + +sal_Int32 +ScVbaShape::getType( const css::uno::Reference< drawing::XShape >& xShape ) +{ + OUString sShapeType; + uno::Reference< drawing::XShapeDescriptor > xShapeDescriptor( xShape, uno::UNO_QUERY_THROW ); + sShapeType = xShapeDescriptor->getShapeType(); + SAL_INFO("vbahelper", "ScVbaShape::getType: " << sShapeType); + // office::MsoShapeType::msoDiagram to "com.sun.star.drawing.GroupShape" + if( sShapeType == "com.sun.star.drawing.GroupShape" ) + return office::MsoShapeType::msoGroup; + else if( sShapeType == "com.sun.star.drawing.GraphicObjectShape" ) + return office::MsoShapeType::msoPicture; + else if( sShapeType == "com.sun.star.drawing.ControlShape" || sShapeType == "FrameShape" ) + return office::MsoShapeType::msoOLEControlObject; + // OOo don't support office::MsoShapeType::msoComment as a Shape. + else if( sShapeType == "com.sun.star.drawing.OLE2Shape" ) + return office::MsoShapeType::msoChart; + // Art characters office::MsoShapeType::msoTextEffect, in OOo corresponding to "com.sun.star.drawing.CustomShape" + else if( sShapeType == "com.sun.star.drawing.ConnectorShape" ) + { + drawing::ConnectorType connectorType; + uno::Reference< beans::XPropertySet > xPropertySet( xShape, uno::UNO_QUERY_THROW ); + xPropertySet->getPropertyValue( "EdgeKind" ) >>= connectorType; + if( connectorType == drawing::ConnectorType_CURVE ) + return office::MsoShapeType::msoFreeform; + else if( connectorType == drawing::ConnectorType_LINE ) + return office::MsoShapeType::msoLine; + else + return office::MsoShapeType::msoAutoShape; + } + else if( sShapeType == "com.sun.star.drawing.LineShape" ) + return office::MsoShapeType::msoLine; + else if( sShapeType == "com.sun.star.drawing.CustomShape" + || sShapeType == "com.sun.star.drawing.RectangleShape" + || sShapeType == "com.sun.star.drawing.EllipseShape" ) + return office::MsoShapeType::msoAutoShape; + else if( sShapeType == "com.sun.star.drawing.TextShape" ) + return office::MsoShapeType::msoTextBox; + else + throw uno::RuntimeException("the shape type do not be supported: " + sShapeType ); +} + +sal_Int32 ScVbaShape::getAutoShapeType(const css::uno::Reference< drawing::XShape >& xShape) +{ + assert( ScVbaShape::getType( xShape ) == office::MsoShapeType::msoAutoShape ); + + OUString sShapeType; + uno::Reference< drawing::XShapeDescriptor > xShapeDescriptor( xShape, uno::UNO_QUERY_THROW ); + sShapeType = xShapeDescriptor->getShapeType(); + SAL_INFO("vbahelper", "ScVbaShape::getAutoShapeType: " << sShapeType); + + if( sShapeType == "com.sun.star.drawing.EllipseShape" ) + return office::MsoAutoShapeType::msoShapeOval; + else if ( sShapeType == "com.sun.star.drawing.RectangleShape" ) + return office::MsoAutoShapeType::msoShapeRectangle; + else if ( sShapeType == "com.sun.star.drawing.CustomShape" ) + { + uno::Reference< beans::XPropertySet > aXPropSet( xShape, uno::UNO_QUERY ); + uno::Any aGeoPropSet = aXPropSet->getPropertyValue( "CustomShapeGeometry" ); + uno::Sequence< beans::PropertyValue > aGeoPropSeq; + if ( aGeoPropSet >>= aGeoPropSeq ) + { + for( const auto& rProp : std::as_const(aGeoPropSeq) ) + { + if( rProp.Name == "Type" ) + { + OUString sType; + if( rProp.Value >>= sType ) + { + if( sType.endsWith( "ellipse" ) ) + return office::MsoAutoShapeType::msoShapeOval; + // TODO other custom shapes here + } + } + } + } + } + + SAL_WARN( "vbahelper", "ScVbaShape::getAutoShapeType: unknown auto type" ); + return -1; // could not decide + +} + +// Attributes +OUString SAL_CALL +ScVbaShape::getName() +{ + OUString sName; + uno::Reference< container::XNamed > xNamed( m_xShape, uno::UNO_QUERY_THROW ); + sName = xNamed->getName(); + return sName; +} + +void SAL_CALL +ScVbaShape::setName( const OUString& _name ) +{ + uno::Reference< container::XNamed > xNamed( m_xShape, uno::UNO_QUERY_THROW ); + xNamed->setName( _name ); +} + +OUString SAL_CALL +ScVbaShape::getAlternativeText() +{ + OUString sAltText; + uno::Reference< beans::XPropertySet > xProps( m_xShape, uno::UNO_QUERY_THROW ); + xProps->getPropertyValue("Title") >>= sAltText; + return sAltText; +} + +void SAL_CALL +ScVbaShape::setAlternativeText( const OUString& sAltText ) +{ + uno::Reference< beans::XPropertySet > xProps( m_xShape, uno::UNO_QUERY_THROW ); + xProps->setPropertyValue("Title", uno::Any( sAltText ) ); +} + +double SAL_CALL +ScVbaShape::getHeight() +{ + return m_pShapeHelper->getHeight(); +} + +void SAL_CALL +ScVbaShape::setHeight(double _height) +{ + m_pShapeHelper->setHeight( _height ); +} + +double SAL_CALL +ScVbaShape::getWidth() +{ + return m_pShapeHelper->getWidth(); +} + +void SAL_CALL +ScVbaShape::setWidth(double _width) +{ + m_pShapeHelper->setWidth( _width ); +} + +double SAL_CALL +ScVbaShape::getLeft() +{ + double left = 0; + try + { + left = m_pShapeHelper->getLeft(); + } + catch( uno::Exception& ) + { + // fail to get position by using XShape::getPosition() + sal_Int32 nLeft = 0; + m_xPropertySet->getPropertyValue( "HoriOrientPosition" ) >>= nLeft; + left = Millimeter::getInPoints( nLeft ); + } + return left; +} + +void SAL_CALL +ScVbaShape::setLeft( double _left ) +{ + try + { + m_pShapeHelper->setLeft( _left ); + } + catch( uno::Exception& ) + { + sal_Int32 nLeft = Millimeter::getInHundredthsOfOneMillimeter( _left ); + m_xPropertySet->setPropertyValue( "HoriOrientPosition" , uno::makeAny( nLeft ) ); + } +} + +double SAL_CALL +ScVbaShape::getTop() +{ + double top = 0; + try + { + top = m_pShapeHelper->getTop(); + } + catch( uno::Exception& ) + { + sal_Int32 nTop = 0; + m_xPropertySet->getPropertyValue( "VertOrientPosition" ) >>= nTop; + top = Millimeter::getInPoints( nTop ); + } + return top; +} + +void SAL_CALL +ScVbaShape::setTop( double _top ) +{ + try + { + m_pShapeHelper->setTop( _top ); + } + catch( uno::Exception& ) + { + sal_Int32 nTop = Millimeter::getInHundredthsOfOneMillimeter( _top ); + m_xPropertySet->setPropertyValue( "VertOrientPosition" , uno::makeAny( nTop ) ); + } +} + +sal_Bool SAL_CALL +ScVbaShape::getVisible() +{ + // #STUB + //UNO Shapes are always visible + return true; +} + +void SAL_CALL +ScVbaShape::setVisible( sal_Bool /*_visible*/ ) +{ + // #STUB + //UNO Shapes are always visible +} + +sal_Int32 SAL_CALL +ScVbaShape::getZOrderPosition() +{ + sal_Int32 nZOrderPosition = 0; + uno::Any aZOrderPosition = m_xPropertySet->getPropertyValue( "ZOrder" ); + aZOrderPosition >>= nZOrderPosition; + return nZOrderPosition + 1; +} + +sal_Int32 SAL_CALL +ScVbaShape::getType() +{ + return m_nType; +} + +double SAL_CALL +ScVbaShape::getRotation() +{ + double dRotation = 0; + sal_Int32 nRotation = 0; + m_xPropertySet->getPropertyValue( "RotateAngle" ) >>= nRotation; + dRotation = static_cast< double >( nRotation /100 ); + return dRotation; +} + +void SAL_CALL +ScVbaShape::setRotation( double _rotation ) +{ + sal_Int32 nRotation = static_cast < sal_Int32 > ( _rotation * 100 ); + m_xPropertySet->setPropertyValue( "RotateAngle" , uno::makeAny( nRotation ) ); +} + +uno::Reference< msforms::XLineFormat > SAL_CALL +ScVbaShape::getLine() +{ + // TODO should only return line + return uno::Reference< msforms::XLineFormat >( new ScVbaLineFormat( this, mxContext, m_xShape ) ); +} + +uno::Reference< msforms::XFillFormat > SAL_CALL +ScVbaShape::getFill() +{ + return uno::Reference< msforms::XFillFormat >( new ScVbaFillFormat( this, mxContext, m_xShape ) ); +} + +uno::Reference< msforms::XPictureFormat > SAL_CALL +ScVbaShape::getPictureFormat() +{ + return uno::Reference< msforms::XPictureFormat >( new ScVbaPictureFormat( this, mxContext, m_xShape ) ); +} + +// Methods +uno::Any SAL_CALL +ScVbaShape::TextFrame() +{ + uno::Reference< lang::XServiceInfo > xServiceInfo( m_xModel, uno::UNO_QUERY_THROW ); + if( xServiceInfo->supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) ) + { + uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext(); + uno::Sequence< uno::Any > aArgs(2); + aArgs[0] <<= getParent(); + aArgs[1] <<= m_xShape; + uno::Reference< uno::XInterface > xTextFrame = xContext->getServiceManager()->createInstanceWithArgumentsAndContext( "ooo.vba.excel.TextFrame" , aArgs, xContext ); + return uno::makeAny( xTextFrame ); + } + + return uno::makeAny( uno::Reference< msforms::XTextFrame >( new VbaTextFrame( this, mxContext, m_xShape ) ) ); +} + +void SAL_CALL +ScVbaShape::Delete() +{ + SolarMutexGuard aGuard; + m_xShapes->remove( m_xShape ); +} + +void SAL_CALL +ScVbaShape::ZOrder( sal_Int32 ZOrderCmd ) +{ + sal_Int32 nOrderPosition; + uno::Any aOrderPosition = m_xPropertySet->getPropertyValue( "ZOrder" ); + aOrderPosition >>= nOrderPosition; + switch( ZOrderCmd ) + { + case office::MsoZOrderCmd::msoBringToFront: + m_xPropertySet->setPropertyValue( "ZOrder" , uno::makeAny( SAL_MAX_INT32 ) ); + break; + case office::MsoZOrderCmd::msoSendToBack: + m_xPropertySet->setPropertyValue( "ZOrder" , uno::makeAny( sal_Int32(0) ) ); + break; + case office::MsoZOrderCmd::msoBringForward: + nOrderPosition += 1; + m_xPropertySet->setPropertyValue( "ZOrder" , uno::makeAny( nOrderPosition ) ); + break; + case office::MsoZOrderCmd::msoSendBackward: + if( nOrderPosition > 0 ) + { + nOrderPosition -= 1; + m_xPropertySet->setPropertyValue( "ZOrder" , uno::makeAny( nOrderPosition ) ); + } + break; + // below two commands use with Writer for text and image object. + case office::MsoZOrderCmd::msoBringInFrontOfText: + case office::MsoZOrderCmd::msoSendBehindText: + throw uno::RuntimeException( "This ZOrderCmd is not implemented, it is use with writer." ); + default: + throw uno::RuntimeException( "Invalid Parameter." ); + } +} + +void SAL_CALL +ScVbaShape::IncrementRotation( double Increment ) +{ + double nCurrentRotation = getRotation(); + nCurrentRotation += Increment; + setRotation(nCurrentRotation); +} + +void SAL_CALL +ScVbaShape::IncrementLeft( double Increment ) +{ + double nCurrentLeft = getLeft(); + nCurrentLeft += Increment; + setLeft(nCurrentLeft); +} + +void SAL_CALL +ScVbaShape::IncrementTop( double Increment ) +{ + double nCurrentTop = getTop(); + nCurrentTop += Increment; + setTop(nCurrentTop); +} + +void SAL_CALL +ScVbaShape::ScaleHeight( double Factor, sal_Bool /*RelativeToOriginalSize*/, sal_Int32 Scale ) +{ + double nHeight = getHeight(); + double nNewHeight = nHeight * Factor; + if( Scale == office::MsoScaleFrom::msoScaleFromTopLeft ) + { + setHeight(nNewHeight); + } + else if( Scale == office::MsoScaleFrom::msoScaleFromBottomRight ) + { + double nDeltaHeight = nNewHeight - nHeight; + double nNewTop = getTop() - nDeltaHeight; + setTop(nNewTop); + setHeight(nNewHeight); + } + else if( Scale == office::MsoScaleFrom::msoScaleFromMiddle ) + { + double nDeltaHeight = (nNewHeight - nHeight) / 2; + double nNewTop = getTop() - nDeltaHeight; + setTop(nNewTop); + setHeight(nNewHeight); + } + else + { + throw uno::RuntimeException( "ScaleHeight.Scale wrong value is given." ); + } +} + +void SAL_CALL +ScVbaShape::ScaleWidth( double Factor, sal_Bool /*RelativeToOriginalSize*/, sal_Int32 Scale ) +{ + double nWidth = getWidth(); + double nNewWidth = nWidth * Factor; + if( Scale == office::MsoScaleFrom::msoScaleFromTopLeft ) + { + setWidth(nNewWidth); + } + else if( Scale == office::MsoScaleFrom::msoScaleFromBottomRight ) + { + double nDeltaWidth = nNewWidth - nWidth; + double nNewLeft = getLeft() - nDeltaWidth; + setLeft(nNewLeft); + setWidth(nNewWidth); + } + else if( Scale == office::MsoScaleFrom::msoScaleFromMiddle ) + { + double nDeltaWidth = (nNewWidth - nWidth) / 2; + double nNewLeft = getLeft() - nDeltaWidth; + setLeft(nNewLeft); + setWidth(nNewWidth); + } + else + { + throw uno::RuntimeException( "ScaleHeight.Scale wrong value is given." ); + } +} + +void SAL_CALL +ScVbaShape::Select( const uno::Any& /*Replace*/ ) +{ + uno::Reference< view::XSelectionSupplier > xSelectSupp( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); + xSelectSupp->select( uno::makeAny( m_xShape ) ); +} + +// This method should not be part of Shape, what we really need to do is... +// dynamically create the appropriate objects e.g. TextBox, Oval, Picture etc. +// ( e.g. the ones that really do have ShapeRange as an attribute ) +uno::Any SAL_CALL +ScVbaShape::ShapeRange( const uno::Any& index ) +{ + // perhaps we should store a reference to the Shapes Collection + // in this class + // but anyway this method should not even be in this class + // #TODO not sure what the parent of the Shapes collection should be + + XNamedObjectCollectionHelper< drawing::XShape >::XNamedVec aVec; + aVec.push_back( m_xShape ); + uno::Reference< container::XIndexAccess > xIndexAccess( new XNamedObjectCollectionHelper< drawing::XShape >( aVec ) ); + uno::Reference< container::XChild > xChild( m_xShape, uno::UNO_QUERY_THROW ); + // #FIXME for want of a better parent, setting this + uno::Reference< msforms::XShapeRange > xShapeRange( new ScVbaShapeRange( mxParent, mxContext, xIndexAccess, uno::Reference< drawing::XDrawPage >( xChild->getParent(), uno::UNO_QUERY_THROW ), m_xModel ) ); + if ( index.hasValue() ) + return xShapeRange->Item( index, uno::Any() ); + return uno::makeAny( xShapeRange ); +} + +sal_Bool SAL_CALL +ScVbaShape::getLockAspectRatio() +{ + // #STUB + return false; +} + +void SAL_CALL +ScVbaShape::setLockAspectRatio( sal_Bool /*_lockaspectratio*/ ) +{ + // #STUB +} + +sal_Bool SAL_CALL +ScVbaShape::getLockAnchor() +{ + // #STUB + return true; +} + +void SAL_CALL +ScVbaShape::setLockAnchor( sal_Bool /*_lockanchor*/ ) +{ + // #STUB +} + +sal_Int32 SAL_CALL +ScVbaShape::getRelativeHorizontalPosition() +{ + sal_Int32 nRelativeHorizontalPosition = word::WdRelativeHorizontalPosition::wdRelativeHorizontalPositionMargin; + sal_Int16 nType = text::RelOrientation::PAGE_LEFT; + m_xPropertySet->getPropertyValue( "HoriOrientRelation" ) >>= nType; + + switch( nType ) + { + case text::RelOrientation::FRAME: + { + nRelativeHorizontalPosition = word::WdRelativeHorizontalPosition::wdRelativeHorizontalPositionColumn; + break; + } + case text::RelOrientation::PAGE_FRAME: + { + nRelativeHorizontalPosition = word::WdRelativeHorizontalPosition::wdRelativeHorizontalPositionPage; + break; + } + case text::RelOrientation::CHAR: + { + nRelativeHorizontalPosition = word::WdRelativeHorizontalPosition::wdRelativeHorizontalPositionCharacter; + break; + } + case text::RelOrientation::PAGE_PRINT_AREA: + { + nRelativeHorizontalPosition = word::WdRelativeHorizontalPosition::wdRelativeHorizontalPositionMargin; + break; + } + default: + { + throw uno::RuntimeException( "Shape::RelativeHorizontalPosition: not implemented" ); + } + } + return nRelativeHorizontalPosition; +} + +void SAL_CALL +ScVbaShape::setRelativeHorizontalPosition(::sal_Int32 _relativehorizontalposition) +{ + sal_Int16 nType = text::RelOrientation::PAGE_FRAME; + switch( _relativehorizontalposition ) + { + case word::WdRelativeHorizontalPosition::wdRelativeHorizontalPositionCharacter: + { + nType = text::RelOrientation::CHAR; + break; + } + case word::WdRelativeHorizontalPosition::wdRelativeHorizontalPositionColumn: + { + nType = text::RelOrientation::PAGE_FRAME; + break; + } + case word::WdRelativeHorizontalPosition::wdRelativeHorizontalPositionMargin: + { + nType = text::RelOrientation::PAGE_PRINT_AREA; + break; + } + case word::WdRelativeHorizontalPosition::wdRelativeHorizontalPositionPage: + { + nType = text::RelOrientation::PAGE_FRAME; + break; + } + default: + { + DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_ARGUMENT); + } + } + m_xPropertySet->setPropertyValue( "HoriOrientRelation" , uno::makeAny( nType ) ); +} + +sal_Int32 SAL_CALL +ScVbaShape::getRelativeVerticalPosition() +{ + sal_Int32 nRelativeVerticalPosition = word::WdRelativeVerticalPosition::wdRelativeVerticalPositionMargin; + sal_Int16 nType = text::RelOrientation::PAGE_FRAME; + m_xPropertySet->getPropertyValue( "VertOrientRelation" ) >>= nType; + + switch( nType ) + { + case text::RelOrientation::FRAME: + { + nRelativeVerticalPosition = word::WdRelativeVerticalPosition::wdRelativeVerticalPositionParagraph; + break; + } + case text::RelOrientation::PAGE_FRAME: + { + nRelativeVerticalPosition = word::WdRelativeVerticalPosition::wdRelativeVerticalPositionPage; + break; + } + case text::RelOrientation::TEXT_LINE: + { + nRelativeVerticalPosition = word::WdRelativeVerticalPosition::wdRelativeVerticalPositionLine; + break; + } + case text::RelOrientation::PAGE_PRINT_AREA: + { + nRelativeVerticalPosition = word::WdRelativeVerticalPosition::wdRelativeVerticalPositionMargin; + break; + } + default: + { + throw uno::RuntimeException( "Shape::RelativeVerticalPosition: not implemented" ); + } + } + return nRelativeVerticalPosition; +} + +void SAL_CALL +ScVbaShape::setRelativeVerticalPosition(::sal_Int32 _relativeverticalposition) +{ + sal_Int16 nType = text::RelOrientation::PAGE_FRAME; + switch( _relativeverticalposition ) + { + case word::WdRelativeVerticalPosition::wdRelativeVerticalPositionLine: + { + nType = text::RelOrientation::TEXT_LINE; + break; + } + case word::WdRelativeVerticalPosition::wdRelativeVerticalPositionParagraph: + { + nType = text::RelOrientation::FRAME; + break; + } + case word::WdRelativeVerticalPosition::wdRelativeVerticalPositionMargin: + { + nType = text::RelOrientation::PAGE_PRINT_AREA; + break; + } + case word::WdRelativeVerticalPosition::wdRelativeVerticalPositionPage: + { + nType = text::RelOrientation::PAGE_FRAME; + break; + } + default: + { + DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_ARGUMENT); + } + } + m_xPropertySet->setPropertyValue( "VertOrientRelation" , uno::makeAny( nType ) ); +} + +uno::Any SAL_CALL +ScVbaShape::WrapFormat() +{ + uno::Reference< lang::XServiceInfo > xServiceInfo( m_xModel, uno::UNO_QUERY_THROW ); + if( xServiceInfo->supportsService( "com.sun.star.text.TextDocument" )) + { + uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext(); + uno::Sequence< uno::Any > aArgs(2); + aArgs[0] <<= getParent(); + aArgs[1] <<= m_xShape; + uno::Reference< uno::XInterface > xWrapFormat = xContext->getServiceManager()->createInstanceWithArgumentsAndContext( "ooo.vba.word.WrapFormat" , aArgs, xContext ); + return uno::makeAny( xWrapFormat ); + } + throw uno::RuntimeException( "Not implemented" ); +} + +OUString +ScVbaShape::getServiceImplName() +{ + return "ScVbaShape"; +} + +uno::Sequence< OUString > +ScVbaShape::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msform.Shape" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbashaperange.cxx b/vbahelper/source/vbahelper/vbashaperange.cxx new file mode 100644 index 000000000..7e69fc01b --- /dev/null +++ b/vbahelper/source/vbahelper/vbashaperange.cxx @@ -0,0 +1,419 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <com/sun/star/drawing/ShapeCollection.hpp> +#include <com/sun/star/drawing/XShapeGrouper.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <ooo/vba/office/MsoShapeType.hpp> + +#include <vbahelper/vbashaperange.hxx> +#include <vbahelper/vbashape.hxx> +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class VbShapeRangeEnumHelper : public EnumerationHelper_BASE +{ + uno::Reference< XCollection > m_xParent; + uno::Reference<container::XIndexAccess > m_xIndexAccess; + sal_Int32 nIndex; +public: + VbShapeRangeEnumHelper( const uno::Reference< XCollection >& xParent, const uno::Reference< container::XIndexAccess >& xIndexAccess ) : m_xParent( xParent ), m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {} + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( nIndex < m_xIndexAccess->getCount() ); + } + virtual uno::Any SAL_CALL nextElement( ) override + { + ScVbaShapeRange* pCollectionImpl = dynamic_cast< ScVbaShapeRange* >(m_xParent.get()); + if ( pCollectionImpl && hasMoreElements() ) + return pCollectionImpl->createCollectionObject( m_xIndexAccess->getByIndex( nIndex++ ) ); + throw container::NoSuchElementException(); + } + +}; + +} + +ScVbaShapeRange::ScVbaShapeRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xShapes, const uno::Reference< drawing::XDrawPage >& xDrawPage, const uno::Reference< frame::XModel >& xModel ) : ScVbaShapeRange_BASE( xParent, xContext, xShapes ), m_xDrawPage( xDrawPage ), m_xModel( xModel ) +{ +} + +// Methods +void SAL_CALL +ScVbaShapeRange::Select( ) +{ + uno::Reference< view::XSelectionSupplier > xSelectSupp( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); + xSelectSupp->select( uno::makeAny( getShapes() ) ); +} + +uno::Reference< msforms::XShape > SAL_CALL +ScVbaShapeRange::Group() +{ + uno::Reference< drawing::XShapeGrouper > xShapeGrouper( m_xDrawPage, uno::UNO_QUERY_THROW ); + uno::Reference< drawing::XShapeGroup > xShapeGroup( xShapeGrouper->group( getShapes() ), uno::UNO_SET_THROW ); + uno::Reference< drawing::XShape > xShape( xShapeGroup, uno::UNO_QUERY_THROW ); + return uno::Reference< msforms::XShape >( new ScVbaShape( getParent(), mxContext, xShape, getShapes(), m_xModel, office::MsoShapeType::msoGroup ) ); +} + +uno::Reference< drawing::XShapes > const & +ScVbaShapeRange::getShapes() +{ + if ( !m_xShapes.is() ) + { + m_xShapes.set( drawing::ShapeCollection::create(mxContext) ); + sal_Int32 nLen = m_xIndexAccess->getCount(); + for ( sal_Int32 index = 0; index < nLen; ++index ) + m_xShapes->add( uno::Reference< drawing::XShape >( m_xIndexAccess->getByIndex( index ), uno::UNO_QUERY_THROW ) ); + + } + return m_xShapes; +} + + +void SAL_CALL +ScVbaShapeRange::IncrementRotation( double Increment ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->IncrementRotation( Increment ); + } +} + +void SAL_CALL +ScVbaShapeRange::IncrementLeft( double Increment ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->IncrementLeft( Increment ); + } +} + +void SAL_CALL +ScVbaShapeRange::IncrementTop( double Increment ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->IncrementTop( Increment ); + } +} + +OUString SAL_CALL ScVbaShapeRange::getName() +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->getName( ); + } + throw uno::RuntimeException(); +} + +void SAL_CALL ScVbaShapeRange::setName( const OUString& _name ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->setName( _name ); + } +} + +double SAL_CALL ScVbaShapeRange::getHeight() +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->getHeight( ); + } + throw uno::RuntimeException(); +} + +void SAL_CALL ScVbaShapeRange::setHeight( double _height ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->setHeight( _height ); + } +} + +double SAL_CALL ScVbaShapeRange::getWidth() +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->getWidth( ); + } + throw uno::RuntimeException(); +} + +void SAL_CALL ScVbaShapeRange::setWidth( double _width ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->setWidth( _width ); + } +} + +double SAL_CALL ScVbaShapeRange::getLeft() +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->getLeft(); + } + throw uno::RuntimeException(); +} + +void SAL_CALL ScVbaShapeRange::setLeft( double _left ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->setLeft( _left ); + } +} + +double SAL_CALL ScVbaShapeRange::getTop() +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->getTop(); + } + throw uno::RuntimeException(); +} + +void SAL_CALL ScVbaShapeRange::setTop( double _top ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->setTop( _top ); + } +} + +uno::Reference< ov::msforms::XLineFormat > SAL_CALL ScVbaShapeRange::getLine() +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->getLine(); + } + throw uno::RuntimeException(); +} + +uno::Reference< ov::msforms::XFillFormat > SAL_CALL ScVbaShapeRange::getFill() +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->getFill(); + } + throw uno::RuntimeException(); +} + +sal_Bool SAL_CALL ScVbaShapeRange::getLockAspectRatio() +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->getLockAspectRatio(); + } + throw uno::RuntimeException(); +} + +void SAL_CALL ScVbaShapeRange::setLockAspectRatio( sal_Bool _lockaspectratio ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->setLockAspectRatio( _lockaspectratio ); + } +} + +sal_Bool SAL_CALL ScVbaShapeRange::getLockAnchor() +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->getLockAnchor(); + } + throw uno::RuntimeException(); +} + +void SAL_CALL ScVbaShapeRange::setLockAnchor( sal_Bool _lockanchor ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->setLockAnchor( _lockanchor ); + } +} + +::sal_Int32 SAL_CALL ScVbaShapeRange::getRelativeHorizontalPosition() +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->getRelativeHorizontalPosition(); + } + throw uno::RuntimeException(); +} + +void SAL_CALL ScVbaShapeRange::setRelativeHorizontalPosition( ::sal_Int32 _relativehorizontalposition ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->setRelativeHorizontalPosition( _relativehorizontalposition ); + } +} + +::sal_Int32 SAL_CALL ScVbaShapeRange::getRelativeVerticalPosition() +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->getRelativeVerticalPosition(); + } + throw uno::RuntimeException(); +} + +void SAL_CALL ScVbaShapeRange::setRelativeVerticalPosition( ::sal_Int32 _relativeverticalposition ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->setRelativeVerticalPosition( _relativeverticalposition ); + } +} + +uno::Any SAL_CALL ScVbaShapeRange::TextFrame( ) +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->TextFrame(); + } + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL ScVbaShapeRange::WrapFormat( ) +{ + sal_Int32 nLen = getCount(); + sal_Int32 index = 1; + if (index <= nLen) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + return xShape->WrapFormat(); + } + throw uno::RuntimeException(); +} + +void SAL_CALL ScVbaShapeRange::ZOrder( sal_Int32 ZOrderCmd ) +{ + sal_Int32 nLen = getCount(); + for ( sal_Int32 index = 1; index <= nLen; ++index ) + { + uno::Reference< msforms::XShape > xShape( Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); + xShape->ZOrder( ZOrderCmd ); + } +} + +uno::Type SAL_CALL +ScVbaShapeRange::getElementType() +{ + return cppu::UnoType<msforms::XShape>::get(); +} + +uno::Reference< container::XEnumeration > SAL_CALL +ScVbaShapeRange::createEnumeration() +{ + return new VbShapeRangeEnumHelper( this, m_xIndexAccess ); +} + +uno::Any +ScVbaShapeRange:: createCollectionObject( const css::uno::Any& aSource ) +{ + uno::Reference< drawing::XShape > xShape( aSource, uno::UNO_QUERY_THROW ); + // #TODO #FIXME Shape parent should always be the sheet the shapes belong + // to + uno::Reference< msforms::XShape > xVbShape( new ScVbaShape( uno::Reference< XHelperInterface >(), mxContext, xShape, getShapes(), m_xModel, ScVbaShape::getType( xShape ) ) ); + return uno::makeAny( xVbShape ); +} + +OUString +ScVbaShapeRange::getServiceImplName() +{ + return "ScVbaShapeRange"; +} + +uno::Sequence< OUString > +ScVbaShapeRange::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msform.ShapeRange" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbashapes.cxx b/vbahelper/source/vbahelper/vbashapes.cxx new file mode 100644 index 000000000..6177a23b5 --- /dev/null +++ b/vbahelper/source/vbahelper/vbashapes.cxx @@ -0,0 +1,421 @@ +/* -*- 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/view/XSelectionSupplier.hpp> +#include <com/sun/star/text/WrapTextMode.hpp> +#include <ooo/vba/msforms/XShapeRange.hpp> +#include <ooo/vba/office/MsoAutoShapeType.hpp> +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/script/BasicErrorException.hpp> +#include <com/sun/star/script/XTypeConverter.hpp> +#include <com/sun/star/text/TextContentAnchorType.hpp> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/text/VertOrientation.hpp> +#include <com/sun/star/text/RelOrientation.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/drawing/XShapes.hpp> + +#include <vbahelper/vbahelper.hxx> +#include <vbahelper/vbashape.hxx> +#include <vbahelper/vbashapes.hxx> +#include <vbahelper/vbashaperange.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +namespace { + +class VbShapeEnumHelper : public EnumerationHelper_BASE +{ + uno::Reference<msforms::XShapes > m_xParent; + uno::Reference<container::XIndexAccess > m_xIndexAccess; + sal_Int32 nIndex; +public: + VbShapeEnumHelper( const uno::Reference< msforms::XShapes >& xParent, const uno::Reference< container::XIndexAccess >& xIndexAccess ) : m_xParent( xParent ), m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {} + virtual sal_Bool SAL_CALL hasMoreElements( ) override + { + return ( nIndex < m_xIndexAccess->getCount() ); + } + virtual uno::Any SAL_CALL nextElement( ) override + { + ScVbaShapes* pShapes = dynamic_cast< ScVbaShapes* >(m_xParent.get()); + if ( pShapes && hasMoreElements() ) + return pShapes->createCollectionObject( m_xIndexAccess->getByIndex( nIndex++ ) ); + throw container::NoSuchElementException(); + } + +}; + +} + +void ScVbaShapes::initBaseCollection() +{ + if ( m_xNameAccess.is() ) // already has NameAccess + return; + // no NameAccess then use ShapeCollectionHelper + XNamedObjectCollectionHelper< drawing::XShape >::XNamedVec aShapes; + sal_Int32 nLen = m_xIndexAccess->getCount(); + aShapes.reserve( nLen ); + for ( sal_Int32 index=0; index<nLen; ++index ) + aShapes.emplace_back( m_xIndexAccess->getByIndex( index ) , uno::UNO_QUERY ); + uno::Reference< container::XIndexAccess > xShapes( new XNamedObjectCollectionHelper< drawing::XShape >( aShapes ) ); + m_xIndexAccess = xShapes; + m_xNameAccess.set( xShapes, uno::UNO_QUERY ); +} + +ScVbaShapes::ScVbaShapes( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xShapes, const uno::Reference< frame::XModel>& xModel ): ScVbaShapes_BASE( xParent, xContext, xShapes, true ), m_nNewShapeCount(0), m_xModel( xModel ) +{ + m_xShapes.set( xShapes, uno::UNO_QUERY_THROW ); + m_xDrawPage.set( xShapes, uno::UNO_QUERY_THROW ); + initBaseCollection(); +} + +uno::Reference< container::XEnumeration > +ScVbaShapes::createEnumeration() +{ + return new VbShapeEnumHelper( this, m_xIndexAccess ); +} + +uno::Any +ScVbaShapes::createCollectionObject( const css::uno::Any& aSource ) +{ + if( aSource.hasValue() ) + { + uno::Reference< drawing::XShape > xShape( aSource, uno::UNO_QUERY_THROW ); + return uno::makeAny( uno::Reference< msforms::XShape >( new ScVbaShape( getParent(), mxContext, xShape, m_xShapes, m_xModel, ScVbaShape::getType( xShape ) ) ) ); + } + return uno::Any(); +} + +uno::Type +ScVbaShapes::getElementType() +{ + return cppu::UnoType<ooo::vba::msforms::XShape>::get(); +} + +OUString +ScVbaShapes::getServiceImplName() +{ + return "ScVbaShapes"; +} + +uno::Sequence< OUString > +ScVbaShapes::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msform.Shapes" + }; + return aServiceNames; +} + +css::uno::Reference< css::container::XIndexAccess > +ScVbaShapes::getShapesByArrayIndices( const uno::Any& Index ) +{ + if ( Index.getValueTypeClass() != uno::TypeClass_SEQUENCE ) + throw uno::RuntimeException(); + + const uno::Reference< script::XTypeConverter >& xConverter = getTypeConverter(mxContext); + uno::Any aConverted = xConverter->convertTo( Index, cppu::UnoType<uno::Sequence< uno::Any >>::get() ); + + uno::Sequence< uno::Any > sIndices; + aConverted >>= sIndices; + XNamedObjectCollectionHelper< drawing::XShape >::XNamedVec aShapes; + for( const auto& rIndex : std::as_const(sIndices) ) + { + uno::Reference< drawing::XShape > xShape; + if ( rIndex.getValueTypeClass() == uno::TypeClass_STRING ) + { + OUString sName; + rIndex >>= sName; + xShape.set( m_xNameAccess->getByName( sName ), uno::UNO_QUERY ); + } + else + { + sal_Int32 nIndex = 0; + rIndex >>= nIndex; + // adjust for 1 based mso indexing + xShape.set( m_xIndexAccess->getByIndex( nIndex - 1 ), uno::UNO_QUERY ); + + } + // populate map with drawing::XShapes + if ( xShape.is() ) + aShapes.push_back( xShape ); + } + uno::Reference< container::XIndexAccess > xIndexAccess( new XNamedObjectCollectionHelper< drawing::XShape >( aShapes ) ); + return xIndexAccess; +} + +uno::Reference< msforms::XShapeRange > SAL_CALL +ScVbaShapes::Range( const uno::Any& shapes ) +{ + // shapes, can be an index or an array of indices + uno::Reference< container::XIndexAccess > xShapes; + if ( shapes.getValueTypeClass() == uno::TypeClass_SEQUENCE ) + xShapes = getShapesByArrayIndices( shapes ); + else + { + // wrap single index into a sequence + uno::Sequence< uno::Any > sIndices(1); + sIndices[ 0 ] = shapes; + uno::Any aIndex; + aIndex <<= sIndices; + xShapes = getShapesByArrayIndices( aIndex ); + } + return new ScVbaShapeRange( getParent(), mxContext, xShapes, m_xDrawPage, m_xModel ); +} + +void SAL_CALL +ScVbaShapes::SelectAll() +{ + uno::Reference< view::XSelectionSupplier > xSelectSupp( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); + try + { + xSelectSupp->select( uno::makeAny( m_xShapes ) ); + } + // viewuno.cxx ScTabViewObj::select will throw IllegalArgumentException + // if one of the shapes is no 'markable' e.g. a button + // the method still works + catch(const lang::IllegalArgumentException&) + { + } +} + +uno::Reference< drawing::XShape > +ScVbaShapes::createShape( const OUString& service ) +{ + uno::Reference< lang::XMultiServiceFactory > xMSF( m_xModel, uno::UNO_QUERY_THROW ); + uno::Reference< drawing::XShape > xShape( xMSF->createInstance( service ), uno::UNO_QUERY_THROW ); + return xShape; +} + +uno::Any +ScVbaShapes::AddRectangle(sal_Int32 startX, sal_Int32 startY, sal_Int32 nLineWidth, sal_Int32 nLineHeight) +{ + sal_Int32 nXPos = Millimeter::getInHundredthsOfOneMillimeter( startX ); + sal_Int32 nYPos = Millimeter::getInHundredthsOfOneMillimeter( startY ); + sal_Int32 nWidth = Millimeter::getInHundredthsOfOneMillimeter( nLineWidth ); + sal_Int32 nHeight = Millimeter::getInHundredthsOfOneMillimeter( nLineHeight ); + + uno::Reference< drawing::XShape > xShape( createShape( "com.sun.star.drawing.RectangleShape" ), uno::UNO_SET_THROW ); + m_xShapes->add( xShape ); + + OUString sName(createName( "Rectangle" )); + setDefaultShapeProperties( xShape ); + setShape_NameProperty( xShape, sName ); + + awt::Point aMovePositionIfRange(0, 0); + awt::Point position; + position.X = nXPos - aMovePositionIfRange.X; + position.Y = nYPos - aMovePositionIfRange.Y; + xShape->setPosition( position ); + + awt::Size size; + size.Height = nHeight; + size.Width = nWidth; + xShape->setSize( size ); + + ScVbaShape *pScVbaShape = new ScVbaShape( getParent(), mxContext, xShape, m_xShapes, m_xModel, ScVbaShape::getType( xShape ) ); + return uno::makeAny( uno::Reference< msforms::XShape > ( pScVbaShape ) ); +} + +uno::Any +ScVbaShapes::AddEllipse(sal_Int32 startX, sal_Int32 startY, sal_Int32 nLineWidth, sal_Int32 nLineHeight) +{ + sal_Int32 nXPos = Millimeter::getInHundredthsOfOneMillimeter( startX ); + sal_Int32 nYPos = Millimeter::getInHundredthsOfOneMillimeter( startY ); + sal_Int32 nWidth = Millimeter::getInHundredthsOfOneMillimeter( nLineWidth ); + sal_Int32 nHeight = Millimeter::getInHundredthsOfOneMillimeter( nLineHeight ); + + uno::Reference< drawing::XShape > xShape( createShape( "com.sun.star.drawing.EllipseShape" ), uno::UNO_SET_THROW ); + m_xShapes->add( xShape ); + + awt::Point aMovePositionIfRange( 0, 0 ); + //TODO helperapi using a writer document + /* + XDocument xDocument = (XDocument)getParent(); + if (AnyConverter.isVoid(_aRange)) + { + _aRange = xDocument.Range(new Integer(0), new Integer(1)); + // Top&Left in Word is Top&Left of the paper and not the writeable area. + aMovePositionIfRange = calculateTopLeftMargin((HelperInterfaceAdaptor)xDocument); + } + + setShape_AnchorTypeAndRangeProperty(xShape, _aRange); + */ + OUString name(createName( "Oval" )); + setDefaultShapeProperties(xShape); + setShape_NameProperty(xShape, name); + + awt::Point position; + position.X = nXPos - aMovePositionIfRange.X; + position.Y = nYPos - aMovePositionIfRange.Y; + xShape->setPosition(position); + + awt::Size size; + size.Height = nHeight; + size.Width = nWidth; + xShape->setSize(size); + + ScVbaShape *pScVbaShape = new ScVbaShape( getParent(), mxContext, xShape, m_xShapes, m_xModel, ScVbaShape::getType( xShape ) ); + return uno::makeAny( uno::Reference< msforms::XShape > ( pScVbaShape ) ); +} + +//helperapi calc +uno::Any SAL_CALL +ScVbaShapes::AddLine( sal_Int32 StartX, sal_Int32 StartY, sal_Int32 endX, sal_Int32 endY ) +{ + sal_Int32 nLineWidth = endX - StartX; + sal_Int32 nLineHeight = endY - StartY; + + sal_Int32 nHeight = Millimeter::getInHundredthsOfOneMillimeter( nLineHeight ); + sal_Int32 nWidth = Millimeter::getInHundredthsOfOneMillimeter( nLineWidth ); + sal_Int32 nXPos = Millimeter::getInHundredthsOfOneMillimeter( StartX ); + sal_Int32 nYPos = Millimeter::getInHundredthsOfOneMillimeter( StartY ); + + uno::Reference< drawing::XShape > xShape( createShape( "com.sun.star.drawing.LineShape" ), uno::UNO_SET_THROW ); + m_xShapes->add( xShape ); + + awt::Point aMovePositionIfRange( 0, 0 ); + + OUString name(createName( "Line" )); + setDefaultShapeProperties(xShape); + setShape_NameProperty(xShape, name); + + awt::Point position; + position.X = nXPos - aMovePositionIfRange.X; + position.Y = nYPos - aMovePositionIfRange.Y; + xShape->setPosition(position); + + awt::Size size; + size.Height = nHeight; + size.Width = nWidth; + xShape->setSize(size); + + ScVbaShape *pScVbaShape = new ScVbaShape( getParent(), mxContext, xShape, m_xShapes, m_xModel, ScVbaShape::getType( xShape ) ); + return uno::makeAny( uno::Reference< msforms::XShape > ( pScVbaShape ) ); +} + +uno::Any SAL_CALL +ScVbaShapes::AddShape( sal_Int32 _nType, sal_Int32 _nLeft, sal_Int32 _nTop, sal_Int32 _nWidth, sal_Int32 _nHeight ) +{ + if (_nType == office::MsoAutoShapeType::msoShapeRectangle) + { + return AddRectangle(_nLeft, _nTop, _nWidth, _nHeight); + } + else if (_nType == office::MsoAutoShapeType::msoShapeOval) + { + return AddEllipse(_nLeft, _nTop, _nWidth, _nHeight); + } + return uno::Any(); +} + +uno::Any SAL_CALL +ScVbaShapes::AddTextbox( sal_Int32 /*_nOrientation*/, sal_Int32 _nLeft, sal_Int32 _nTop, sal_Int32 _nWidth, sal_Int32 _nHeight ) +{ + uno::Reference< lang::XServiceInfo > xServiceInfo( m_xModel, uno::UNO_QUERY_THROW ); + if( xServiceInfo->supportsService( "com.sun.star.text.TextDocument" ) ) + { + return AddTextboxInWriter( _nLeft, _nTop, _nWidth, _nHeight ); + } + throw uno::RuntimeException( "Not implemented" ); +} + +uno::Any +ScVbaShapes::AddTextboxInWriter( sal_Int32 _nLeft, sal_Int32 _nTop, sal_Int32 _nWidth, sal_Int32 _nHeight ) +{ + sal_Int32 nXPos = Millimeter::getInHundredthsOfOneMillimeter( _nLeft ); + sal_Int32 nYPos = Millimeter::getInHundredthsOfOneMillimeter( _nTop ); + sal_Int32 nWidth = Millimeter::getInHundredthsOfOneMillimeter( _nWidth ); + sal_Int32 nHeight = Millimeter::getInHundredthsOfOneMillimeter( _nHeight ); + + uno::Reference< drawing::XShape > xShape( createShape( "com.sun.star.drawing.TextShape" ), uno::UNO_SET_THROW ); + m_xShapes->add( xShape ); + + setDefaultShapeProperties(xShape); + + OUString sName(createName( "Text Box" )); + setShape_NameProperty( xShape, sName ); + + awt::Size size; + size.Height = nHeight; + size.Width = nWidth; + xShape->setSize(size); + + uno::Reference< beans::XPropertySet > xShapeProps( xShape, uno::UNO_QUERY_THROW ); + xShapeProps->setPropertyValue( "AnchorType", uno::makeAny( text::TextContentAnchorType_AT_PAGE ) ); + xShapeProps->setPropertyValue( "HoriOrientRelation", uno::makeAny( text::RelOrientation::PAGE_LEFT ) ); + xShapeProps->setPropertyValue( "HoriOrient", uno::makeAny( text::HoriOrientation::NONE ) ); + xShapeProps->setPropertyValue( "HoriOrientPosition", uno::makeAny( nXPos ) ); + + xShapeProps->setPropertyValue( "VertOrientRelation", uno::makeAny( text::RelOrientation::PAGE_FRAME ) ); + xShapeProps->setPropertyValue( "VertOrient", uno::makeAny( text::VertOrientation::NONE ) ); + xShapeProps->setPropertyValue( "VertOrientPosition", uno::makeAny( nYPos ) ); + + // set to visible + xShapeProps->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_SOLID ) ); + // set to font + xShapeProps->setPropertyValue( "LayerID", uno::makeAny( sal_Int16(1) ) ); + xShapeProps->setPropertyValue( "LayerName", uno::makeAny( OUString("Heaven") ) ); + + + ScVbaShape *pScVbaShape = new ScVbaShape( getParent(), mxContext, xShape, m_xShapes, m_xModel, ScVbaShape::getType( xShape ) ); + return uno::makeAny( uno::Reference< msforms::XShape > ( pScVbaShape ) ); +} + +void +ScVbaShapes::setDefaultShapeProperties( const uno::Reference< drawing::XShape >& xShape ) +{ + uno::Reference< beans::XPropertySet > xPropertySet( xShape, uno::UNO_QUERY_THROW ); + xPropertySet->setPropertyValue( "FillStyle", uno::makeAny( OUString("SOLID") ) ); + xPropertySet->setPropertyValue( "FillColor", uno::makeAny( sal_Int32(0xFFFFFF) ) ); + xPropertySet->setPropertyValue( "TextWordWrap", uno::makeAny( text::WrapTextMode_THROUGH ) ); + //not find in OOo2.3 + //xPropertySet->setPropertyValue("Opaque", uno::makeAny( sal_True ) ); +} + +void +ScVbaShapes::setShape_NameProperty( const uno::Reference< css::drawing::XShape >& xShape, const OUString& sName ) +{ + uno::Reference< beans::XPropertySet > xPropertySet( xShape, uno::UNO_QUERY_THROW ); + try + { + xPropertySet->setPropertyValue( "Name", uno::makeAny( sName ) ); + } + catch(const script::BasicErrorException&) + { + } +} + +OUString +ScVbaShapes::createName( const OUString& sName ) +{ + sal_Int32 nActNumber = 1 + m_nNewShapeCount; + m_nNewShapeCount++; + return sName + OUString::number( nActNumber ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbatextframe.cxx b/vbahelper/source/vbahelper/vbatextframe.cxx new file mode 100644 index 000000000..6e19734cd --- /dev/null +++ b/vbahelper/source/vbahelper/vbatextframe.cxx @@ -0,0 +1,157 @@ +/* -*- 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/beans/XPropertySet.hpp> +#include <com/sun/star/drawing/TextFitToSizeType.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include <vbahelper/vbatextframe.hxx> + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +VbaTextFrame::VbaTextFrame( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, uno::Reference< drawing::XShape > const & xShape ) : VbaTextFrame_BASE( xParent, xContext ), m_xShape( xShape ) +{ + m_xPropertySet.set( m_xShape, uno::UNO_QUERY_THROW ); +} + +void +VbaTextFrame::setAsMSObehavior() +{ + //set property TextWordWrap default as False. + // TextFitToSize control the text content. It seems we should set the default as False. + // com.sun.star.drawing.TextFitToSizeType.NONE + m_xPropertySet->setPropertyValue( "TextWordWrap", uno::makeAny( false ) ); + m_xPropertySet->setPropertyValue( "TextFitToSize", uno::makeAny( drawing::TextFitToSizeType_NONE ) ); +} + +sal_Int32 VbaTextFrame::getMargin( const OUString& sMarginType ) +{ + sal_Int32 nMargin = 0; + uno::Any aMargin = m_xPropertySet->getPropertyValue( sMarginType ); + aMargin >>= nMargin; + return nMargin; +} + +void VbaTextFrame::setMargin( const OUString& sMarginType, float fMargin ) +{ + sal_Int32 nMargin = Millimeter::getInHundredthsOfOneMillimeter( fMargin ); + m_xPropertySet->setPropertyValue( sMarginType, uno::makeAny( nMargin ) ); +} + +// Attributes +sal_Bool SAL_CALL +VbaTextFrame::getAutoSize() +{ + // I don't know why, but in OOo, TextAutoGrowHeight is the property control autosize. not TextFitToSize. + // TextFitToSize control the text content. + // and in mso, there isnot option TextWordWrap which means auto wrap. the default is False. + bool bAutosize = false; + uno::Any aTextAutoGrowHeight = m_xPropertySet->getPropertyValue( "TextAutoGrowHeight" ); + aTextAutoGrowHeight >>= bAutosize; + return bAutosize; +} + +void SAL_CALL +VbaTextFrame::setAutoSize( sal_Bool _autosize ) +{ + setAsMSObehavior(); + m_xPropertySet->setPropertyValue( "TextAutoGrowHeight", uno::makeAny( _autosize ) ); +} + +float SAL_CALL +VbaTextFrame::getMarginBottom() +{ + sal_Int32 nMargin = getMargin( "TextLowerDistance" ); + float fMargin = static_cast<float>(Millimeter::getInPoints( nMargin )); + return fMargin; +} + +void SAL_CALL +VbaTextFrame::setMarginBottom( float _marginbottom ) +{ + setMargin( "TextLowerDistance", _marginbottom ); +} + +float SAL_CALL +VbaTextFrame::getMarginTop() +{ + sal_Int32 nMargin = getMargin( "TextUpperDistance" ); + float fMargin = static_cast<float>(Millimeter::getInPoints( nMargin )); + return fMargin; +} + +void SAL_CALL +VbaTextFrame::setMarginTop( float _margintop ) +{ + setMargin( "TextUpperDistance", _margintop ); +} + +float SAL_CALL +VbaTextFrame::getMarginLeft() +{ + sal_Int32 nMargin = getMargin( "TextLeftDistance" ); + float fMargin = static_cast<float>(Millimeter::getInPoints( nMargin )); + return fMargin; +} + +void SAL_CALL +VbaTextFrame::setMarginLeft( float _marginleft ) +{ + setMargin( "TextLeftDistance", _marginleft ); +} + +float SAL_CALL +VbaTextFrame::getMarginRight() +{ + sal_Int32 nMargin = getMargin( "TextRightDistance" ); + float fMargin = static_cast<float>(Millimeter::getInPoints( nMargin )); + return fMargin; +} + +void SAL_CALL +VbaTextFrame::setMarginRight( float _marginright ) +{ + setMargin( "TextRightDistance" , _marginright ); +} + + +// Methods +uno::Any SAL_CALL +VbaTextFrame::Characters() +{ + throw uno::RuntimeException( "Not implemented" ); +} + +OUString +VbaTextFrame::getServiceImplName() +{ + return "VbaTextFrame"; +} + +uno::Sequence< OUString > +VbaTextFrame::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.msforms.TextFrame" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vbahelper/source/vbahelper/vbawindowbase.cxx b/vbahelper/source/vbahelper/vbawindowbase.cxx new file mode 100644 index 000000000..a2735e31f --- /dev/null +++ b/vbahelper/source/vbahelper/vbawindowbase.cxx @@ -0,0 +1,171 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <vbahelper/vbawindowbase.hxx> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/awt/XWindow2.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XModel.hpp> + +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +VbaWindowBase::VbaWindowBase( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const uno::Reference< frame::XController >& xController ) : + WindowBaseImpl_BASE( xParent, xContext ), + m_xModel( xModel, uno::UNO_SET_THROW ) +{ + construct( xController ); +} + +VbaWindowBase::VbaWindowBase( uno::Sequence< uno::Any > const & args, + uno::Reference< uno::XComponentContext > const & xContext ) : + WindowBaseImpl_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0, false ), xContext ), + m_xModel( getXSomethingFromArgs< frame::XModel >( args, 1, false ) ) +{ + construct( getXSomethingFromArgs< frame::XController >( args, 2 ) ); +} + +sal_Bool SAL_CALL +VbaWindowBase::getVisible() +{ + return getWindow2()->isVisible(); +} + +void SAL_CALL +VbaWindowBase::setVisible( sal_Bool _visible ) +{ + getWindow2()->setVisible( _visible ); +} + +static void setPosSize( const uno::Reference< awt::XWindow >& xWindow, sal_Int32 nValue, sal_Int16 nFlag ) +{ + css::awt::Rectangle aRect = xWindow->getPosSize(); + switch( nFlag ) + { + case css::awt::PosSize::X: + xWindow->setPosSize( nValue, aRect.Y, 0, 0, css::awt::PosSize::X ); + break; + case css::awt::PosSize::Y: + xWindow->setPosSize( aRect.X, nValue, 0, 0, css::awt::PosSize::Y ); + break; + case css::awt::PosSize::WIDTH: + xWindow->setPosSize( 0, 0, nValue, aRect.Height, css::awt::PosSize::WIDTH ); + break; + case css::awt::PosSize::HEIGHT: + xWindow->setPosSize( 0, 0, aRect.Width, nValue, css::awt::PosSize::HEIGHT ); + break; + default: + break; + } +} + +sal_Int32 SAL_CALL +VbaWindowBase::getHeight() +{ + return getWindow()->getPosSize().Height; +} + +void SAL_CALL +VbaWindowBase::setHeight( sal_Int32 _height ) +{ + setPosSize( getWindow(), _height, css::awt::PosSize::HEIGHT ); +} + +sal_Int32 SAL_CALL +VbaWindowBase::getLeft() +{ + return getWindow()->getPosSize().X; +} + +void SAL_CALL +VbaWindowBase::setLeft( sal_Int32 _left ) +{ + setPosSize( getWindow(), _left, css::awt::PosSize::X ); +} + +sal_Int32 SAL_CALL +VbaWindowBase::getTop() +{ + return getWindow()->getPosSize().Y; +} + +void SAL_CALL +VbaWindowBase::setTop( sal_Int32 _top ) +{ + setPosSize( getWindow(), _top, css::awt::PosSize::Y ); +} + +sal_Int32 SAL_CALL +VbaWindowBase::getWidth() +{ + return getWindow()->getPosSize().Width; +} + +void SAL_CALL +VbaWindowBase::setWidth( sal_Int32 _width ) +{ + setPosSize( getWindow(), _width, css::awt::PosSize::WIDTH ); +} + +OUString +VbaWindowBase::getServiceImplName() +{ + return "VbaWindowBase"; +} + +uno::Sequence< OUString > +VbaWindowBase::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.VbaWindowBase" + }; + return aServiceNames; +} + +uno::Reference< frame::XController > VbaWindowBase::getController() const +{ + return uno::Reference< frame::XController >( m_xController, uno::UNO_SET_THROW ); +} + +uno::Reference< awt::XWindow > VbaWindowBase::getWindow() const +{ + return uno::Reference< awt::XWindow >( m_xWindow, uno::UNO_SET_THROW ); +} + +uno::Reference< awt::XWindow2 > VbaWindowBase::getWindow2() const +{ + return uno::Reference< awt::XWindow2 >( getWindow(), uno::UNO_QUERY_THROW ); +} + +void VbaWindowBase::construct( const uno::Reference< frame::XController >& xController ) +{ + if( !xController.is() ) throw uno::RuntimeException(); + uno::Reference< frame::XFrame > xFrame( xController->getFrame(), uno::UNO_SET_THROW ); + uno::Reference< awt::XWindow > xWindow( xFrame->getContainerWindow(), uno::UNO_SET_THROW ); + m_xController = xController; + m_xWindow = xWindow; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |