sw/source/uibase/inc/conttree.hxx | 2 sw/source/uibase/utlui/content.cxx | 143 ++++++++++++++++++++++++++++++++++++- 2 files changed, 143 insertions(+), 2 deletions(-)
New commits: commit 329c32d1e9e316f3ba75d38dd4565ea14599ec9a Author: Jim Raykowski <[email protected]> AuthorDate: Sun Dec 4 19:31:45 2022 -0900 Commit: Noel Grandin <[email protected]> CommitDate: Thu Dec 8 08:02:22 2022 +0000 tdf#152029 Bring refmarks and textfields to attention in document view when the mouse pointer is over these content types and content entries in the Navigator content tree Change-Id: I07754d79597d1df4baa696dd86c58ff601576e5d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143695 Tested-by: Jenkins Reviewed-by: Noel Grandin <[email protected]> diff --git a/sw/source/uibase/inc/conttree.hxx b/sw/source/uibase/inc/conttree.hxx index 6d2083f04480..cc7bb6d10e17 100644 --- a/sw/source/uibase/inc/conttree.hxx +++ b/sw/source/uibase/inc/conttree.hxx @@ -138,6 +138,8 @@ class SwContentTree final : public SfxListener void BringBookmarksToAttention(const std::vector<OUString>& rNames); void BringURLFieldsToAttention(const SwGetINetAttrs& rINetAttrsArr); + void BringReferencesToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr); + void BringTextFieldsToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr); /** * Before any data will be deleted, the last active entry has to be found. diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 3e581082c8e8..fc2ec547826f 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -103,6 +103,7 @@ #include <fmtftn.hxx> #include <txtfrm.hxx> +#include <txtrfmrk.hxx> #include <svx/sdr/overlay/overlayselection.hxx> #include <svx/sdr/overlay/overlayobject.hxx> #include <svx/sdr/overlay/overlaymanager.hxx> @@ -1166,7 +1167,8 @@ IMPL_LINK(SwContentTree, MouseMoveHdl, const MouseEvent&, rMEvt, bool) SwContent* pCnt = weld::fromId<SwContent*>(m_xTreeView->get_id(*xEntry)); const ContentTypeId nType = pCnt->GetParent()->GetType(); bRemoveOverlayObject = nType != ContentTypeId::BOOKMARK && - nType != ContentTypeId::URLFIELD; + nType != ContentTypeId::URLFIELD && nType != ContentTypeId::REFERENCE && + nType != ContentTypeId::TEXTFIELD; if (!bRemoveOverlayObject && m_xTreeView->iter_compare(*xEntry, *m_xOverlayCompareEntry) != 0) { @@ -1180,6 +1182,24 @@ IMPL_LINK(SwContentTree, MouseMoveHdl, const MouseEvent&, rMEvt, bool) BringURLFieldsToAttention(SwGetINetAttrs {SwGetINetAttr(pCnt->GetName(), *static_cast<SwURLFieldContent*>(pCnt)->GetINetAttr())}); } + else if (nType == ContentTypeId::REFERENCE) + { + if (const SwTextAttr* pTextAttr = + m_pActiveShell->GetDoc()->GetRefMark(pCnt->GetName())->GetTextRefMark()) + { + std::vector<const SwTextAttr*> aTextAttrArr {pTextAttr}; + BringReferencesToAttention(aTextAttrArr); + } + } + else if (nType == ContentTypeId::TEXTFIELD) + { + if (const SwTextAttr* pTextAttr = + static_cast<SwTextFieldContent*>(pCnt)->GetFormatField()->GetTextField()) + { + std::vector<const SwTextAttr*> aTextAttrArr {pTextAttr}; + BringTextFieldsToAttention(aTextAttrArr); + } + } } } else // content type entry @@ -1187,7 +1207,8 @@ IMPL_LINK(SwContentTree, MouseMoveHdl, const MouseEvent&, rMEvt, bool) const ContentTypeId nType = weld::fromId<SwContentType*>(m_xTreeView->get_id(*xEntry))->GetType(); bRemoveOverlayObject = nType != ContentTypeId::BOOKMARK && - nType != ContentTypeId::URLFIELD; + nType != ContentTypeId::URLFIELD && nType != ContentTypeId::REFERENCE && + nType != ContentTypeId::TEXTFIELD; if (!bRemoveOverlayObject && m_xTreeView->iter_compare(*xEntry, *m_xOverlayCompareEntry) != 0) { @@ -1211,6 +1232,38 @@ IMPL_LINK(SwContentTree, MouseMoveHdl, const MouseEvent&, rMEvt, bool) m_pActiveShell->GetINetAttrs(aINetAttrsArr, false); BringURLFieldsToAttention(aINetAttrsArr); } + else if (nType == ContentTypeId::REFERENCE) + { + std::vector<const SwTextAttr*> aTextAttrArr; + for (const SfxPoolItem* pItem : + m_pActiveShell->GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK)) + { + auto pRefMark = dynamic_cast<const SwFormatRefMark*>(pItem); + if (!pRefMark) + continue; + const SwTextRefMark* pTextRef = pRefMark->GetTextRefMark(); + if (pTextRef && &pTextRef->GetTextNode().GetNodes() == + &m_pActiveShell->GetNodes()) + aTextAttrArr.push_back(pTextRef); + } + BringReferencesToAttention(aTextAttrArr); + } + else if (nType == ContentTypeId::TEXTFIELD) + { + std::vector<const SwTextAttr*> aTextAttrArr; + for (size_t i = 0; i < m_aActiveContentArr[nType]->GetMemberCount(); i++) + { + const SwTextFieldContent* pTextFieldContent = + static_cast<const SwTextFieldContent*>( + m_aActiveContentArr[nType]->GetMember(i)); + if (pTextFieldContent) + if (const SwFormatField* pFormatField = + pTextFieldContent->GetFormatField()) + if (const SwTextAttr* pTextAttr = pFormatField->GetTextField()) + aTextAttrArr.push_back(pTextAttr); + } + BringTextFieldsToAttention(aTextAttrArr); + } } } } @@ -5632,4 +5685,90 @@ void SwContentTree::BringURLFieldsToAttention(const SwGetINetAttrs& rINetAttrsAr m_aOverlayObjectDelayTimer.Start(); } +void SwContentTree::BringReferencesToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr) +{ + std::vector<basegfx::B2DRange> aRanges; + for (const SwTextAttr* p : rTextAttrsArr) + { + const SwTextNode& rTextNode = p->GetRefMark().GetTextRefMark()->GetTextNode(); + if (SwTextFrame* pFrame = static_cast<SwTextFrame*>( + rTextNode.getLayoutFrame(m_pActiveShell->GetLayout()))) + { + SwRect aStartCharRect; + SwPosition aStartPos(rTextNode, p->GetStart()); + pFrame->GetCharRect(aStartCharRect, aStartPos); + SwRect aEndCharRect; + SwPosition aEndPos(rTextNode, p->GetAnyEnd()); + pFrame->GetCharRect(aEndCharRect, aEndPos); + if (aStartCharRect.Top() == aEndCharRect.Top()) + { + // single line range + aRanges.emplace_back(aStartCharRect.Left(), aStartCharRect.Top(), + aEndCharRect.Right() + 1, aEndCharRect.Bottom() + 1); + } + else + { + // multi line range + SwRect aFrameRect = pFrame->getFrameArea(); + aRanges.emplace_back(aStartCharRect.Left(), aStartCharRect.Top(), + aFrameRect.Right(), aStartCharRect.Bottom() + 1); + if (aStartCharRect.Bottom() + 1 != aEndCharRect.Top()) + aRanges.emplace_back(aFrameRect.Left(), aStartCharRect.Bottom() + 1, + aFrameRect.Right(), aEndCharRect.Top() + 1); + aRanges.emplace_back(aFrameRect.Left(), aEndCharRect.Top() + 1, + aEndCharRect.Right() + 1, aEndCharRect.Bottom() + 1); + } + } + } + if (m_xOverlayObject && m_xOverlayObject->getOverlayManager()) + m_xOverlayObject->getOverlayManager()->remove(*m_xOverlayObject); + m_xOverlayObject.reset(new sdr::overlay::OverlaySelection(sdr::overlay::OverlayType::Invert, + Color(), std::move(aRanges), + true /*unused for Invert type*/)); + m_aOverlayObjectDelayTimer.Start(); +} + +void SwContentTree::BringTextFieldsToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr) +{ + std::vector<basegfx::B2DRange> aRanges; + std::shared_ptr<SwPaM> pPamForTextField; + for (const SwTextAttr* p : rTextAttrsArr) + { + SwTextField::GetPamForTextField(*p->GetFormatField().GetTextField(), pPamForTextField); + SwTextNode& rTextNode = p->GetFormatField().GetTextField()->GetTextNode(); + if (SwTextFrame* pFrame = static_cast<SwTextFrame*>( + rTextNode.getLayoutFrame(m_pActiveShell->GetLayout()))) + { + SwRect aStartCharRect; + pFrame->GetCharRect(aStartCharRect, *pPamForTextField->GetMark()); + SwRect aEndCharRect; + pFrame->GetCharRect(aEndCharRect, *pPamForTextField->GetPoint()); + if (aStartCharRect.Top() == aEndCharRect.Top()) + { + // single line range + aRanges.emplace_back(aStartCharRect.Left(), aStartCharRect.Top(), + aEndCharRect.Right() + 1, aEndCharRect.Bottom() + 1); + } + else + { + // multi line range + SwRect aFrameRect = pFrame->getFrameArea(); + aRanges.emplace_back(aStartCharRect.Left(), aStartCharRect.Top(), + aFrameRect.Right(), aStartCharRect.Bottom() + 1); + if (aStartCharRect.Bottom() + 1 != aEndCharRect.Top()) + aRanges.emplace_back(aFrameRect.Left(), aStartCharRect.Bottom() + 1, + aFrameRect.Right(), aEndCharRect.Top() + 1); + aRanges.emplace_back(aFrameRect.Left(), aEndCharRect.Top() + 1, + aEndCharRect.Right() + 1, aEndCharRect.Bottom() + 1); + } + } + } + if (m_xOverlayObject && m_xOverlayObject->getOverlayManager()) + m_xOverlayObject->getOverlayManager()->remove(*m_xOverlayObject); + m_xOverlayObject.reset(new sdr::overlay::OverlaySelection(sdr::overlay::OverlayType::Invert, + Color(), std::move(aRanges), + true /*unused for Invert type*/)); + m_aOverlayObjectDelayTimer.Start(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
