Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/editeng/AccessibleStaticTextBase.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
20
#ifndef INCLUDED_EDITENG_ACCESSIBLESTATICTEXTBASE_HXX
21
#define INCLUDED_EDITENG_ACCESSIBLESTATICTEXTBASE_HXX
22
23
#include <memory>
24
#include <tools/gen.hxx>
25
#include <cppuhelper/implbase2.hxx>
26
#include <com/sun/star/uno/Reference.hxx>
27
#include <com/sun/star/accessibility/XAccessibleText.hpp>
28
#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp>
29
#include <com/sun/star/accessibility/TextSegment.hpp>
30
#include <editeng/AccessibleEditableTextPara.hxx>
31
#include <editeng/EPaM.hxx>
32
#include <editeng/editengdllapi.h>
33
#include <editeng/unoedprx.hxx>
34
35
namespace com::sun::star::accessibility { class XAccessible; }
36
37
class SvxEditSource;
38
39
namespace accessibility
40
{
41
42
typedef ::cppu::ImplHelper2<
43
    css::accessibility::XAccessibleText,
44
    css::accessibility::XAccessibleTextAttributes > AccessibleStaticTextBase_BASE;
45
46
/** Helper class for objects containing EditEngine/Outliner text
47
48
    This class implements the XAccessibleText interface for static
49
    text, somewhat similar to the children of the
50
    AccessibleTextHelper class. Currently, there are no children,
51
    i.e. the whole text is presented in one big chunk. This might
52
    change in the future, if a need for image bullets should
53
    arise. These, by convention, would be represented as children
54
    of the text.
55
56
    You have to implement the SvxEditSource, SvxTextForwarder,
57
    SvxViewForwarder and SvxEditViewForwarder interfaces in order
58
    to enable your object to cooperate with this
59
    class. SvxTextForwarder encapsulates the fact that text
60
    objects do not necessarily have an EditEngine at their
61
    disposal, SvxViewForwarder and SvxEditViewForwarder do the
62
    same for the document and the edit view. The three mentioned
63
    forwarder objects are not stored by the AccessibleTextHelper,
64
    but fetched every time from the SvxEditSource. So you are best
65
    off making your SvxEditSource::Get*Forwarder methods cache the
66
    current forwarder.
67
68
    As this class is intended for static (i.e. non-changing) text
69
    only, no event broadcasting is necessary. You must handle
70
    visibility by yourself, the bounding boxes returned by
71
    getCharacterBounds() are relative to your accessibility
72
    object.
73
74
    @attention All public non-UNO methods (those are the uppercase
75
    ones) must not be called with any mutex hold, except when
76
    calling from the main thread (with holds the solar mutex),
77
    unless stated otherwise. This is because they themselves might
78
    need the solar mutex in addition to the object mutex, and the
79
    ordering of the locking must be: first solar mutex, then
80
    object mutex. Furthermore, state change events might be fired
81
    internally.
82
83
    @derive Use this class as a base for objects containing static
84
    edit engine text. To avoid overwriting every interface method
85
    to intercept derived object defunc state, just set NULL as the
86
    edit source. Every interface method will then properly throw
87
    an exception.
88
*/
89
class EDITENG_DLLPUBLIC AccessibleStaticTextBase : public AccessibleStaticTextBase_BASE
90
{
91
92
public:
93
    /** Create accessible text object for given edit source
94
95
        @param pEditSource
96
        The edit source to use. Object ownership is transferred
97
        from the caller to the callee. The object listens on the
98
        SvxEditSource for object disposal, so no provisions have
99
        to be taken if the caller destroys the data (e.g. the
100
        model) contained in the given SvxEditSource.
101
102
    */
103
    explicit AccessibleStaticTextBase( ::std::unique_ptr< SvxEditSource > && pEditSource );
104
105
    virtual ~AccessibleStaticTextBase();
106
107
private:
108
    AccessibleStaticTextBase( const AccessibleStaticTextBase& ) = delete;
109
    AccessibleStaticTextBase& operator= ( const AccessibleStaticTextBase& ) = delete;
110
111
public:
112
113
    /** Set the current edit source
114
115
        @attention You are required to have the solar mutex
116
        locked, when calling this method. Thus, the method should
117
        only be called from the main office thread.
118
119
        The EditSource set here is required to broadcast out the
120
        following hints: SfxHintId::EditSourceParasMoved,
121
        SfxHintId::EditSourceSelectionChanged, SfxHintId::TextModified,
122
        SfxHintId::TextParaInserted, SfxHintId::TextParaRemoved,
123
        SfxHintId::TextHeightChanged,
124
        SfxHintId::TextViewScrolled. Otherwise, not all state changes
125
        will get noticed by the accessibility object. Further
126
        more, when the corresponding core object or the model is
127
        dying, either the edit source must be set to NULL or it
128
        has to broadcast a SfxHintId::Dying hint.
129
130
        This class does not have a dispose method, since it is not
131
        a UNO component. Nevertheless, it holds C++ references to
132
        several core objects, so you should issue a
133
        SetEditSource(::std::unique_ptr<SvxEditSource>()) in
134
        your dispose() method.
135
136
        @param pEditSource
137
        The new edit source to set. Object ownership is transferred
138
        from the caller to the callee.
139
    */
140
    void SetEditSource( ::std::unique_ptr< SvxEditSource > && pEditSource );
141
142
    /** Set offset of EditEngine from parent
143
144
        @attention You are required to have the solar mutex
145
        locked, when calling this method. Thus, the method should
146
        only be called from the main office thread.
147
148
        If the origin of the underlying EditEngine does
149
        not correspond to the upper left corner of the object
150
        using this class, you have to specify the offset.
151
152
        @param rPoint
153
        The offset in screen coordinates (i.e. pixel)
154
    */
155
    void SetOffset( const Point& rPoint );
156
157
    /** Drop all references and enter disposed state
158
159
        This method drops all references to external objects (also
160
        the event source reference set via SetEventSource()) and
161
        sets the object into the disposed state (i.e. the methods
162
        return default values or throw a uno::DisposedException
163
        exception).
164
     */
165
    void Dispose();
166
167
    // XAccessibleText interface implementation
168
    virtual sal_Int32 SAL_CALL getCaretPosition() override final;
169
    virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override final;
170
    virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override final;
171
    virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override;
172
    virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override final;
173
    virtual sal_Int32 SAL_CALL getCharacterCount() override final;
174
    virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override final;
175
    virtual OUString SAL_CALL getSelectedText() override final;
176
    virtual sal_Int32 SAL_CALL getSelectionStart() override final;
177
    virtual sal_Int32 SAL_CALL getSelectionEnd() override final;
178
    /// This will only work with a functional SvxEditViewForwarder, i.e. an EditEngine/Outliner in edit mode
179
    virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override final;
180
    virtual OUString SAL_CALL getText() override final;
181
    virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override final;
182
    /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine)
183
    virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override final;
184
    /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine)
