sw/inc/formatcontentcontrol.hxx | 4 ++ sw/inc/textcontentcontrol.hxx | 2 + sw/source/core/txtnode/attrcontentcontrol.cxx | 33 ++++++++++++++++++++++++ sw/source/ui/vba/vbacontentcontrollistentry.cxx | 16 +++++------ 4 files changed, 46 insertions(+), 9 deletions(-)
New commits: commit 64ad923652a11dc68a93f41044df9719c15dec86 Author: Justin Luth <jl...@mail.com> AuthorDate: Mon Nov 28 14:16:57 2022 -0500 Commit: Justin Luth <jl...@mail.com> CommitDate: Thu Dec 1 21:26:49 2022 +0100 tdf#151548 ContentControls: improve GetSelectedListItem Before there was only an option to get the temporarily selected list item that had not yet been committed to text. Add a function that checks whether there is a valid selected item, regardless of whether it has been written out or not. Change-Id: I1199bdccd2e665089750eefa5c3a445d56935556 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143420 Tested-by: Jenkins Reviewed-by: Justin Luth <jl...@mail.com> diff --git a/sw/inc/formatcontentcontrol.hxx b/sw/inc/formatcontentcontrol.hxx index 88d32e83d31a..94399d6818e8 100644 --- a/sw/inc/formatcontentcontrol.hxx +++ b/sw/inc/formatcontentcontrol.hxx @@ -306,6 +306,10 @@ public: const std::optional<size_t>& GetSelectedListItem() const { return m_oSelectedListItem; } + /// Get a copy of selected list item's index, + /// potentially even if the selection is already written out to text (i.e. validated). + std::optional<size_t> GetSelectedListItem(bool bCheckDocModel) const; + void SetSelectedDate(std::optional<double> oSelectedDate) { m_oSelectedDate = oSelectedDate; } const std::optional<double>& GetSelectedDate() const { return m_oSelectedDate; } diff --git a/sw/inc/textcontentcontrol.hxx b/sw/inc/textcontentcontrol.hxx index 8c8a3b3ee044..a9bc4e4a1054 100644 --- a/sw/inc/textcontentcontrol.hxx +++ b/sw/inc/textcontentcontrol.hxx @@ -42,6 +42,8 @@ public: void ChgTextNode(SwTextNode* pNode); SwTextNode* GetTextNode() const; + /// Get the current (potentially invalid) string from the doc + OUString ToString() const; void Invalidate(); void dumpAsXml(xmlTextWriterPtr pWriter) const override; diff --git a/sw/source/core/txtnode/attrcontentcontrol.cxx b/sw/source/core/txtnode/attrcontentcontrol.cxx index 98cfa13f9611..e3d0c2237b3b 100644 --- a/sw/source/core/txtnode/attrcontentcontrol.cxx +++ b/sw/source/core/txtnode/attrcontentcontrol.cxx @@ -232,6 +232,25 @@ void SwContentControl::SwClientNotify(const SwModify&, const SfxHint& rHint) } } +std::optional<size_t> SwContentControl::GetSelectedListItem(bool bCheckDocModel) const +{ + if (!bCheckDocModel || m_oSelectedListItem) + return m_oSelectedListItem; + + const size_t nLen = GetListItems().size(); + if (GetShowingPlaceHolder() || !nLen || !GetTextAttr()) + return std::nullopt; + + const OUString& rText = GetTextAttr()->ToString(); + for (size_t i = 0; i < nLen; ++i) + { + if (GetTextAttr()[i].ToString() == rText) + return i; + } + assert(!GetDropDown() && "DropDowns must always have an associated list item"); + return std::nullopt; +} + bool SwContentControl::AddListItem(size_t nZIndex, const OUString& rDisplayText, const OUString& rValue) { @@ -662,6 +681,20 @@ SwTextNode* SwTextContentControl::GetTextNode() const return rFormatContentControl.GetTextNode(); } +OUString SwTextContentControl::ToString() const +{ + if (!GetTextNode()) + return OUString(); + + // Don't select the text attribute itself at the start. + sal_Int32 nStart = GetStart() + 1; + // Don't select the CH_TXTATR_BREAKWORD itself at the end. + sal_Int32 nEnd = *End() - 1; + + SwPaM aPaM(*GetTextNode(), nStart, *GetTextNode(), nEnd); + return aPaM.GetText(); +} + void SwTextContentControl::Invalidate() { SwDocShell* pDocShell = GetTextNode() ? GetTextNode()->GetDoc().GetDocShell() : nullptr; diff --git a/sw/source/ui/vba/vbacontentcontrollistentry.cxx b/sw/source/ui/vba/vbacontentcontrollistentry.cxx index 61d2a1faf6a8..80603df21309 100644 --- a/sw/source/ui/vba/vbacontentcontrollistentry.cxx +++ b/sw/source/ui/vba/vbacontentcontrollistentry.cxx @@ -63,19 +63,17 @@ void SwVbaContentControlListEntry::setText(const OUString& rSet) return; } - bool bNeedsInvalidation = false; - if (!pCC->GetShowingPlaceHolder()) - { - // TODO: implement bCheckDocModel - std::optional<size_t> oSel(pCC->GetSelectedListItem(/*bCheckDocModel=true*/)); - bNeedsInvalidation = oSel && *oSel == m_nZIndex; - } + const std::optional<size_t> oSel(pCC->GetSelectedListItem(/*bCheckDocModel=*/true)); + const bool bNeedsInvalidation = pCC->GetDropDown() && oSel && *oSel == m_nZIndex; vListItems[m_nZIndex].m_aDisplayText = rSet; pCC->SetListItems(vListItems); if (bNeedsInvalidation) + { + pCC->SetSelectedListItem(m_nZIndex); m_rCC.Invalidate(); + } } OUString SwVbaContentControlListEntry::getValue() @@ -114,7 +112,7 @@ void SwVbaContentControlListEntry::MoveDown() if (m_nZIndex >= pCC->GetListItems().size() - 1) return; - const std::optional<size_t>& oSelected = pCC->GetSelectedListItem(); + const std::optional<size_t> oSelected = pCC->GetSelectedListItem(/*bCheckDocModel=*/false); if (oSelected) { if (*oSelected == m_nZIndex) @@ -135,7 +133,7 @@ void SwVbaContentControlListEntry::MoveUp() if (!m_nZIndex || m_nZIndex >= pCC->GetListItems().size()) return; - const std::optional<size_t>& oSelected = pCC->GetSelectedListItem(); + const std::optional<size_t> oSelected = pCC->GetSelectedListItem(/*bCheckDocModel=*/false); if (oSelected) { if (*oSelected == m_nZIndex)