Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/inc/accmap.hxx
Line
Count
Source
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
#pragma once
20
21
#include <cppuhelper/weakref.hxx>
22
#include <rtl/ref.hxx>
23
#include <osl/mutex.hxx>
24
#include <svx/IAccessibleViewForwarder.hxx>
25
#include <svx/IAccessibleParent.hxx>
26
27
#include <svx/AccessibleControlShape.hxx>
28
#include <o3tl/typed_flags_set.hxx>
29
#include <unotools/weakref.hxx>
30
#include <vector>
31
#include <memory>
32
#include <o3tl/sorted_vector.hxx>
33
34
class SwAccessibleParagraph;
35
class SwViewShell;
36
class SwFrame;
37
class SwTextFrame;
38
class SwPageFrame;
39
class SwAccessibleContext;
40
class SwAccessibleEventList_Impl;
41
class SwAccessibleEventMap_Impl;
42
class SdrObject;
43
namespace accessibility { class AccessibleShape; }
44
class SwAccessibleShapeMap_Impl;
45
struct SwAccessibleEvent_Impl;
46
class SwAccessibleSelectedParas_Impl;
47
class SwRect;
48
class MapMode;
49
class SwAccPreviewData;
50
class SwFEShell;
51
struct PreviewPage;
52
namespace vcl { class Window; }
53
namespace com::sun::star::accessibility { class XAccessible; }
54
55
enum class AccessibleStates
56
{
57
    NONE                   = 0x0000,
58
    // real states for events
59
    EDITABLE               = 0x0001,
60
    OPAQUE                 = 0x0002,
61
    // pseudo states for events
62
    TEXT_ATTRIBUTE_CHANGED = 0x0200,
63
    TEXT_SELECTION_CHANGED = 0x0100,
64
    CARET                  = 0x0080,
65
    RELATION_FROM          = 0x0040,
66
    RELATION_TO            = 0x0020,
67
};
68
namespace o3tl
69
{
70
    template<> struct typed_flags<AccessibleStates> : is_typed_flags<AccessibleStates, 0x3e3> {};
71
}
72
73
using SwAccessibleContextMap
74
    = std::unordered_map<const SwFrame*, unotools::WeakReference<SwAccessibleContext>>;
75
76
class SwAccessibleMap final : public ::accessibility::IAccessibleViewForwarder,
77
                        public ::accessibility::IAccessibleParent
78
                , public std::enable_shared_from_this<SwAccessibleMap>