185
    virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override final;
186
    /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine)
187
    virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override final;
188
    /// This will only work with a functional SvxEditViewForwarder, i.e. an EditEngine/Outliner in edit mode
189
    virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override final;
190
    virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override final;
191
192
    // XAccessibleTextAttributes
193
    virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getDefaultAttributes( const css::uno::Sequence< OUString >& RequestedAttributes ) override final;
194
    virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getRunAttributes( sal_Int32 Index, const css::uno::Sequence< OUString >& RequestedAttributes ) override final;
195
196
    // child-related methods from XAccessibleContext
197
    /// @throws css::uno::RuntimeException
198
    virtual sal_Int64 SAL_CALL getAccessibleChildCount();
199
    /// @throws css::lang::IndexOutOfBoundsException
200
    /// @throws css::uno::RuntimeException
201
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i );
202
203
    // child-related methods from XAccessibleComponent
204
    /// @throws css::uno::RuntimeException
205
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint );
206
207
protected:
208
    tools::Rectangle GetParagraphBoundingBox() const;
209
210
private:
211
212
    EPaM ImpCalcInternal(sal_Int32 nFlatIndex, bool bExclusive) const;
213
214
    EPaM Index2Internal(sal_Int32 nFlatIndex) const
215
0
    {
216
217
0
        return ImpCalcInternal(nFlatIndex, false);
218
0
    }
219
220
    EPaM Range2Internal(sal_Int32 nFlatIndex) const
221
0
    {
222
223
0
        return ImpCalcInternal(nFlatIndex, true);
224
0
    }
225
226
    AccessibleEditableTextPara& GetParagraph(sal_Int32 nPara) const;
227
    sal_Int32 GetParagraphCount() const;
228
229
    sal_Int32 Internal2Index(EPaM nEEIndex) const;
230
231
    void CorrectTextSegment(css::accessibility::TextSegment& aTextSegment, int nPara) const;
232
233
    bool SetSelection(sal_Int32 nStartPara, sal_Int32 nStartIndex,
234
                      sal_Int32 nEndPara, sal_Int32 nEndIndex);
235
    bool CopyText(sal_Int32 nStartPara, sal_Int32 nStartIndex,
236
                  sal_Int32 nEndPara, sal_Int32 nEndIndex);
237
238
    bool RemoveLineBreakCount(sal_Int32& rIndex);
239
240
    // implements our functionality, we're just an adapter (guarded by solar mutex)
241
    mutable rtl::Reference<AccessibleEditableTextPara> mxTextParagraph;
242
243
    // a wrapper for the text forwarders (guarded by solar mutex)
244
    mutable SvxEditSourceAdapter maEditSource;
245
246
};
247
248
} // end of namespace accessibility
249
250
#endif // INCLUDED_EDITENG_ACCESSIBLESTATICTEXTBASE_HXX
251
252
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */