Related tdf#156116 - A11Y - show only one warning/textframes

Only give one warninig message (Anchor Frames/Text boxes “As Character“.)
per floating textframes.

cherry-picked from commit: bac847ded67941c6db21a2f041a0b9dad9d2b0bd
(Related tdf#156116 - A11Y - show only one warning/textframes) - part 1

Change-Id: I6cff4022a30de9734d6afc592f52c7ad4297c18a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156200
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156499
diff --git a/include/sfx2/AccessibilityIssue.hxx b/include/sfx2/AccessibilityIssue.hxx
index f20ce70..ac9ad6a 100644
--- a/include/sfx2/AccessibilityIssue.hxx
+++ b/include/sfx2/AccessibilityIssue.hxx
@@ -44,6 +44,7 @@ class SFX2_DLLPUBLIC AccessibilityIssue
{
public:
    AccessibilityIssue(AccessibilityIssueID eIssueID = AccessibilityIssueID::UNSPECIFIED);
    AccessibilityIssue(AccessibilityIssue const&) = default;
    virtual ~AccessibilityIssue();

    virtual bool canGotoIssue() const = 0;
@@ -54,6 +55,8 @@ public:

    void setParent(weld::Window* pParent) { m_pParent = pParent; }

    AccessibilityIssue& operator=(const AccessibilityIssue&) = default;

    AccessibilityIssueID m_eIssueID;
    OUString m_aIssueText;

diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx
index bf0d4ae..f4c4967 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -1174,6 +1174,10 @@ public:
/// Check for floating text frames, as it causes problems with reading order.
class FloatingTextCheck : public NodeCheck
{
private:
    // list of already added textframes.
    std::map<SwNodeIndex, SwNodeIndex> m_vIdx;

public:
    FloatingTextCheck(sfx::AccessibilityIssueCollection& rIssueCollection)
        : NodeCheck(rIssueCollection)
@@ -1190,7 +1194,9 @@ public:
        // If a node is in fly and if it is not anchored as char, throw warning.
        const SwNode* startFly = pCurrent->FindFlyStartNode();
        if (startFly
            && startFly->GetFlyFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR)
            && startFly->GetFlyFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR
            && m_vIdx.insert(std::make_pair(SwNodeIndex(*startFly), SwNodeIndex(*pCurrent))).second
                   == true)
        {
            auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_FLOATING_TEXT));
            pIssue->setIssueObject(IssueObject::TEXTFRAME);
diff --git a/sw/source/core/access/AccessibilityIssue.cxx b/sw/source/core/access/AccessibilityIssue.cxx
index 1cb1a9a..edef086 100644
--- a/sw/source/core/access/AccessibilityIssue.cxx
+++ b/sw/source/core/access/AccessibilityIssue.cxx
@@ -62,22 +62,27 @@ void AccessibilityIssue::gotoIssue() const
    if (!m_pDoc)
        return;

    switch (m_eIssueObject)
    /* Copying the issueobject because the EnterSelFrameMode ends up calling some sidebar functions
    that recreate the list of a11y issues and the AccessibilityIssue objects are stored by value in a vector
    and the vector is being mutated there and so the instance is overwritten with something else. */
    AccessibilityIssue TempObject(*this);

    switch (TempObject.m_eIssueObject)
    {
        case IssueObject::GRAPHIC:
        case IssueObject::OLE:
        case IssueObject::TEXTFRAME:
        {
            SwWrtShell* pWrtShell = m_pDoc->GetDocShell()->GetWrtShell();
            bool bSelected = pWrtShell->GotoFly(m_sObjectID, FLYCNTTYPE_ALL, true);
            SwWrtShell* pWrtShell = TempObject.m_pDoc->GetDocShell()->GetWrtShell();
            bool bSelected = pWrtShell->GotoFly(TempObject.m_sObjectID, FLYCNTTYPE_ALL, true);
            if (bSelected && pWrtShell->IsFrameSelected())
            {
                pWrtShell->HideCursor();
                pWrtShell->EnterSelFrameMode();
            }

            if (!bSelected && m_eIssueObject == IssueObject::TEXTFRAME)
                pWrtShell->GotoDrawingObject(m_sObjectID);
            if (!bSelected && TempObject.m_eIssueObject == IssueObject::TEXTFRAME)
                pWrtShell->GotoDrawingObject(TempObject.m_sObjectID);

            if (comphelper::LibreOfficeKit::isActive())
                pWrtShell->ShowCursor();
@@ -85,21 +90,21 @@ void AccessibilityIssue::gotoIssue() const
        break;
        case IssueObject::SHAPE:
        {
            SwWrtShell* pWrtShell = m_pDoc->GetDocShell()->GetWrtShell();
            pWrtShell->GotoDrawingObject(m_sObjectID);
            SwWrtShell* pWrtShell = TempObject.m_pDoc->GetDocShell()->GetWrtShell();
            pWrtShell->GotoDrawingObject(TempObject.m_sObjectID);
            if (comphelper::LibreOfficeKit::isActive())
                pWrtShell->ShowCursor();
        }
        break;
        case IssueObject::FORM:
        {
            SwWrtShell* pWrtShell = m_pDoc->GetDocShell()->GetWrtShell();
            SwWrtShell* pWrtShell = TempObject.m_pDoc->GetDocShell()->GetWrtShell();
            bool bIsDesignMode = pWrtShell->GetView().GetFormShell()->IsDesignMode();
            if (bIsDesignMode || (!bIsDesignMode && pWrtShell->WarnSwitchToDesignModeDialog()))
            {
                if (!bIsDesignMode)
                    pWrtShell->GetView().GetFormShell()->SetDesignMode(true);
                pWrtShell->GotoDrawingObject(m_sObjectID);
                pWrtShell->GotoDrawingObject(TempObject.m_sObjectID);
                if (comphelper::LibreOfficeKit::isActive())
                    pWrtShell->ShowCursor();
            }
@@ -107,18 +112,18 @@ void AccessibilityIssue::gotoIssue() const
        break;
        case IssueObject::TABLE:
        {
            SwWrtShell* pWrtShell = m_pDoc->GetDocShell()->GetWrtShell();
            pWrtShell->GotoTable(m_sObjectID);
            SwWrtShell* pWrtShell = TempObject.m_pDoc->GetDocShell()->GetWrtShell();
            pWrtShell->GotoTable(TempObject.m_sObjectID);
            if (comphelper::LibreOfficeKit::isActive())
                pWrtShell->ShowCursor();
        }
        break;
        case IssueObject::TEXT:
        {
            SwWrtShell* pWrtShell = m_pDoc->GetDocShell()->GetWrtShell();
            SwContentNode* pContentNode = m_pNode->GetContentNode();
            SwPosition aPoint(*pContentNode, m_nStart);
            SwPosition aMark(*pContentNode, m_nEnd);
            SwWrtShell* pWrtShell = TempObject.m_pDoc->GetDocShell()->GetWrtShell();
            SwContentNode* pContentNode = TempObject.m_pNode->GetContentNode();
            SwPosition aPoint(*pContentNode, TempObject.m_nStart);
            SwPosition aMark(*pContentNode, TempObject.m_nEnd);
            pWrtShell->EnterStdMode();
            pWrtShell->StartAllAction();
            SwPaM* pPaM = pWrtShell->GetCursor();
@@ -132,9 +137,9 @@ void AccessibilityIssue::gotoIssue() const
        break;
        case IssueObject::FOOTENDNOTE:
        {
            SwWrtShell* pWrtShell = m_pDoc->GetDocShell()->GetWrtShell();
            if (m_pTextFootnote)
                pWrtShell->GotoFootnoteAnchor(*m_pTextFootnote);
            SwWrtShell* pWrtShell = TempObject.m_pDoc->GetDocShell()->GetWrtShell();
            if (TempObject.m_pTextFootnote)
                pWrtShell->GotoFootnoteAnchor(*TempObject.m_pTextFootnote);
            if (comphelper::LibreOfficeKit::isActive())
                pWrtShell->ShowCursor();
        }
@@ -142,7 +147,7 @@ void AccessibilityIssue::gotoIssue() const
        default:
            break;
    }
    m_pDoc->GetDocShell()->GetView()->GetEditWin().GrabFocus();
    TempObject.m_pDoc->GetDocShell()->GetView()->GetEditWin().GrabFocus();
}

bool AccessibilityIssue::canQuickFixIssue() const
diff --git a/sw/source/core/inc/AccessibilityIssue.hxx b/sw/source/core/inc/AccessibilityIssue.hxx
index 82474e1..151d565 100644
--- a/sw/source/core/inc/AccessibilityIssue.hxx
+++ b/sw/source/core/inc/AccessibilityIssue.hxx
@@ -48,6 +48,7 @@ private:

public:
    AccessibilityIssue(sfx::AccessibilityIssueID eIssueID = sfx::AccessibilityIssueID::UNSPECIFIED);
    AccessibilityIssue(AccessibilityIssue const&) = default;

    void setIssueObject(IssueObject eIssueObject);
    void setDoc(SwDoc& rDoc);
@@ -76,6 +77,8 @@ public:
    sal_Int32 getEnd() { return m_nEnd; }
    SwNode* getNode() { return m_pNode; }
    SwTextFootnote* getTextFootnote() { return m_pTextFootnote; }

    AccessibilityIssue& operator=(const AccessibilityIssue&) = default;
};

} // end sw namespace
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index 07f767e..82ac2fe 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -2620,8 +2620,17 @@ void SwFrameFormat::SetFormatName( const OUString& rNewName, bool bBroadcast )
        {
            if (SwFlyFrame* pSFly = SwIterator<SwFlyFrame, SwFormat>(*this).First())
            {
                if (SwNode* pSwNode = static_cast<SwNoTextFrame*>(pSFly->Lower())->GetNode())
                    pSwNode->resetAndQueueAccessibilityCheck(true);
                if (pSFly->Lower() && !pSFly->Lower()->IsNoTextFrame())
                {
                    // TODO: update AccessibilityCheckStatus for textframes
                }
                else
                {
                    if (SwNode* pSwNode = static_cast<SwNoTextFrame*>(pSFly->Lower())->GetNode())
                    {
                        pSwNode->resetAndQueueAccessibilityCheck(true);
                    }
                }
            }
        }
    }