diff options
-rw-r--r-- | oovbaapi/UnoApi_oovbaapi.mk | 1 | ||||
-rw-r--r-- | oovbaapi/ooo/vba/word/XTextInput.idl | 38 | ||||
-rw-r--r-- | sw/Library_vbaswobj.mk | 1 | ||||
-rw-r--r-- | sw/qa/core/data/docm/testVBA.docm | bin | 30997 -> 30732 bytes | |||
-rw-r--r-- | sw/source/core/crsr/bookmark.cxx | 41 | ||||
-rw-r--r-- | sw/source/core/inc/bookmark.hxx | 6 | ||||
-rw-r--r-- | sw/source/ui/vba/vbaformfield.cxx | 6 | ||||
-rw-r--r-- | sw/source/ui/vba/vbaformfieldtextinput.cxx | 132 | ||||
-rw-r--r-- | sw/source/ui/vba/vbaformfieldtextinput.hxx | 68 |
9 files changed, 290 insertions, 3 deletions
diff --git a/oovbaapi/UnoApi_oovbaapi.mk b/oovbaapi/UnoApi_oovbaapi.mk index 400528dd75c6..6d83196dbcf6 100644 --- a/oovbaapi/UnoApi_oovbaapi.mk +++ b/oovbaapi/UnoApi_oovbaapi.mk @@ -1097,6 +1097,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,oovbaapi,ooo/vba/word,\ XTabStop \ XTabStops \ XTemplate \ + XTextInput \ XVariable \ XVariables \ XView \ diff --git a/oovbaapi/ooo/vba/word/XTextInput.idl b/oovbaapi/ooo/vba/word/XTextInput.idl new file mode 100644 index 000000000000..ec7b3465cdd7 --- /dev/null +++ b/oovbaapi/ooo/vba/word/XTextInput.idl @@ -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/. + */ + +module ooo { module vba { module word { + +interface XTextInput +{ + interface ooo::vba::XHelperInterface; + interface com::sun::star::script::XDefaultProperty; + + /// Default member: True if the specified form field object is a valid text input form field. + [attribute, readonly] boolean Valid; + + /// Returns and sets the default text. + [attribute] string Default; + /// Returns the string that specifies how the text should be formated (like date/time, currency) + [attribute, readonly] string Format; + /// Returns the type of content: oovbaapi/ooo/vba/word/WdTextFormFieldType.idl + [attribute, readonly] long Type; + /// Returns and sets the width, in points, of the specified text input field. + [attribute] long Width; + + /// Deletes the text from the text form field. + void Clear(); + /// Sets options for the specified text form field. + void EditType( [in] long Type, [in] /*optional string*/ any Default, + [in] /*optional string*/ any Format, [in] /*optional boolean*/ any Enabled); +}; + +}; }; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/Library_vbaswobj.mk b/sw/Library_vbaswobj.mk index 027b67a5f12c..5785f11f14cf 100644 --- a/sw/Library_vbaswobj.mk +++ b/sw/Library_vbaswobj.mk @@ -75,6 +75,7 @@ $(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/vbaformfieldtextinput \ sw/source/ui/vba/vbaframe \ sw/source/ui/vba/vbaframes \ sw/source/ui/vba/vbalistformat \ diff --git a/sw/qa/core/data/docm/testVBA.docm b/sw/qa/core/data/docm/testVBA.docm Binary files differindex 58ac4e8bd3ae..9abcd091638d 100644 --- a/sw/qa/core/data/docm/testVBA.docm +++ b/sw/qa/core/data/docm/testVBA.docm diff --git a/sw/source/core/crsr/bookmark.cxx b/sw/source/core/crsr/bookmark.cxx index 8bc383f01b23..da13b5165849 100644 --- a/sw/source/core/crsr/bookmark.cxx +++ b/sw/source/core/crsr/bookmark.cxx @@ -554,6 +554,7 @@ namespace sw::mark TextFieldmark::TextFieldmark(const SwPaM& rPaM, const OUString& rName) : Fieldmark(rPaM) + , m_pDocumentContentOperationsManager(nullptr) { if ( !rName.isEmpty() ) m_aName = rName; @@ -562,6 +563,7 @@ namespace sw::mark void TextFieldmark::InitDoc(SwDoc& io_rDoc, sw::mark::InsertMode const eMode, SwPosition const*const pSepPos) { + m_pDocumentContentOperationsManager = &io_rDoc.GetDocumentContentOperationsManager(); if (eMode == sw::mark::InsertMode::New) { lcl_SetFieldMarks(*this, io_rDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND, pSepPos); @@ -586,6 +588,45 @@ namespace sw::mark sw::UpdateFramesForRemoveDeleteRedline(rDoc, tmp); } + OUString TextFieldmark::GetContent() const + { + const SwTextNode& rTextNode = *GetMarkEnd().GetNode().GetTextNode(); + SwPosition const sepPos(sw::mark::FindFieldSep(*this)); + const sal_Int32 nStart(sepPos.GetContentIndex()); + const sal_Int32 nEnd(GetMarkEnd().GetContentIndex()); + + OUString sContent; + const sal_Int32 nLen = rTextNode.GetText().getLength(); + if (nStart + 1 < nLen && nEnd <= nLen && nEnd > nStart + 2) + sContent = rTextNode.GetText().copy(nStart + 1, nEnd - nStart - 2); + + return sContent; + } + + void TextFieldmark::ReplaceContent(const OUString& sNewContent) + { + if (!m_pDocumentContentOperationsManager) + return; + + SwPosition const sepPos(sw::mark::FindFieldSep(*this)); + const sal_Int32 nStart(sepPos.GetContentIndex()); + const sal_Int32 nEnd(GetMarkEnd().GetContentIndex()); + + const sal_Int32 nLen = GetMarkEnd().GetNode().GetTextNode()->GetText().getLength(); + if (nStart + 1 < nLen && nEnd <= nLen && nEnd > nStart + 2) + { + SwPaM aFieldPam(GetMarkStart().GetNode(), nStart + 1, + GetMarkStart().GetNode(), nEnd - 1); + m_pDocumentContentOperationsManager->ReplaceRange(aFieldPam, sNewContent, false); + } + else + { + SwPaM aFieldStartPam(GetMarkStart().GetNode(), nStart + 1); + m_pDocumentContentOperationsManager->InsertString(aFieldStartPam, sNewContent); + } + Invalidate(); + } + NonTextFieldmark::NonTextFieldmark(const SwPaM& rPaM) : Fieldmark(rPaM) { } diff --git a/sw/source/core/inc/bookmark.hxx b/sw/source/core/inc/bookmark.hxx index 94788b8dcdcf..14c176c96a36 100644 --- a/sw/source/core/inc/bookmark.hxx +++ b/sw/source/core/inc/bookmark.hxx @@ -241,6 +241,12 @@ namespace sw::mark { TextFieldmark(const SwPaM& rPaM, const OUString& rName); virtual void InitDoc(SwDoc& io_rDoc, sw::mark::InsertMode eMode, SwPosition const* pSepPos) override; virtual void ReleaseDoc(SwDoc& rDoc) override; + + OUString GetContent() const override; + void ReplaceContent(const OUString& sNewContent) override; + + private: + sw::DocumentContentOperationsManager* m_pDocumentContentOperationsManager; }; // Non text fieldmarks have no content between the start and end marks. diff --git a/sw/source/ui/vba/vbaformfield.cxx b/sw/source/ui/vba/vbaformfield.cxx index 35e8927fe02e..dd43e47b84bf 100644 --- a/sw/source/ui/vba/vbaformfield.cxx +++ b/sw/source/ui/vba/vbaformfield.cxx @@ -26,6 +26,7 @@ #include "vbaformfield.hxx" #include "vbaformfieldcheckbox.hxx" +#include "vbaformfieldtextinput.hxx" #include "wordvbahelper.hxx" using namespace ::ooo::vba; @@ -67,9 +68,8 @@ uno::Any SAL_CALL SwVbaFormField::DropDown() uno::Any SAL_CALL SwVbaFormField::TextInput() { - // return uno::Any(uno::Reference<word::XTextInput>( - // new SwVbaFormFieldTextInput(mxParent, mxContext, m_rFormField))); - return uno::Any(); + return uno::Any(uno::Reference<word::XTextInput>( + new SwVbaFormFieldTextInput(mxParent, mxContext, m_rFormField))); } uno::Any SAL_CALL SwVbaFormField::Previous() diff --git a/sw/source/ui/vba/vbaformfieldtextinput.cxx b/sw/source/ui/vba/vbaformfieldtextinput.cxx new file mode 100644 index 000000000000..8fb65395ef88 --- /dev/null +++ b/sw/source/ui/vba/vbaformfieldtextinput.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/. + */ + +#include <ooo/vba/word/WdTextFormFieldType.hpp> + +#include <sal/log.hxx> + +#include "vbaformfieldtextinput.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +/** + * Official documentation at https://learn.microsoft.com/en-us/office/vba/api/word.textinput + * + * TextInput formfields are inline text objects that are only found in MS Word. + * They cannot be created in Excel or in Calc. + * + * Note that VBA might call this a TextInput, but it might not actually be one, + * so make good use of getValid() + */ +SwVbaFormFieldTextInput::SwVbaFormFieldTextInput( + const uno::Reference<ooo::vba::XHelperInterface>& rParent, + const uno::Reference<uno::XComponentContext>& rContext, sw::mark::IFieldmark& rFormField) + : SwVbaFormFieldTextInput_BASE(rParent, rContext) + , m_rTextInput(rFormField) +{ +} + +SwVbaFormFieldTextInput::~SwVbaFormFieldTextInput() {} + +OUString SwVbaFormFieldTextInput::getDefaultPropertyName() { return "Valid"; } + +sal_Bool SwVbaFormFieldTextInput::getValid() +{ + return IDocumentMarkAccess::GetType(m_rTextInput) + == IDocumentMarkAccess::MarkType::TEXT_FIELDMARK; +} + +OUString SwVbaFormFieldTextInput::getDefault() +{ + if (!getValid()) + return OUString(); + + return m_rTextInput.GetContent(); +} + +void SwVbaFormFieldTextInput::setDefault(const OUString& sSet) +{ + // Hard to know what to do here, since LO doesn't have a default property for text input. + // This really only makes sense when macro-adding a text input. + // In that case, we want it to affect the actual text content. + // However, if the text has already been set by the user, then this shouldn't do anything. + // Assuming this is only ever set when adding a text input seems the sanest approach. + if (!getValid() || getDefault() == sSet) + return; + + m_rTextInput.ReplaceContent(sSet); +} + +OUString SwVbaFormFieldTextInput::getFormat() +{ + if (!getValid()) + return OUString(); + + SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::getFormat stub"); + return OUString(); +} + +sal_Int32 SwVbaFormFieldTextInput::getType() +{ + if (!getValid()) + return word::WdTextFormFieldType::wdRegularText; + + SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::getType stub"); + return word::WdTextFormFieldType::wdRegularText; +} + +sal_Int32 SwVbaFormFieldTextInput::getWidth() +{ + if (!getValid()) + return 0; + + SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::getWidth stub"); + return 11 * 50; +} + +void SwVbaFormFieldTextInput::setWidth(sal_Int32 nWidth) +{ + if (!getValid()) + return; + + SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::setWidth[" << nWidth << "] stub"); +} + +void SwVbaFormFieldTextInput::Clear() +{ + if (!getValid() || m_rTextInput.GetContent().isEmpty()) + return; + + m_rTextInput.ReplaceContent(""); +} + +void SwVbaFormFieldTextInput::EditType(sal_Int32 nType, const uno::Any& rDefault, + const uno::Any& rFormat, const uno::Any& rEnabled) +{ + OUString sDefault; + OUString sFormat; + bool bEnabled = true; + rDefault >>= sDefault; + rFormat >>= sFormat; + rEnabled >>= bEnabled; + SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::EditType[" + << nType << "] sDefault[" << sDefault << "] sFormat[" << sFormat + << "] bEnabled[" << bEnabled << "] stub"); +} + +OUString SwVbaFormFieldTextInput::getServiceImplName() { return "SwVbaFormFieldTextInput"; } + +uno::Sequence<OUString> SwVbaFormFieldTextInput::getServiceNames() +{ + static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.TextInput" }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbaformfieldtextinput.hxx b/sw/source/ui/vba/vbaformfieldtextinput.hxx new file mode 100644 index 000000000000..513cac64defd --- /dev/null +++ b/sw/source/ui/vba/vbaformfieldtextinput.hxx @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include <ooo/vba/word/XTextInput.hpp> + +#include <vbahelper/vbahelperinterface.hxx> + +#include <IDocumentMarkAccess.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XTextInput> SwVbaFormFieldTextInput_BASE; + +class SwVbaFormFieldTextInput : public SwVbaFormFieldTextInput_BASE +{ +private: + sw::mark::IFieldmark& m_rTextInput; + +public: + /// @throws css::uno::RuntimeException + SwVbaFormFieldTextInput(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, + sw::mark::IFieldmark& rFormField); + ~SwVbaFormFieldTextInput() override; + + // XTextInput + OUString SAL_CALL getDefaultPropertyName() override; + + // default member: True if the specified form field object is a valid text form field + sal_Bool SAL_CALL getValid() override; + + // Returns and sets the default text string of the input box + OUString SAL_CALL getDefault() override; + void SAL_CALL setDefault(const OUString& bSet) override; + // Returns the format string for the current text + OUString SAL_CALL getFormat() override; + /* + * Returns the type of text form field. + * Possible return values are: + * wdCalculationText - Calculation text field, + * wdCurrentDateText - Current date text field, + * wdCurrentTimeText - Current time text field, + * wdDateText - Date text field, + * wdNumberText - Number text field, + * wdRegularText - Regular text field. + */ + sal_Int32 SAL_CALL getType() override; + // Returns and sets the width, in points + sal_Int32 SAL_CALL getWidth() override; + void SAL_CALL setWidth(sal_Int32 nSet) override; + + // Deletes the text from the text form field. + void SAL_CALL Clear() override; + // Sets the type, default text string, format string, and enabled status + void SAL_CALL EditType(sal_Int32 nType, const css::uno::Any& rDefault, + const css::uno::Any& rFormat, const css::uno::Any& rEnabled) override; + + // XHelperInterface + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |