summaryrefslogtreecommitdiff
path: root/sw/inc/accmap.hxx
blob: 975c01f559b94dcd0d21160a651ce407887084d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_SW_INC_ACCMAP_HXX
#define INCLUDED_SW_INC_ACCMAP_HXX

#include <cppuhelper/weakref.hxx>
#include <com/sun/star/accessibility/XAccessible.hpp>
#include <rtl/ref.hxx>
#include <osl/mutex.hxx>
#include <svx/IAccessibleViewForwarder.hxx>
#include <svx/IAccessibleParent.hxx>

#include <svx/AccessibleControlShape.hxx>
#include <o3tl/typed_flags_set.hxx>

#include <list>
#include <vector>
#include <memory>
#include <set>

class SwAccessibleParagraph;
class SwViewShell;
namespace tools { class Rectangle; }
class SwFrame;
class SwTextFrame;
class SwPageFrame;
class SwAccessibleContext;
class SwAccessibleContextMap_Impl;
class SwAccessibleEventList_Impl;
class SwAccessibleEventMap_Impl;
class SdrObject;
namespace accessibility { class AccessibleShape; }
class SwAccessibleShapeMap_Impl;
struct SwAccessibleEvent_Impl;
class SwAccessibleSelectedParas_Impl;
class SwRect;
class MapMode;
class SwAccPreviewData;
class SwFEShell;
class Fraction;
struct PreviewPage;
namespace vcl { class Window; }

// The shape list is filled if an accessible shape is destroyed. It
// simply keeps a reference to the accessible shape's XShape. These
// references are destroyed within the EndAction when firing events.
// There are two reason for this. First of all, a new accessible shape
// for the XShape might be created soon. It's then cheaper if the XShape
// still exists. The other reason are situations where an accessible shape
// is destroyed within an SwFrameFormat::Modify. In this case, destroying
// the XShape at the same time (indirectly by destroying the accessible
// shape) leads to an assert, because a client of the Modify is destroyed
// within a Modify call.
using SwShapeList_Impl = std::list<css::uno::Reference<css::drawing::XShape>>;

enum class AccessibleStates
{
    NONE                   = 0x0000,
    // real states for events
    EDITABLE               = 0x0001,
    OPAQUE                 = 0x0002,
    // pseudo states for events
    TEXT_ATTRIBUTE_CHANGED = 0x0200,
    TEXT_SELECTION_CHANGED = 0x0100,
    CARET                  = 0x0080,
    RELATION_FROM          = 0x0040,
    RELATION_TO            = 0x0020,
};
namespace o3tl
{
    template<> struct typed_flags<AccessibleStates> : is_typed_flags<AccessibleStates, 0x3e3> {};
}

