tdf#151548 vba FormFields: Add basic word::XDropDown support
make CppunitTest_sw_macros_test CPPUNIT_TEST_NAME=testVba This now allows MS Word Basic legacy list box form fields to be controlled by VBA basic. -allows getting and setting the text string/list entry -allows adding and deleting list entries Change-Id: Ia772c62395c40a6aa0afae2549f15f4ea3304dbf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142396 Reviewed-by: Justin Luth <jluth@mail.com> Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
This commit is contained in:
committed by
Miklos Vajna
parent
55c2e9e7e2
commit
b8fa94b28a
@@ -1052,6 +1052,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,oovbaapi,ooo/vba/word,\
|
||||
XDocument \
|
||||
XDocumentOutgoing \
|
||||
XDocuments \
|
||||
XDropDown \
|
||||
XField \
|
||||
XFields \
|
||||
XFind \
|
||||
@@ -1063,6 +1064,8 @@ $(eval $(call gb_UnoApi_add_idlfiles,oovbaapi,ooo/vba/word,\
|
||||
XGlobals \
|
||||
XHeaderFooter \
|
||||
XHeadersFooters \
|
||||
XListEntries \
|
||||
XListEntry \
|
||||
XListFormat \
|
||||
XListGalleries \
|
||||
XListGallery \
|
||||
|
31
oovbaapi/ooo/vba/word/XDropDown.idl
Normal file
31
oovbaapi/ooo/vba/word/XDropDown.idl
Normal file
@@ -0,0 +1,31 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
module ooo { module vba { module word {
|
||||
|
||||
interface XDropDown
|
||||
{
|
||||
interface ooo::vba::XHelperInterface;
|
||||
interface com::sun::star::script::XDefaultProperty;
|
||||
|
||||
/// Default member: True if the specified form field object is a valid drop down form field.
|
||||
[attribute, readonly] boolean Valid;
|
||||
|
||||
/// Returns or sets a number that represents the default drop-down index.
|
||||
[attribute] long Default;
|
||||
/// Returns or sets the index of the selected item in a drop-down form field.
|
||||
[attribute] long Value;
|
||||
|
||||
/// Returns a ListEntries collection that represents all the items in a DropDown object.
|
||||
any ListEntries( [in] any Index );
|
||||
};
|
||||
|
||||
}; }; };
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
25
oovbaapi/ooo/vba/word/XListEntries.idl
Normal file
25
oovbaapi/ooo/vba/word/XListEntries.idl
Normal file
@@ -0,0 +1,25 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
module ooo { module vba { module word {
|
||||
|
||||
interface XListEntry;
|
||||
interface XListEntries
|
||||
{
|
||||
interface ooo::vba::XCollection;
|
||||
|
||||
/// Returns a ListEntry object that represents an item added to a drop-down form field.
|
||||
XListEntry Add( [in] string Name, [in] /*optional long*/ any Index ) raises ( com::sun::star::script::BasicErrorException );
|
||||
/// Removes all items from the drop-down form field.
|
||||
void Clear();
|
||||
};
|
||||
|
||||
}; }; };
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
27
oovbaapi/ooo/vba/word/XListEntry.idl
Normal file
27
oovbaapi/ooo/vba/word/XListEntry.idl
Normal file
@@ -0,0 +1,27 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
module ooo { module vba { module word {
|
||||
|
||||
interface XListEntry
|
||||
{
|
||||
interface ooo::vba::XHelperInterface;
|
||||
|
||||
/// Returns the position of an item in a collection.
|
||||
[attribute, readonly] long Index;
|
||||
/// Returns or sets the name of the specified object.
|
||||
[attribute] string Name;
|
||||
|
||||
/// Deletes the list entry.
|
||||
void Delete();
|
||||
};
|
||||
|
||||
}; }; };
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
@@ -75,6 +75,9 @@ $(eval $(call gb_Library_add_exception_objects,vbaswobj,\
|
||||
sw/source/ui/vba/vbaformfield \
|
||||
sw/source/ui/vba/vbaformfields \
|
||||
sw/source/ui/vba/vbaformfieldcheckbox \
|
||||
sw/source/ui/vba/vbaformfielddropdown \
|
||||
sw/source/ui/vba/vbaformfielddropdownlistentries \
|
||||
sw/source/ui/vba/vbaformfielddropdownlistentry \
|
||||
sw/source/ui/vba/vbaformfieldtextinput \
|
||||
sw/source/ui/vba/vbaframe \
|
||||
sw/source/ui/vba/vbaframes \
|
||||
|
@@ -125,6 +125,25 @@ namespace sw::mark
|
||||
ICheckboxFieldmark &operator =(ICheckboxFieldmark const&) = delete;
|
||||
};
|
||||
|
||||
class SW_DLLPUBLIC IDropdownFieldmark
|
||||
: virtual public IFieldmark
|
||||
{
|
||||
protected:
|
||||
IDropdownFieldmark() = default;
|
||||
|
||||
public:
|
||||
virtual OUString GetContent(sal_Int32* pIndex) const = 0;
|
||||
virtual OUString GetContent() const override = 0;
|
||||
virtual void AddContent(const OUString& rText, sal_Int32* pIndex = nullptr) = 0;
|
||||
virtual void DelContent(sal_Int32 nDelIndex = -1) = 0;
|
||||
virtual void ReplaceContent(const OUString* pText, sal_Int32* pIndex) = 0;
|
||||
virtual void ReplaceContent(const OUString& sNewContent) override = 0;
|
||||
|
||||
private:
|
||||
IDropdownFieldmark(IDropdownFieldmark const &) = delete;
|
||||
IDropdownFieldmark &operator =(IDropdownFieldmark const&) = delete;
|
||||
};
|
||||
|
||||
class SW_DLLPUBLIC IDateFieldmark
|
||||
: virtual public IFieldmark
|
||||
{
|
||||
|
Binary file not shown.
@@ -34,6 +34,7 @@
|
||||
#include <xmloff/odffields.hxx>
|
||||
#include <libxml/xmlwriter.h>
|
||||
#include <comphelper/random.hxx>
|
||||
#include <comphelper/sequence.hxx>
|
||||
#include <comphelper/anytostring.hxx>
|
||||
#include <sal/log.hxx>
|
||||
#include <svl/numformat.hxx>
|
||||
@@ -749,6 +750,182 @@ namespace sw::mark
|
||||
FieldmarkWithDropDownButton::RemoveButton();
|
||||
}
|
||||
|
||||
/** GetContent
|
||||
* @param pIndex The zero-based index to retrieve
|
||||
* [in] if pIndex is null or negative, return the listbox's chosen result,
|
||||
* else return the indicated entry (or last entry for invalid choice).
|
||||
* [out] the index of the returned result or -1 if error
|
||||
*/
|
||||
OUString DropDownFieldmark::GetContent(sal_Int32* pIndex) const
|
||||
{
|
||||
sal_Int32 nIndex = pIndex ? *pIndex : -1;
|
||||
auto rParameters = *GetParameters();
|
||||
if (nIndex < 0)
|
||||
rParameters[ODF_FORMDROPDOWN_RESULT] >>= nIndex;
|
||||
|
||||
uno::Sequence<OUString> aSeq;
|
||||
rParameters[ODF_FORMDROPDOWN_LISTENTRY] >>= aSeq;
|
||||
nIndex = std::min(nIndex, aSeq.getLength() - 1);
|
||||
|
||||
if (nIndex < 0)
|
||||
{
|
||||
if (pIndex)
|
||||
*pIndex = -1;
|
||||
return OUString();
|
||||
}
|
||||
|
||||
if (pIndex)
|
||||
*pIndex = nIndex;
|
||||
|
||||
return aSeq[nIndex];
|
||||
}
|
||||
|
||||
OUString DropDownFieldmark::GetContent() const
|
||||
{
|
||||
return GetContent(nullptr);
|
||||
}
|
||||
|
||||
/** AddContent : INSERTS a new choice
|
||||
* @param rText: The choice to add to the list choices.
|
||||
*
|
||||
* @param pIndex [optional]
|
||||
* [in] If pIndex is null or invalid, append to the end of the list.
|
||||
* [out] Modified to point to the position of the choice if it already exists.
|
||||
*/
|
||||
void DropDownFieldmark::AddContent(const OUString& rText, sal_Int32* pIndex)
|
||||
{
|
||||
uno::Sequence<OUString> aSeq;
|
||||
sw::mark::IFieldmark::parameter_map_t* pParameters = GetParameters();
|
||||
(*pParameters)[ODF_FORMDROPDOWN_LISTENTRY] >>= aSeq;
|
||||
|
||||
// no duplicates: if it already exists, modify the given index to point to it
|
||||
const sal_Int32 nCurrentTextPos = comphelper::findValue(aSeq, rText);
|
||||
if (nCurrentTextPos != -1)
|
||||
{
|
||||
if (pIndex)
|
||||
*pIndex = nCurrentTextPos;
|
||||
return;
|
||||
}
|
||||
|
||||
const sal_Int32 nLen = aSeq.getLength();
|
||||
const sal_Int32 nNewPos = pIndex && *pIndex > -1 ? std::min(*pIndex, nLen) : nLen;
|
||||
|
||||
// need to shift list result index up if adding new entry before it
|
||||
sal_Int32 nResultIndex = -1;
|
||||
(*pParameters)[ODF_FORMDROPDOWN_RESULT] >>= nResultIndex;
|
||||
if (nNewPos <= nResultIndex)
|
||||
(*pParameters)[ODF_FORMDROPDOWN_RESULT] <<= nResultIndex + 1;
|
||||
|
||||
auto aList = comphelper::sequenceToContainer<std::vector<OUString>>(aSeq);
|
||||
if (nNewPos < nLen)
|
||||
aList.insert(aList.begin() + nNewPos, rText);
|
||||
else
|
||||
{
|
||||
*pIndex = nLen;
|
||||
aList.push_back(rText);
|
||||
}
|
||||
|
||||
(*pParameters)[ODF_FORMDROPDOWN_LISTENTRY] <<= comphelper::containerToSequence(aList);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* ReplaceContent : changes the list result index or renames the existing choices
|
||||
* @param pText
|
||||
* [in] If pIndex is null, change the list result index to this provided choice
|
||||
* (but do nothing if pText is an invalid choice)
|
||||
* else rename that entry.
|
||||
*
|
||||
* @param pIndex
|
||||
* [in] If pText is null, change the list result index to this provided Index
|
||||
* (or the last position if it is an invalid choice)
|
||||
* else rename this entry (doing nothing for invalid indexes).
|
||||
* [out] If pIndex is invalid, it is modified to use the last position.
|
||||
*
|
||||
* This function allows duplicate entries - which is also allowed in MS Word.
|
||||
*/
|
||||
void DropDownFieldmark::ReplaceContent(const OUString* pText, sal_Int32* pIndex)
|
||||
{
|
||||
if (!pIndex && !pText)
|
||||
return;
|
||||
|
||||
uno::Sequence<OUString> aSeq;
|
||||
sw::mark::IFieldmark::parameter_map_t* pParameters = GetParameters();
|
||||
(*pParameters)[ODF_FORMDROPDOWN_LISTENTRY] >>= aSeq;
|
||||
const sal_Int32 nLen = aSeq.getLength();
|
||||
|
||||
if (!pText)
|
||||
{
|
||||
if (*pIndex < 0 || *pIndex >= nLen)
|
||||
*pIndex = nLen - 1;
|
||||
|
||||
// select pIndex as the new value for the list box
|
||||
(*pParameters)[ODF_FORMDROPDOWN_RESULT] <<= *pIndex;
|
||||
Invalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pIndex)
|
||||
{
|
||||
const sal_Int32 nNewPos = comphelper::findValue(aSeq, *pText);
|
||||
if (nNewPos != -1)
|
||||
{
|
||||
(*pParameters)[ODF_FORMDROPDOWN_RESULT] <<= nNewPos;
|
||||
Invalidate();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (*pIndex > -1 && *pIndex < nLen)
|
||||
{
|
||||
auto aList = comphelper::sequenceToContainer<std::vector<OUString>>(aSeq);
|
||||
aList[*pIndex] = *pText;
|
||||
(*pParameters)[ODF_FORMDROPDOWN_LISTENTRY] <<= comphelper::containerToSequence(aList);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void DropDownFieldmark::ReplaceContent(const OUString& rNewContent)
|
||||
{
|
||||
ReplaceContent(&rNewContent, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove everything if the given index is negative, else remove the given index (if valid).
|
||||
* If deleting the currently selected choice, reset the selection to the first choice.
|
||||
*/
|
||||
void DropDownFieldmark::DelContent(sal_Int32 nDelIndex)
|
||||
{
|
||||
sw::mark::IFieldmark::parameter_map_t* pParameters = GetParameters();
|
||||
uno::Sequence<OUString> aSeq;
|
||||
if (nDelIndex < 0)
|
||||
{
|
||||
pParameters->erase(ODF_FORMDROPDOWN_RESULT);
|
||||
(*pParameters)[ODF_FORMDROPDOWN_LISTENTRY] <<= aSeq;
|
||||
Invalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
(*pParameters)[ODF_FORMDROPDOWN_LISTENTRY] >>= aSeq;
|
||||
if (nDelIndex >= aSeq.getLength())
|
||||
return;
|
||||
|
||||
// If deleting the current choice, select the first entry instead
|
||||
// else need to shift list result index down if deleting an entry before it
|
||||
sal_Int32 nResultIndex = -1;
|
||||
(*pParameters)[ODF_FORMDROPDOWN_RESULT] >>= nResultIndex;
|
||||
if (nDelIndex == nResultIndex)
|
||||
nResultIndex = 0;
|
||||
else if (nDelIndex < nResultIndex)
|
||||
--nResultIndex;
|
||||
|
||||
comphelper::removeElementAt(aSeq, nDelIndex);
|
||||
if (nResultIndex != -1)
|
||||
(*pParameters)[ODF_FORMDROPDOWN_RESULT] <<= nResultIndex;
|
||||
(*pParameters)[ODF_FORMDROPDOWN_LISTENTRY] <<= aSeq;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void DropDownFieldmark::SetPortionPaintArea(const SwRect& rPortionPaintArea)
|
||||
{
|
||||
m_aPortionPaintArea = rPortionPaintArea;
|
||||
|
@@ -290,7 +290,8 @@ namespace sw::mark {
|
||||
|
||||
/// Fieldmark representing a drop-down form field.
|
||||
class DropDownFieldmark final
|
||||
: public FieldmarkWithDropDownButton
|
||||
: virtual public IDropdownFieldmark
|
||||
, public FieldmarkWithDropDownButton
|
||||
{
|
||||
public:
|
||||
DropDownFieldmark(const SwPaM& rPaM, const OUString& rName);
|
||||
@@ -298,6 +299,12 @@ namespace sw::mark {
|
||||
|
||||
virtual void ShowButton(SwEditWin* pEditWin) override;
|
||||
virtual void RemoveButton() override;
|
||||
OUString GetContent(sal_Int32* pIndex) const override;
|
||||
OUString GetContent() const override;
|
||||
void AddContent(const OUString& rText, sal_Int32* pIndex = nullptr) override;
|
||||
void DelContent(sal_Int32 nDelIndex = -1) override;
|
||||
void ReplaceContent(const OUString* pText, sal_Int32* pIndex) override;
|
||||
void ReplaceContent(const OUString& sNewContent) override;
|
||||
|
||||
// This method should be called only by the portion so we can now the portion's painting area
|
||||
void SetPortionPaintArea(const SwRect& rPortionPaintArea);
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "vbaformfield.hxx"
|
||||
#include "vbaformfieldcheckbox.hxx"
|
||||
#include "vbaformfielddropdown.hxx"
|
||||
#include "vbaformfieldtextinput.hxx"
|
||||
#include "wordvbahelper.hxx"
|
||||
|
||||
@@ -61,9 +62,8 @@ uno::Any SAL_CALL SwVbaFormField::CheckBox()
|
||||
|
||||
uno::Any SAL_CALL SwVbaFormField::DropDown()
|
||||
{
|
||||
// return uno::Any(uno::Reference<word::XDropDown>(
|
||||
// new SwVbaFormFieldDropDown(mxParent, mxContext, m_rFormField)));
|
||||
return uno::Any();
|
||||
return uno::Any(uno::Reference<word::XDropDown>(
|
||||
new SwVbaFormFieldDropDown(mxParent, mxContext, m_rFormField)));
|
||||
}
|
||||
|
||||
uno::Any SAL_CALL SwVbaFormField::TextInput()
|
||||
|
101
sw/source/ui/vba/vbaformfielddropdown.cxx
Normal file
101
sw/source/ui/vba/vbaformfielddropdown.cxx
Normal file
@@ -0,0 +1,101 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <ooo/vba/word/WdTextFormFieldType.hpp>
|
||||
|
||||
#include "vbaformfielddropdown.hxx"
|
||||
#include "vbaformfielddropdownlistentries.hxx"
|
||||
|
||||
using namespace ::ooo::vba;
|
||||
using namespace ::com::sun::star;
|
||||
|
||||
/**
|
||||
* Official documentation found at https://learn.microsoft.com/en-us/office/vba/api/word.dropdown
|
||||
*
|
||||
* DropDown formfields are inline text objects that are only found in MS Word.
|
||||
* They cannot be created in Excel or in Calc.
|
||||
*
|
||||
* Note that VBA might call this a DropDown, but it might not actually be one,
|
||||
* so make good use of getValid()
|
||||
*/
|
||||
SwVbaFormFieldDropDown::SwVbaFormFieldDropDown(
|
||||
const uno::Reference<ooo::vba::XHelperInterface>& rParent,
|
||||
const uno::Reference<uno::XComponentContext>& rContext, ::sw::mark::IFieldmark& rFormField)
|
||||
: SwVbaFormFieldDropDown_BASE(rParent, rContext)
|
||||
, m_pDropDown(dynamic_cast<sw::mark::IDropdownFieldmark*>(&rFormField))
|
||||
{
|
||||
}
|
||||
|
||||
SwVbaFormFieldDropDown::~SwVbaFormFieldDropDown() {}
|
||||
|
||||
OUString SwVbaFormFieldDropDown::getDefaultPropertyName() { return "Valid"; }
|
||||
|
||||
sal_Bool SwVbaFormFieldDropDown::getValid()
|
||||
{
|
||||
return m_pDropDown
|
||||
&& IDocumentMarkAccess::GetType(*m_pDropDown)
|
||||
== IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK;
|
||||
}
|
||||
|
||||
sal_Int32 SwVbaFormFieldDropDown::getDefault() { return getValue(); }
|
||||
|
||||
void SwVbaFormFieldDropDown::setDefault(sal_Int32 nSet)
|
||||
{
|
||||
// Hard to know what to do here, since LO doesn't have a default property for DropDowns.
|
||||
// Setting this really only makes sense when macro-adding a DropDown.
|
||||
// In that case, we want it to affect the actual text content.
|
||||
// However, if an item has already been selected by the user, then this shouldn't do anything.
|
||||
// Assuming this is only ever set when adding a DropDown seems the sanest approach.
|
||||
setValue(nSet);
|
||||
}
|
||||
|
||||
sal_Int32 SwVbaFormFieldDropDown::getValue()
|
||||
{
|
||||
sal_Int32 nRet = 0;
|
||||
if (!getValid())
|
||||
return nRet;
|
||||
|
||||
--nRet; // send -1, which requests being changed to the selected DropDown's zero-based index
|
||||
m_pDropDown->GetContent(&nRet);
|
||||
return nRet + 1;
|
||||
}
|
||||
|
||||
void SwVbaFormFieldDropDown::setValue(sal_Int32 nIndex)
|
||||
{
|
||||
if (!getValid() || nIndex == getValue())
|
||||
return;
|
||||
|
||||
// switch to zero-based index for implementation
|
||||
--nIndex;
|
||||
m_pDropDown->ReplaceContent(/*pText=*/nullptr, &nIndex);
|
||||
}
|
||||
|
||||
uno::Any SwVbaFormFieldDropDown::ListEntries(const uno::Any& rIndex)
|
||||
{
|
||||
if (!getValid())
|
||||
return uno::Any();
|
||||
|
||||
uno::Reference<XCollection> xCol(
|
||||
new SwVbaFormFieldDropDownListEntries(this, mxContext, *m_pDropDown));
|
||||
|
||||
if (rIndex.hasValue())
|
||||
return xCol->Item(rIndex, uno::Any());
|
||||
|
||||
return uno::Any(xCol);
|
||||
}
|
||||
|
||||
OUString SwVbaFormFieldDropDown::getServiceImplName() { return "SwVbaFormFieldDropDown"; }
|
||||
|
||||
uno::Sequence<OUString> SwVbaFormFieldDropDown::getServiceNames()
|
||||
{
|
||||
static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.DropDown" };
|
||||
return aServiceNames;
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
52
sw/source/ui/vba/vbaformfielddropdown.hxx
Normal file
52
sw/source/ui/vba/vbaformfielddropdown.hxx
Normal file
@@ -0,0 +1,52 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ooo/vba/word/XDropDown.hpp>
|
||||
|
||||
#include <vbahelper/vbahelperinterface.hxx>
|
||||
|
||||
#include <IDocumentMarkAccess.hxx>
|
||||
|
||||
typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XDropDown> SwVbaFormFieldDropDown_BASE;
|
||||
|
||||
class SwVbaFormFieldDropDown : public SwVbaFormFieldDropDown_BASE
|
||||
{
|
||||
private:
|
||||
sw::mark::IDropdownFieldmark* m_pDropDown;
|
||||
|
||||
public:
|
||||
/// @throws css::uno::RuntimeException
|
||||
SwVbaFormFieldDropDown(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
|
||||
const css::uno::Reference<css::uno::XComponentContext>& rContext,
|
||||
sw::mark::IFieldmark& rFormField);
|
||||
~SwVbaFormFieldDropDown() override;
|
||||
|
||||
// XDropDown
|
||||
OUString SAL_CALL getDefaultPropertyName() override;
|
||||
|
||||
// Default member: True if the specified form field object is a valid listbox field
|
||||
sal_Bool SAL_CALL getValid() override;
|
||||
|
||||
// Returns and sets the index for the default listbox entry
|
||||
sal_Int32 SAL_CALL getDefault() override;
|
||||
void SAL_CALL setDefault(sal_Int32 nSet) override;
|
||||
// Returns and sets the index of the selected listbox entry
|
||||
sal_Int32 SAL_CALL getValue() override;
|
||||
void SAL_CALL setValue(sal_Int32 nIndex) override;
|
||||
|
||||
// Returns a ListEntries collection that represents all the available entries
|
||||
css::uno::Any SAL_CALL ListEntries(const css::uno::Any& rIndex) override;
|
||||
|
||||
// XHelperInterface
|
||||
OUString getServiceImplName() override;
|
||||
css::uno::Sequence<OUString> getServiceNames() override;
|
||||
};
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
171
sw/source/ui/vba/vbaformfielddropdownlistentries.cxx
Normal file
171
sw/source/ui/vba/vbaformfielddropdownlistentries.cxx
Normal file
@@ -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/.
|
||||
*/
|
||||
|
||||
#include <xmloff/odffields.hxx>
|
||||
|
||||
#include "vbaformfielddropdownlistentries.hxx"
|
||||
|
||||
using namespace ::ooo::vba;
|
||||
using namespace ::com::sun::star;
|
||||
|
||||
static uno::Sequence<OUString> lcl_getListEntries(sw::mark::IDropdownFieldmark& rDropDown)
|
||||
{
|
||||
uno::Sequence<OUString> aSeq;
|
||||
(*rDropDown.GetParameters())[ODF_FORMDROPDOWN_LISTENTRY] >>= aSeq;
|
||||
return aSeq;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class ListEntriesEnumWrapper : public EnumerationHelper_BASE
|
||||
{
|
||||
uno::Reference<container::XIndexAccess> mxIndexAccess;
|
||||
sal_Int32 nIndex;
|
||||
|
||||
public:
|
||||
explicit ListEntriesEnumWrapper(uno::Reference<container::XIndexAccess> xIndexAccess)
|
||||
: mxIndexAccess(xIndexAccess)
|
||||
, nIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual sal_Bool SAL_CALL hasMoreElements() override
|
||||
{
|
||||
return (nIndex < mxIndexAccess->getCount());
|
||||
}
|
||||
|
||||
virtual uno::Any SAL_CALL nextElement() override
|
||||
{
|
||||
if (nIndex < mxIndexAccess->getCount())
|
||||
{
|
||||
return mxIndexAccess->getByIndex(nIndex++);
|
||||
}
|
||||
throw container::NoSuchElementException();
|
||||
}
|
||||
};
|
||||
|
||||
class ListEntryCollectionHelper
|
||||
: public ::cppu::WeakImplHelper<container::XIndexAccess, container::XEnumerationAccess>
|
||||
{
|
||||
private:
|
||||
uno::Reference<XHelperInterface> mxParent;
|
||||
uno::Reference<uno::XComponentContext> mxContext;
|
||||
sw::mark::IDropdownFieldmark& m_rDropDown;
|
||||
|
||||
public:
|
||||
/// @throws css::uno::RuntimeException
|
||||
ListEntryCollectionHelper(uno::Reference<ov::XHelperInterface> xParent,
|
||||
uno::Reference<uno::XComponentContext> xContext,
|
||||
sw::mark::IDropdownFieldmark& rFormField)
|
||||
: mxParent(xParent)
|
||||
, mxContext(xContext)
|
||||
, m_rDropDown(rFormField)
|
||||
{
|
||||
}
|
||||
|
||||
virtual sal_Int32 SAL_CALL getCount() override
|
||||
{
|
||||
return lcl_getListEntries(m_rDropDown).getLength();
|
||||
}
|
||||
|
||||
virtual uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
|
||||
{
|
||||
if (Index < 0 || Index >= getCount())
|
||||
throw lang::IndexOutOfBoundsException();
|
||||
|
||||
return uno::Any(uno::Reference<word::XListEntry>(
|
||||
new SwVbaFormFieldDropDownListEntry(mxParent, mxContext, m_rDropDown, Index)));
|
||||
}
|
||||
|
||||
virtual uno::Type SAL_CALL getElementType() override
|
||||
{
|
||||
return cppu::UnoType<word::XListEntry>::get();
|
||||
}
|
||||
|
||||
virtual sal_Bool SAL_CALL hasElements() override { return getCount() != 0; }
|
||||
|
||||
// XEnumerationAccess
|
||||
virtual uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override
|
||||
{
|
||||
return new ListEntriesEnumWrapper(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
SwVbaFormFieldDropDownListEntries::SwVbaFormFieldDropDownListEntries(
|
||||
const uno::Reference<XHelperInterface>& xParent,
|
||||
const uno::Reference<uno::XComponentContext>& xContext,
|
||||
sw::mark::IDropdownFieldmark& rFormField)
|
||||
: SwVbaFormFieldDropDownListEntries_BASE(
|
||||
xParent, xContext,
|
||||
uno::Reference<container::XIndexAccess>(
|
||||
new ListEntryCollectionHelper(xParent, xContext, rFormField)))
|
||||
, m_rDropDown(rFormField)
|
||||
{
|
||||
}
|
||||
|
||||
// XListEntries
|
||||
uno::Reference<word::XListEntry>
|
||||
SAL_CALL SwVbaFormFieldDropDownListEntries::Add(const OUString& rName, const uno::Any& rIndex)
|
||||
{
|
||||
sal_Int32 nZIndex = 0;
|
||||
rIndex >>= nZIndex;
|
||||
// rIndex is 1-based, nZIndex is 0-based. If rIndex is not given, then add as the last choice.
|
||||
|
||||
// In testing with Word 2010, this gives a compile error: 'ListEntries.Add("Name", 2)'
|
||||
// This compiles, but gets an unsupported runtime error: 'ListEntries.Add("Name", 2) = "Choice'
|
||||
// So the only thing that actually works is to simply append: 'ListEntires.Add("Name")'
|
||||
// but I'll still keep the expected implementation for the broken case.
|
||||
if (!nZIndex)
|
||||
nZIndex = SAL_MAX_INT32;
|
||||
else
|
||||
--nZIndex;
|
||||
m_rDropDown.AddContent(rName + "__allowDuplicates", &nZIndex);
|
||||
m_rDropDown.ReplaceContent(&rName, &nZIndex);
|
||||
|
||||
return uno::Reference<word::XListEntry>(
|
||||
new SwVbaFormFieldDropDownListEntry(mxParent, mxContext, m_rDropDown, nZIndex));
|
||||
}
|
||||
|
||||
void SAL_CALL SwVbaFormFieldDropDownListEntries::Clear() { m_rDropDown.DelContent(); }
|
||||
|
||||
sal_Int32 SwVbaFormFieldDropDownListEntries::getCount()
|
||||
{
|
||||
return lcl_getListEntries(m_rDropDown).getLength();
|
||||
}
|
||||
|
||||
// XEnumerationAccess
|
||||
uno::Type SwVbaFormFieldDropDownListEntries::getElementType()
|
||||
{
|
||||
return cppu::UnoType<word::XListEntry>::get();
|
||||
}
|
||||
|
||||
uno::Reference<container::XEnumeration> SwVbaFormFieldDropDownListEntries::createEnumeration()
|
||||
{
|
||||
return new ListEntriesEnumWrapper(m_xIndexAccess);
|
||||
}
|
||||
|
||||
// SwVbadropDownListEntries_BASE
|
||||
uno::Any SwVbaFormFieldDropDownListEntries::createCollectionObject(const uno::Any& aSource)
|
||||
{
|
||||
return aSource;
|
||||
}
|
||||
|
||||
OUString SwVbaFormFieldDropDownListEntries::getServiceImplName()
|
||||
{
|
||||
return "SwVbaFormFieldDropDownListEntries";
|
||||
}
|
||||
|
||||
uno::Sequence<OUString> SwVbaFormFieldDropDownListEntries::getServiceNames()
|
||||
{
|
||||
static uno::Sequence<OUString> const sNames{ "ooo.vba.word.ListEntries" };
|
||||
return sNames;
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
49
sw/source/ui/vba/vbaformfielddropdownlistentries.hxx
Normal file
49
sw/source/ui/vba/vbaformfielddropdownlistentries.hxx
Normal file
@@ -0,0 +1,49 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ooo/vba/word/XListEntries.hpp>
|
||||
#include <ooo/vba/word/XListEntry.hpp>
|
||||
|
||||
#include <vbahelper/vbacollectionimpl.hxx>
|
||||
|
||||
#include "vbaformfielddropdownlistentries.hxx"
|
||||
#include "vbaformfielddropdownlistentry.hxx"
|
||||
|
||||
typedef CollTestImplHelper<ooo::vba::word::XListEntries> SwVbaFormFieldDropDownListEntries_BASE;
|
||||
|
||||
class SwVbaFormFieldDropDownListEntries : public SwVbaFormFieldDropDownListEntries_BASE
|
||||
{
|
||||
private:
|
||||
sw::mark::IDropdownFieldmark& m_rDropDown;
|
||||
|
||||
public:
|
||||
/// @throws css::uno::RuntimeException
|
||||
SwVbaFormFieldDropDownListEntries(
|
||||
const css::uno::Reference<ov::XHelperInterface>& xParent,
|
||||
const css::uno::Reference<css::uno::XComponentContext>& xContext,
|
||||
sw::mark::IDropdownFieldmark& m_rDropDown);
|
||||
|
||||
// XListEntries
|
||||
css::uno::Reference<ooo::vba::word::XListEntry>
|
||||
SAL_CALL Add(const OUString& rName, const css::uno::Any& rIndex) override;
|
||||
void SAL_CALL Clear() override;
|
||||
sal_Int32 SAL_CALL getCount() override;
|
||||
|
||||
// XEnumerationAccess
|
||||
css::uno::Type SAL_CALL getElementType() override;
|
||||
css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override;
|
||||
|
||||
// SwVbaFormFieldDropDownListEntries_BASE
|
||||
css::uno::Any createCollectionObject(const css::uno::Any& aSource) override;
|
||||
OUString getServiceImplName() override;
|
||||
css::uno::Sequence<OUString> getServiceNames() override;
|
||||
};
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
56
sw/source/ui/vba/vbaformfielddropdownlistentry.cxx
Normal file
56
sw/source/ui/vba/vbaformfielddropdownlistentry.cxx
Normal file
@@ -0,0 +1,56 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "vbaformfielddropdownlistentry.hxx"
|
||||
|
||||
using namespace ::ooo::vba;
|
||||
using namespace ::com::sun::star;
|
||||
|
||||
SwVbaFormFieldDropDownListEntry::SwVbaFormFieldDropDownListEntry(
|
||||
const uno::Reference<ooo::vba::XHelperInterface>& rParent,
|
||||
const uno::Reference<uno::XComponentContext>& rContext,
|
||||
sw::mark::IDropdownFieldmark& rFormField, sal_Int32 nZIndex)
|
||||
: SwVbaFormFieldDropDownListEntry_BASE(rParent, rContext)
|
||||
, m_rDropDown(rFormField)
|
||||
, m_nZIndex(nZIndex)
|
||||
{
|
||||
}
|
||||
|
||||
SwVbaFormFieldDropDownListEntry::~SwVbaFormFieldDropDownListEntry() {}
|
||||
|
||||
// XListEntry
|
||||
sal_Int32 SAL_CALL SwVbaFormFieldDropDownListEntry::getIndex() { return m_nZIndex + 1; }
|
||||
|
||||
OUString SAL_CALL SwVbaFormFieldDropDownListEntry::getName()
|
||||
{
|
||||
sal_Int32 nZIndex = m_nZIndex;
|
||||
return m_rDropDown.GetContent(&nZIndex);
|
||||
}
|
||||
|
||||
void SAL_CALL SwVbaFormFieldDropDownListEntry::setName(const OUString& rSet)
|
||||
{
|
||||
sal_Int32 nZIndex = m_nZIndex;
|
||||
m_rDropDown.ReplaceContent(&rSet, &nZIndex);
|
||||
}
|
||||
|
||||
void SwVbaFormFieldDropDownListEntry::Delete() { m_rDropDown.DelContent(m_nZIndex); }
|
||||
|
||||
// XHelperInterface
|
||||
OUString SwVbaFormFieldDropDownListEntry::getServiceImplName()
|
||||
{
|
||||
return "SwVbaFormFieldDropDownListEntry";
|
||||
}
|
||||
|
||||
uno::Sequence<OUString> SwVbaFormFieldDropDownListEntry::getServiceNames()
|
||||
{
|
||||
static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.ListEntry" };
|
||||
return aServiceNames;
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
48
sw/source/ui/vba/vbaformfielddropdownlistentry.hxx
Normal file
48
sw/source/ui/vba/vbaformfielddropdownlistentry.hxx
Normal file
@@ -0,0 +1,48 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ooo/vba/word/XListEntry.hpp>
|
||||
|
||||
#include <vbahelper/vbahelperinterface.hxx>
|
||||
|
||||
#include <IDocumentMarkAccess.hxx>
|
||||
|
||||
typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XListEntry>
|
||||
SwVbaFormFieldDropDownListEntry_BASE;
|
||||
|
||||
class SwVbaFormFieldDropDownListEntry : public SwVbaFormFieldDropDownListEntry_BASE
|
||||
{
|
||||
private:
|
||||
sw::mark::IDropdownFieldmark& m_rDropDown;
|
||||
// All LO and internal functions are 0-based. Convert to 1-based when sending to VBA
|
||||
const sal_Int32 m_nZIndex;
|
||||
|
||||
public:
|
||||
/// @throws css::uno::RuntimeException
|
||||
SwVbaFormFieldDropDownListEntry(
|
||||
const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
|
||||
const css::uno::Reference<css::uno::XComponentContext>& rContext,
|
||||
sw::mark::IDropdownFieldmark& rFormField, sal_Int32 nZIndex);
|
||||
~SwVbaFormFieldDropDownListEntry() override;
|
||||
|
||||
// XListEntry
|
||||
sal_Int32 SAL_CALL getIndex() override;
|
||||
|
||||
OUString SAL_CALL getName() override;
|
||||
void SAL_CALL setName(const OUString& sSet) override;
|
||||
|
||||
void SAL_CALL Delete() override;
|
||||
|
||||
// XHelperInterface
|
||||
OUString getServiceImplName() override;
|
||||
css::uno::Sequence<OUString> getServiceNames() override;
|
||||
};
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
Reference in New Issue
Block a user