79
{
80
    ::osl::Mutex maEventMutex;
81
    SwAccessibleContextMap maFrameMap;
82
    std::unique_ptr<SwAccessibleShapeMap_Impl> mpShapeMap;
83
84
    // The shape list is filled if an accessible shape is destroyed. It
85
    // simply keeps a reference to the accessible shape's XShape. These
86
    // references are destroyed within the EndAction when firing events.
87
    // There are two reason for this. First of all, a new accessible shape
88
    // for the XShape might be created soon. It's then cheaper if the XShape
89
    // still exists. The other reason are situations where an accessible shape
90
    // is destroyed within an SwFrameFormat::SwClientNotify. In this case, destroying
91
    // the XShape at the same time (indirectly by destroying the accessible
92
    // shape) leads to an assert, because a client of the Modify is destroyed
93
    // within a Modify call.
94
    std::vector<css::uno::Reference<css::drawing::XShape>> mvShapes;
95
96
    std::unique_ptr<SwAccessibleEventList_Impl> mpEvents;
97
    std::unique_ptr<SwAccessibleEventMap_Impl> mpEventMap;
98
99
    // Para Container for InvalidateCursorPosition
100
    o3tl::sorted_vector<SwAccessibleParagraph*> m_setParaAdd;
101
    o3tl::sorted_vector<SwAccessibleParagraph*> m_setParaRemove;
102
103
    // #i27301 data structure to keep information about
104
    // accessible paragraph, which have a selection.
105
    std::unique_ptr<SwAccessibleSelectedParas_Impl> mpSelectedParas;
106
    SwViewShell& m_rViewShell;
107
    /// for page preview: store preview data, VisArea, and mapping of
108
    /// preview-to-display coordinates
109
    std::unique_ptr<SwAccPreviewData> mpPreview;
110
111
    unotools::WeakReference< SwAccessibleContext > mxCursorContext;
112
113
    bool mbShapeSelected;
114
115
    void FireEvent( const SwAccessibleEvent_Impl& rEvent );
116
117
    void AppendEvent( const SwAccessibleEvent_Impl& rEvent );
118
119
    void InvalidateCursorPosition(const rtl::Reference<SwAccessibleContext>& rxAcc);
120
    void DoInvalidateShapeSelection(bool bInvalidateFocusMode = false);
121
122
    void InvalidateShapeSelection();
123
124
    //maSelectedFrameMap contains the old selected objects.
125
    SwAccessibleContextMap maSelectedFrameMap;
126
127
    OUString maDocName;
128
129
    //InvalidateShapeInParaSelection() method is responsible for the updating the selected states of the objects.
130
    void InvalidateShapeInParaSelection();
131
132
    void InvalidateRelationSet_(const SwFrame& rFrame, bool bFrom);
133
134
    rtl::Reference<SwAccessibleContext> GetDocumentView_(bool bPagePreview);
135
136
    /** method to build up a new data structure of the accessible paragraphs,
137
        which have a selection
138
139
        Important note: method has to used inside a mutual exclusive section
140
    */
141
    std::unique_ptr<SwAccessibleSelectedParas_Impl> BuildSelectedParas();
142
143
public:
144
145
    SwAccessibleMap(SwViewShell& rViewShell);
146
    virtual ~SwAccessibleMap() override;
147
148
    rtl::Reference<comphelper::OAccessible> GetDocumentView();
149
150
    rtl::Reference<comphelper::OAccessible>
151
    GetDocumentPreview(const std::vector<std::unique_ptr<PreviewPage>>& _rPreviewPages,
152
                       double _fScale, const SwPageFrame* _pSelectedPageFrame,
153
                       const Size& _rPreviewWinSize);
154
155
    ::rtl::Reference < SwAccessibleContext > GetContextImpl(
156
                                                 const SwFrame *pFrame,
157
                                                bool bCreate = true );
158
    css::uno::Reference<css::accessibility::XAccessible> GetContext(
159
                                                 const SwFrame *pFrame,
160
                                                bool bCreate = true );
161
162
    ::rtl::Reference < ::accessibility::AccessibleShape > GetContextImpl(
163
                                        const SdrObject *pObj,
164
                                        SwAccessibleContext *pParentImpl,
165
                                        bool bCreate = true );
166
    css::uno::Reference<css::accessibility::XAccessible> GetContext(
167
                                        const SdrObject *pObj,
168
                                        SwAccessibleContext *pParentImpl,
169
                                        bool bCreate = true );
170
171
    SwViewShell& GetShell() const
172
0
    {
173
0
        return m_rViewShell;
174
0
    }
175
    static bool IsInSameLevel(const SdrObject* pObj, const SwFEShell* pFESh);
176
    void AddShapeContext(const SdrObject *pObj,
177
                             rtl::Reference < ::accessibility::AccessibleShape > const & xAccShape);
178
179
    void AddGroupContext(const SdrObject *pParentObj,
180
                    css::uno::Reference < css::accessibility::XAccessible > const & xAccParent);
181
    void RemoveGroupContext(const SdrObject *pParentObj);
182
183
    const SwRect& GetVisArea() const;
184
185
    /** get size of a dedicated preview page
186
187
        @param _nPreviewPageNum
188
        input parameter - physical page number of page visible in the page preview
189
190
        @return an object of class <Size>
191
    */
192
    Size GetPreviewPageSize( sal_uInt16 _nPreviewPageNum ) const;
193
194
    void RemoveContext( const SwFrame *pFrame );
195
    void RemoveContext( const SdrObject *pObj );
196
197
    // Dispose frame and its children if bRecursive is set
198
    void A11yDispose( const SwFrame* pFrame,
199
                      const SdrObject* pObj,
200
                      vcl::Window* pWindow,
201
                      bool bRecursive = false,
202
                      bool bCanSkipInvisible = true );
203
204
    void InvalidatePosOrSize( const SwFrame* pFrame,
205
                              const SdrObject* pObj,
206
                              vcl::Window* pWindow,
207
                              const SwRect& rOldFrame );
208
209
    void InvalidateContent( const SwFrame *pFrame );
210
211
    void InvalidateAttr( const SwTextFrame& rTextFrame );
212
213
    void InvalidateCursorPosition( const SwFrame *pFrame );
214
    void InvalidateFocus();
215
    void SetCursorContext(
216
        const ::rtl::Reference < SwAccessibleContext >& rCursorContext );
217
218
    // Invalidate state of whole tree. If an action is open, this call
219
    // is processed when the last action ends.
220
    void InvalidateEditableStates( const SwFrame* _pFrame );
221
222
    void InvalidateRelationSet(const SwFrame& rMaster, const SwFrame& rFollow);
223
224
    /** invalidation CONTENT_FLOWS_FROM/_TO relation of a paragraph
225
226
        @param _rTextFrame
227
        input parameter - reference to paragraph, whose CONTENT_FLOWS_FROM/_TO
228
        has to be invalidated.
229
230
        @param _bFrom
231
        input parameter - boolean indicating, if relation CONTENT_FLOWS_FROM
232
        (value <true>) or CONTENT_FLOWS_TO (value <false>) has to be invalidated.
233
    */
234
    void InvalidateParaFlowRelation( const SwTextFrame& _rTextFrame,
235
                                     const bool _bFrom );
236
237
    /** invalidation of text selection of a paragraph */
238
    void InvalidateParaTextSelection( const SwTextFrame& _rTextFrame );
239
240
    /** invalidation of text selection of all paragraphs */
241
    void InvalidateTextSelectionOfAllParas();
242
243
    sal_Int32 GetChildIndex( const SwFrame& rParentFrame,
244
                             vcl::Window& rChild ) const;
245
246
    // update preview data (and fire events if necessary)
247
    void UpdatePreview( const std::vector<std::unique_ptr<PreviewPage>>& _rPreviewPages,
248
                        double _fScale,
249
                        const SwPageFrame* _pSelectedPageFrame,
250
                        const Size&      _rPreviewWinSize );
251
252
    void InvalidatePreviewSelection( sal_uInt16 nSelPage );
253
    bool IsPageSelected( const SwPageFrame *pPageFrame ) const;
254
255
    void FireEvents();
256
257
0
    const OUString& GetDocName() const { return maDocName; }
258
259
    // IAccessibleViewForwarder
260
261
    virtual tools::Rectangle GetVisibleArea() const override;
262
    virtual Point LogicToPixel (const Point& rPoint) const override;
263
    virtual Size LogicToPixel (const Size& rSize) const override;
264
265
    // IAccessibleParent
266
    virtual bool ReplaceChild (
267
        ::accessibility::AccessibleShape* pCurrentChild,
268
        const css::uno::Reference< css::drawing::XShape >& _rxShape,
269
        const tools::Long _nIndex,
270
        const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo
271
    ) override;
272
    virtual ::accessibility::AccessibleControlShape* GetAccControlShapeFromModel
273
        (css::beans::XPropertySet* pSet) override;
274
    virtual css::accessibility::XAccessible*   GetAccessibleCaption (
275
        const css::uno::Reference< css::drawing::XShape > & xShape) override;
276
277
    // additional Core/Pixel conversions for internal use; also works
278
    // for preview
279
    Point PixelToCore (const Point& rPoint) const;
280
    tools::Rectangle CoreToPixel (const SwRect& rRect) const;
281
282
    // is there a known accessibility impl cached for the frame
283
    bool Contains(const SwFrame *pFrame) const;
284
285
private:
286
    /** get mapping mode for LogicToPixel and PixelToLogic conversions
287
288
        Replacement method <PreviewAdjust(..)> by new method <GetMapMode>.
289
        Method returns mapping mode of current output device and adjusts it,
290
        if the shell is in page/print preview.
291
        Necessary, because <PreviewAdjust(..)> changes mapping mode at current
292
        output device for mapping logic document positions to page preview window
293
        positions and vice versa and doesn't take care to recover its changes.
294
295
        @param _rPoint
296
        input parameter - constant reference to point to determine the mapping
297
        mode adjustments for page/print preview.
298
299
        @return mapping mode, which is determined by the method
300
    */
301
    MapMode GetMapMode(const Point& _rPoint) const;
302
public:
303
    virtual bool IsDocumentSelAll() override;
304
};
305
306
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */