LibreOffice Module sw (master) 1
OnlineAccessibilityCheck.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
21#include <doc.hxx>
22#include <pam.hxx>
23#include <txtfrm.hxx>
24#include <sfx2/bindings.hxx>
25#include <sfx2/dispatch.hxx>
26#include <docsh.hxx>
27#include <cmdid.h>
28#include <officecfg/Office/Common.hxx>
30
31namespace sw
32{
34 : m_pNode(pNode)
35{
36 if (m_pNode)
37 {
38 auto* pBroadcast = dynamic_cast<sw::BroadcastingModify*>(m_pNode);
39 if (pBroadcast)
40 {
42 StartListening(pBroadcast->GetNotifier());
43 }
44 else
45 {
46 m_pNode = nullptr;
47 }
48 }
49}
50
52
54{
55 if (!m_pNode)
56 return false;
57 if (!HasBroadcaster())
58 m_pNode = nullptr;
59 return m_pNode;
60}
61
63{
64 if (isAlive())
65 return m_pNode;
66 return nullptr;
67}
68
70 : m_rDocument(rDocument)
71 , m_aAccessibilityCheck(&m_rDocument)
72 , m_nPreviousNodeIndex(-1)
73 , m_nAccessibilityIssues(0)
74 , m_bInitialCheck(false)
75 , m_bOnlineCheckStatus(
76 !utl::ConfigManager::IsFuzzing()
77 ? officecfg::Office::Common::Accessibility::OnlineAccessibilityCheck::get()
78 : false)
79{
80}
81
83{
84 if (!pNode->IsContentNode() && !pNode->IsTableNode())
85 return;
86
88
89 auto it = m_aNodes.find(pNode);
90 if (it == m_aNodes.end())
91 {
92 m_aNodes.emplace(pNode, std::make_unique<WeakNodeContainer>(pNode));
93 }
94
95 for (auto iterator = m_aNodes.begin(); iterator != m_aNodes.end();)
96 {
97 auto& pWeakContentNode = iterator->second;
98 if (pWeakContentNode->isAlive())
99 {
100 auto& rStatus = pWeakContentNode->getNode()->getAccessibilityCheckStatus();
101 if (rStatus.pCollection)
102 {
103 m_nAccessibilityIssues += rStatus.pCollection->getIssues().size();
104 ++iterator;
105 }
106 else
107 {
108 iterator = m_aNodes.erase(iterator);
109 }
110 }
111 else
112 {
113 iterator = m_aNodes.erase(iterator);
114 }
115 }
116}
117
119{
122 : nullptr;
123 if (pBindings)
125}
126
128{
130
132
133 for (SwFrameFormat* const& pFrameFormat : pNode->GetAnchoredFlys())
134 {
135 SdrObject* pObject = pFrameFormat->FindSdrObject();
136 if (pObject)
138 }
139
140 auto aCollection = m_aAccessibilityCheck.getIssueCollection();
141
143 = std::make_unique<sfx::AccessibilityIssueCollection>(aCollection);
144}
145
147{
150 auto aCollection = m_aAccessibilityCheck.getIssueCollection();
152 = std::make_unique<sfx::AccessibilityIssueCollection>(aCollection);
153}
154
156{
157 if (m_bInitialCheck)
158 return;
159
161
162 auto const& pNodes = m_rDocument.GetNodes();
163 for (SwNodeOffset n(0); n < pNodes.Count(); ++n)
164 {
165 SwNode* pNode = pNodes[n];
166 if (pNode)
167 {
169 updateNodeStatus(pNode);
170 }
171 }
172
174
175 m_bInitialCheck = true;
176}
177
179{
180 bool bOnlineCheckStatus
183
184 if (bOnlineCheckStatus != m_bOnlineCheckStatus)
185 {
186 m_pPreviousNode.reset();
188 m_bInitialCheck = false; // force initial check
189
190 if (!bOnlineCheckStatus)
191 {
192 clearAccessibilityIssuesFromAllNodes(); // cleanup all accessibility check data on nodes
194 }
195 else
196 {
198 }
199
200 m_bOnlineCheckStatus = bOnlineCheckStatus;
201
203 }
204}
205
207{
209
211 return;
212
213 initialCheck();
214
216}
217
219{
220 auto nCurrenNodeIndex = rNewPos.GetNodeIndex();
221 auto* pCurrentNode = &rNewPos.GetNode();
222
223 if (!pCurrentNode->IsContentNode() && !pCurrentNode->IsTableNode())
224 return;
225
226 auto pCurrentWeak = std::make_unique<WeakNodeContainer>(pCurrentNode);
227 if (!pCurrentWeak->isAlive())
228 return;
229
230 // Check if previous node was deleted
231 if (!m_pPreviousNode || !m_pPreviousNode->isAlive())
232 {
233 m_pPreviousNode = std::move(pCurrentWeak);
234 m_nPreviousNodeIndex = nCurrenNodeIndex;
235 return;
236 }
237
238 // Check if node index changed
239 if (nCurrenNodeIndex == m_nPreviousNodeIndex)
240 return;
241
242 // Check if previous node is valid
244 || m_nPreviousNodeIndex >= pCurrentNode->GetNodes().Count())
245 {
246 m_pPreviousNode = std::move(pCurrentWeak);
247 m_nPreviousNodeIndex = nCurrenNodeIndex;
248 return;
249 }
250
251 // Run the document level Accessibility Check
253
254 // Get the real previous node from index
255 SwNode* pNode = pCurrentNode->GetNodes()[m_nPreviousNodeIndex];
256
257 if (pNode && (pNode->IsContentNode() || pNode->IsTableNode()))
258 {
260 updateNodeStatus(pNode);
261
262 // Assign previous node and index
263 m_pPreviousNode = std::move(pCurrentWeak);
264 m_nPreviousNodeIndex = nCurrenNodeIndex;
265 }
266 else
267 {
268 runAccessibilityCheck(pCurrentNode);
269 updateNodeStatus(pCurrentNode);
270
271 m_pPreviousNode.reset();
273 }
274
276}
277
279{
280 auto const& pNodes = m_rDocument.GetNodes();
281 for (SwNodeOffset n(0); n < pNodes.Count(); ++n)
282 {
283 SwNode* pNode = pNodes[n];
284 if (pNode)
285 {
287 }
288 }
289
290 m_aNodes.clear();
292}
293
295{
297 return;
298
299 bool bOnlineCheckStatus
301 if (!bOnlineCheckStatus)
302 return;
303
305 m_aNodes.erase(pNode);
307 updateNodeStatus(pNode);
309}
310
312{
314 return;
315
316 bool bOnlineCheckStatus
318 if (!bOnlineCheckStatus)
319 return;
320
323}
324
325} // end sw
326
327/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void Invalidate(sal_uInt16 nId)
SfxBindings * GetBindings() const
SfxDispatcher * GetDispatcher() const
bool HasBroadcaster() const
void EndListeningAll()
bool StartListening(SvtBroadcaster &rBroadcaster)
Definition: doc.hxx:197
SwNodes & GetNodes()
Definition: doc.hxx:422
SwDocShell * GetDocShell()
Definition: doc.hxx:1370
Style of a layout element.
Definition: frmfmt.hxx:72
Base class of the Writer document model elements.
Definition: node.hxx:98
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:706
bool IsContentNode() const
Definition: node.hxx:188
bool IsTableNode() const
Definition: node.hxx:191
sw::AccessibilityCheckStatus & getAccessibilityCheckStatus()
Definition: node.hxx:334
std::vector< SwFrameFormat * > const & GetAnchoredFlys() const
Definition: node.hxx:318
AccessibilityIssueCollection & getIssueCollection()
void checkNode(SwNode *pNode)
void checkObject(SwNode *pNode, SdrObject *pObject)
void update(SwPosition const &rNewPos)
std::unique_ptr< sfx::AccessibilityIssueCollection > m_pDocumentAccessibilityIssues
std::map< SwNode *, std::unique_ptr< WeakNodeContainer > > m_aNodes
sw::AccessibilityCheck m_aAccessibilityCheck
void updateNodeStatus(SwNode *pContentNode)
void lookForPreviousNodeAndUpdate(SwPosition const &rNewPos)
std::unique_ptr< WeakNodeContainer > m_pPreviousNode
bool isAlive()
Is the node still alive or it was deleted?
SwNode * getNode()
Returns the pointer of the node or nullptr if the node got deleted.
static bool IsFuzzing()
#define FN_STAT_ACCESSIBILITY_CHECK
Definition: cmdid.h:870
EmbeddedObjectRef * pObject
sal_Int64 n
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
Dialog to specify the properties of date form field.
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
Marks a position in the document model.
Definition: pam.hxx:38
SwNode & GetNode() const
Definition: pam.hxx:81
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:78
std::unique_ptr< sfx::AccessibilityIssueCollection > pCollection
Definition: node.hxx:89