tdf#152029 Bring comment fields to attention in the document view
when the mouse pointer is over comment content type and content entries
in the Navigator content tree
Change-Id: I81f8667231fe0e94f0b81c4c2d4955ba17aaa3da
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143979
Tested-by: Jenkins
Reviewed-by: Jim Raykowski <raykowj@gmail.com>
diff --git a/sw/source/uibase/inc/conttree.hxx b/sw/source/uibase/inc/conttree.hxx
index 3cf671a..af39a41 100644
--- a/sw/source/uibase/inc/conttree.hxx
+++ b/sw/source/uibase/inc/conttree.hxx
@@ -141,6 +141,7 @@ 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 BringPostItFieldsToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr);
void BringDrawingObjectsToAttention(std::vector<const SdrObject*>& rDrawingObjectsArr);
void BringTextFieldsToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr);
void BringFootnotesToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr);
diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx
index 0c027d73..7853b1c 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -102,6 +102,7 @@
#include <txtftn.hxx>
#include <fmtftn.hxx>
#include <txtannotationfld.hxx>
#include <txtfrm.hxx>
#include <txtrfmrk.hxx>
#include <svx/sdr/overlay/overlayselection.hxx>
@@ -1248,6 +1249,15 @@ IMPL_LINK(SwContentTree, MouseMoveHdl, const MouseEvent&, rMEvt, bool)
BringReferencesToAttention(aTextAttrArr);
}
}
else if (nType == ContentTypeId::POSTIT)
{
if (const SwTextAttr* pTextAttr =
static_cast<SwPostItContent*>(pCnt)->GetPostIt()->GetTextField())
{
std::vector<const SwTextAttr*> aTextAttrArr {pTextAttr};
BringPostItFieldsToAttention(aTextAttrArr);
}
}
else if (nType == ContentTypeId::DRAWOBJECT)
{
if (!pCnt->IsInvisible())
@@ -1372,6 +1382,20 @@ IMPL_LINK(SwContentTree, MouseMoveHdl, const MouseEvent&, rMEvt, bool)
}
BringReferencesToAttention(aTextAttrArr);
}
else if (nType == ContentTypeId::POSTIT)
{
std::vector<const SwTextAttr*> aTextAttrArr;
for (size_t i = 0; i < m_aActiveContentArr[nType]->GetMemberCount(); i++)
{
const SwPostItContent* pPostItContent = static_cast<const SwPostItContent*>(
m_aActiveContentArr[nType]->GetMember(i));
if (pPostItContent && !pPostItContent->IsInvisible())
if (const SwFormatField* pFormatField = pPostItContent->GetPostIt())
if (const SwTextAttr* pTextAttr = pFormatField->GetTextField())
aTextAttrArr.push_back(pTextAttr);
}
BringPostItFieldsToAttention(aTextAttrArr);
}
else if (nType == ContentTypeId::DRAWOBJECT)
{
IDocumentDrawModelAccess& rIDDMA = m_pActiveShell->getIDocumentDrawModelAccess();
@@ -5944,6 +5968,66 @@ void SwContentTree::BringReferencesToAttention(std::vector<const SwTextAttr*>& r
m_aOverlayObjectDelayTimer.Start();
}
void SwContentTree::BringPostItFieldsToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr)
{
std::vector<basegfx::B2DRange> aRanges;
for (const SwTextAttr* p : rTextAttrsArr)
{
if (!p)
continue;
// use as a fallback when there is no mark
SwTextNode& rTextNode = p->GetFormatField().GetTextField()->GetTextNode();
if (!rTextNode.getLayoutFrame(m_pActiveShell->GetLayout()))
continue;
assert(dynamic_cast<const SwTextAnnotationField*>(p->GetFormatField().GetTextField()));
const SwTextAnnotationField* pTextAnnotationField =
static_cast<const SwTextAnnotationField*>(p->GetFormatField().GetTextField());
if (!pTextAnnotationField)
continue;
const ::sw::mark::IMark* pAnnotationMark =
pTextAnnotationField != nullptr ? pTextAnnotationField->GetAnnotationMark()
: nullptr;
const SwPosition aMarkStart = pAnnotationMark ? pAnnotationMark->GetMarkStart()
: SwPosition(rTextNode, p->GetStart());
const SwPosition aMarkEnd = pAnnotationMark ? pAnnotationMark->GetMarkEnd()
: SwPosition(rTextNode, p->GetAnyEnd());
const SwTextFrame* pMarkStartFrame = static_cast<SwTextFrame*>(
aMarkStart.GetNode().GetTextNode()->getLayoutFrame(m_pActiveShell->GetLayout()));
const SwTextFrame* pMarkEndFrame = static_cast<SwTextFrame*>(
aMarkEnd.GetNode().GetTextNode()->getLayoutFrame(m_pActiveShell->GetLayout()));
if (!pMarkStartFrame || !pMarkEndFrame)
continue;
SwRect aStartCharRect;
pMarkStartFrame->GetCharRect(aStartCharRect, aMarkStart);
SwRect aEndCharRect;
pMarkEndFrame->GetCharRect(aEndCharRect, aMarkEnd);
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 = pMarkStartFrame->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::BringFootnotesToAttention(std::vector<const SwTextAttr*>& rTextAttrsArr)
{
std::vector<basegfx::B2DRange> aRanges;
@@ -5987,7 +6071,6 @@ void SwContentTree::BringFootnotesToAttention(std::vector<const SwTextAttr*>& rT
m_aOverlayObjectDelayTimer.Start();
}
void SwContentTree::BringDrawingObjectsToAttention(std::vector<const SdrObject*>& rDrawingObjectsArr)
{
std::vector<basegfx::B2DRange> aRanges;