Coverage Report

Created: 2025-11-16 09:57

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