class SwAccessibleMap : public ::accessibility::IAccessibleViewForwarder,
                        public ::accessibility::IAccessibleParent
                , public std::enable_shared_from_this<SwAccessibleMap>
{
    mutable ::osl::Mutex maMutex;
    ::osl::Mutex maEventMutex;
    SwAccessibleContextMap_Impl *mpFrameMap;
    SwAccessibleShapeMap_Impl *mpShapeMap;
    SwShapeList_Impl *mpShapes;
    SwAccessibleEventList_Impl *mpEvents;
    SwAccessibleEventMap_Impl *mpEventMap;
    // #i27301 data structure to keep information about
    // accessible paragraph, which have a selection.
    SwAccessibleSelectedParas_Impl* mpSelectedParas;
    SwViewShell *mpVSh;
    /// for page preview: store preview data, VisArea, and mapping of
    /// preview-to-display coordinates
    SwAccPreviewData* mpPreview;

    css::uno::WeakReference < css::accessibility::XAccessible > mxCursorContext;

    bool mbShapeSelected;

    void FireEvent( const SwAccessibleEvent_Impl& rEvent );

    void AppendEvent( const SwAccessibleEvent_Impl& rEvent );

    void InvalidateCursorPosition( const css::uno::Reference<css::accessibility::XAccessible>& rAcc );
    void DoInvalidateShapeSelection(bool bInvalidateFocusMode = false);

    void InvalidateShapeSelection();

    //mpSelectedFrameMap contains the old selected objects.
    SwAccessibleContextMap_Impl *mpSeletedFrameMap;

    OUString maDocName;

    //InvalidateShapeInParaSelection() method is responsible for the updating the selected states of the objects.
    void InvalidateShapeInParaSelection();

    void InvalidateRelationSet_( const SwFrame* pFrame, bool bFrom );

    css::uno::Reference<css::accessibility::XAccessible>
            GetDocumentView_( bool bPagePreview );

    /** method to build up a new data structure of the accessible paragraphs,
        which have a selection

        Important note: method has to used inside a mutual exclusive section

        @author OD
    */
    SwAccessibleSelectedParas_Impl* BuildSelectedParas();

public:

    SwAccessibleMap( SwViewShell *pSh );
    virtual ~SwAccessibleMap() override;

    css::uno::Reference<css::accessibility::XAccessible> GetDocumentView();

    css::uno::Reference<css::accessibility::XAccessible> GetDocumentPreview(
                            const std::vector<PreviewPage*>& _rPreviewPages,
                            const Fraction&  _rScale,
                            const SwPageFrame* _pSelectedPageFrame,
                            const Size&      _rPreviewWinSize );

    ::rtl::Reference < SwAccessibleContext > GetContextImpl(
                                                 const SwFrame *pFrame,
                                                bool bCreate = true );
    css::uno::Reference<css::accessibility::XAccessible> GetContext(
                                                 const SwFrame *pFrame,
                                                bool bCreate = true );

    ::rtl::Reference < ::accessibility::AccessibleShape > GetContextImpl(
                                        const SdrObject *pObj,
                                        SwAccessibleContext *pParentImpl,
                                        bool bCreate = true );
    css::uno::Reference<css::accessibility::XAccessible> GetContext(
                                        const SdrObject *pObj,
                                        SwAccessibleContext *pParentImpl,
                                        bool bCreate = true );

    SwViewShell* GetShell() const
    {
        return mpVSh;
    }
    static bool IsInSameLevel(const SdrObject* pObj, const SwFEShell* pFESh);
    void AddShapeContext(const SdrObject *pObj,
                             css::uno::Reference < css::accessibility::XAccessible > const & xAccShape);

    void AddGroupContext(const SdrObject *pParentObj,
                    css::uno::Reference < css::accessibility::XAccessible > const & xAccParent);
    void RemoveGroupContext(const SdrObject *pParentObj);

    const SwRect& GetVisArea() const;

    /** get size of a dedicated preview page

        @author OD

        @param _nPreviewPageNum
        input parameter - physical page number of page visible in the page preview

        @return an object of class <Size>
    */
    Size GetPreviewPageSize( sal_uInt16 _nPreviewPageNum ) const;

    void RemoveContext( const SwFrame *pFrame );
    void RemoveContext( const SdrObject *pObj );

    // Dispose frame and its children if bRecursive is set
    void A11yDispose( const SwFrame* pFrame,
                      const SdrObject* pObj,
                      vcl::Window* pWindow,
                      bool bRecursive = false,
                      bool bCanSkipInvisible = true );

    void InvalidatePosOrSize( const SwFrame* pFrame,
                              const SdrObject* pObj,
                              vcl::Window* pWindow,
                              const SwRect& rOldFrame );

    void InvalidateContent( const SwFrame *pFrame );

    void InvalidateAttr( const SwTextFrame& rTextFrame );

    void InvalidateCursorPosition( const SwFrame *pFrame );
    void InvalidateFocus();
    void SetCursorContext(
        const ::rtl::Reference < SwAccessibleContext >& rCursorContext );

    // Invalidate state of whole tree. If an action is open, this call
    // is processed when the last action ends.
    void InvalidateEditableStates( const SwFrame* _pFrame );

    void InvalidateRelationSet( const SwFrame* pMaster, const SwFrame* pFollow );

    /** invalidation CONTENT_FLOWS_FROM/_TO relation of a paragraph

        @author OD

        @param _rTextFrame
        input parameter - reference to paragraph, whose CONTENT_FLOWS_FROM/_TO
        has to be invalidated.

        @param _bFrom
        input parameter - boolean indicating, if relation CONTENT_FLOWS_FROM
        (value <true>) or CONTENT_FLOWS_TO (value <false>) has to be invalidated.
    */
    void InvalidateParaFlowRelation( const SwTextFrame& _rTextFrame,
                                     const bool _bFrom );

    /** invalidation of text selection of a paragraph

        @author OD
    */
    void InvalidateParaTextSelection( const SwTextFrame& _rTextFrame );

    /** invalidation of text selection of all paragraphs

        @author OD
    */
    void InvalidateTextSelectionOfAllParas();

    sal_Int32 GetChildIndex( const SwFrame& rParentFrame,
                             vcl::Window& rChild ) const;

    // update preview data (and fire events if necessary)
    void UpdatePreview( const std::vector<PreviewPage*>& _rPreviewPages,
                        const Fraction&  _rScale,
                        const SwPageFrame* _pSelectedPageFrame,
                        const Size&      _rPreviewWinSize );

    void InvalidatePreviewSelection( sal_uInt16 nSelPage );
    bool IsPageSelected( const SwPageFrame *pPageFrame ) const;

    void FireEvents();

    const OUString& GetDocName() const { return maDocName; }

    // IAccessibleViewForwarder

    virtual tools::Rectangle GetVisibleArea() const override;
    virtual Point LogicToPixel (const Point& rPoint) const override;
    virtual Size LogicToPixel (const Size& rSize) const override;

    // IAccessibleParent
    virtual bool ReplaceChild (
        ::accessibility::AccessibleShape* pCurrentChild,
        const css::uno::Reference< css::drawing::XShape >& _rxShape,
        const long _nIndex,
        const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo
    ) override;
    virtual ::accessibility::AccessibleControlShape* GetAccControlShapeFromModel
        (css::beans::XPropertySet* pSet) override;
    virtual css::uno::Reference< css::accessibility::XAccessible >   GetAccessibleCaption (
        const css::uno::Reference< css::drawing::XShape > & xShape) override;

    // additional Core/Pixel conversions for internal use; also works
    // for preview
    Point PixelToCore (const Point& rPoint) const;
    tools::Rectangle CoreToPixel (const tools::Rectangle& rRect) const;

private:
    /** get mapping mode for LogicToPixel and PixelToLogic conversions

        Replacement method <PreviewAdjust(..)> by new method <GetMapMode>.
        Method returns mapping mode of current output device and adjusts it,
        if the shell is in page/print preview.
        Necessary, because <PreviewAdjust(..)> changes mapping mode at current
        output device for mapping logic document positions to page preview window
        positions and vice versa and doesn't take care to recover its changes.

        @author OD

        @param _rPoint
        input parameter - constant reference to point to determine the mapping
        mode adjustments for page/print preview.

        @param _orMapMode
        output parameter - reference to the mapping mode, which is determined
        by the method
    */
    void GetMapMode( const Point& _rPoint,
                     MapMode&     _orMapMode ) const;
public:
    virtual bool IsDocumentSelAll() override;

    const css::uno::WeakReference < css::accessibility::XAccessible >&
        GetCursorContext() const { return mxCursorContext; }

    //Para Container for InvalidateCursorPosition
    typedef std::set< SwAccessibleParagraph* >  SET_PARA;
    SET_PARA m_setParaAdd;
    SET_PARA m_setParaRemove;
};
#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */