Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/editeng/AccessibleEditableTextPara.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_ACCESSIBLEEDITABLETEXTPARA_HXX
21
#define INCLUDED_EDITENG_ACCESSIBLEEDITABLETEXTPARA_HXX
22
23
#include <config_options.h>
24
#include <rtl/ustring.hxx>
25
#include <tools/gen.hxx>
26
27
#include <com/sun/star/uno/Reference.hxx>
28
#include <com/sun/star/lang/XServiceInfo.hpp>
29
#include <com/sun/star/accessibility/XAccessible.hpp>
30
#include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
31
#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp>
32
#include <com/sun/star/accessibility/XAccessibleHypertext.hpp>
33
#include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp>
34
35
#include <comphelper/accessibletexthelper.hxx>
36
#include <cppuhelper/implbase.hxx>
37
#include <editeng/editengdllapi.h>
38
#include <editeng/unoedprx.hxx>
39
#include <unotools/weakref.hxx>
40
41
class SvxViewForwarder;
42
class MapMode;
43
class SvxAccessibleTextAdapter;
44
class SvxAccessibleTextEditViewAdapter;
45
namespace accessibility { class AccessibleImageBullet; }
46
47
namespace accessibility
48
{
49
50
class AccessibleParaManager;
51
52
/** This class implements the actual text paragraphs for the EditEngine/Outliner UAA
53
 */
54
class UNLESS_MERGELIBS(EDITENG_DLLPUBLIC) AccessibleEditableTextPara final
55
    : public cppu::ImplInheritanceHelper<
56
          comphelper::OAccessible, css::accessibility::XAccessibleEditableText,
57
          css::accessibility::XAccessibleTextAttributes, css::accessibility::XAccessibleHypertext,
58
          css::accessibility::XAccessibleMultiLineText>,
59
      private ::comphelper::OCommonAccessibleText
60
{
61
62
    // override OCommonAccessibleText methods
63
    virtual OUString                 implGetText() override;
64
    virtual css::lang::Locale        implGetLocale() override;
65
    virtual void                     implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) override;
66
    virtual void                     implGetParagraphBoundary( const OUString& rtext, css::i18n::Boundary& rBoundary, sal_Int32 nIndex ) override;
67
    virtual void                     implGetLineBoundary( const OUString& rtext, css::i18n::Boundary& rBoundary, sal_Int32 nIndex ) override;
68
69
public:
70
    /// Create accessible object for given parent
71
    // #i27138#
72
    // - add parameter <_pParaManager> (default value NULL)
73
    //   This has to be the instance of <AccessibleParaManager>, which
74
    //   created and manages this accessible paragraph.
75
    AccessibleEditableTextPara ( css::uno::Reference< css::accessibility::XAccessible > xParent,
76
                                 const AccessibleParaManager* _pParaManager = nullptr );
77
78
    // XAccessibleContext
79
    virtual sal_Int64 SAL_CALL getAccessibleChildCount() override;
80
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int64 i ) override;
81
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override;
82
    virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override;
83
    virtual sal_Int16 SAL_CALL getAccessibleRole() override;
84
    virtual OUString SAL_CALL getAccessibleDescription() override;
85
    virtual OUString SAL_CALL getAccessibleName() override;
86
    virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() override;
87
    virtual sal_Int64 SAL_CALL getAccessibleStateSet() override;
88
    virtual css::lang::Locale SAL_CALL getLocale() override;
89
90
    // OAccessible
91
    virtual css::awt::Rectangle implGetBounds() override;
92
93
    // XAccessibleComponent
94
    virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override;
95
    virtual void SAL_CALL grabFocus(  ) override;
96
    virtual sal_Int32 SAL_CALL getForeground(  ) override;
97
    virtual sal_Int32 SAL_CALL getBackground(  ) override;
98
99
    // XAccessibleText (this comes implicitly inherited by XAccessibleEditableText AND by XAccessibleMultiLineText)
100
    virtual sal_Int32 SAL_CALL getCaretPosition() override;
101
    virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override;
102
    virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override;
103
    virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override;
104
    virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override;
105
    virtual sal_Int32 SAL_CALL getCharacterCount() override;
106
    virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override;
107
    virtual OUString SAL_CALL getSelectedText() override;
108
    virtual sal_Int32 SAL_CALL getSelectionStart() override;
109
    virtual sal_Int32 SAL_CALL getSelectionEnd() override;
110
    virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override;
111
    virtual OUString SAL_CALL getText() override;
112
    virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override;
113
    /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine)
114
    virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override;
115
    /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine)
116
    virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override;
117
    /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine)
118
    virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override;
119
    virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override;
120
    virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override;
121
122
    // XAccessibleEditableText
123
    virtual sal_Bool SAL_CALL cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override;
124
    virtual sal_Bool SAL_CALL pasteText( sal_Int32 nIndex ) override;
125
    virtual sal_Bool SAL_CALL deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override;
126
    virtual sal_Bool SAL_CALL insertText( const OUString& sText, sal_Int32 nIndex ) override;
127
    virtual sal_Bool SAL_CALL replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const OUString& sReplacement ) override;
128
    virtual sal_Bool SAL_CALL setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const css::uno::Sequence< css::beans::PropertyValue >& aAttributeSet ) override;
129
    virtual sal_Bool SAL_CALL setText( const OUString& sText ) override;
130
131
    // XAccessibleTextAttributes
132
    virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getDefaultAttributes( const css::uno::Sequence< OUString >& RequestedAttributes ) override;
133
    virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getRunAttributes( ::sal_Int32 Index, const css::uno::Sequence< OUString >& RequestedAttributes ) override;
134
135
    // XAccessibleHypertext
136
    virtual ::sal_Int32 SAL_CALL getHyperLinkCount(  ) override;
137
    virtual css::uno::Reference< css::accessibility::XAccessibleHyperlink > SAL_CALL getHyperLink( ::sal_Int32 nLinkIndex ) override;
138
    virtual ::sal_Int32 SAL_CALL getHyperLinkIndex( ::sal_Int32 nCharIndex ) override;
139
140
    // XAccessibleMultiLineText
141
    virtual ::sal_Int32 SAL_CALL getLineNumberAtIndex( ::sal_Int32 nIndex ) override;
142
    virtual css::accessibility::TextSegment SAL_CALL getTextAtLineNumber( ::sal_Int32 nLineNo ) override;
143
    virtual css::accessibility::TextSegment SAL_CALL getTextAtLineWithCaret(  ) override;
144
    virtual ::sal_Int32 SAL_CALL getNumberOfLineWithCaret(  ) override;
145
146
    /** Set the current index in the accessibility parent
147
148
        @attention This method does not lock the SolarMutex,
149
        leaving that to the calling code. This is because only
150
        there potential deadlock situations can be resolved. Thus,
151
        make sure SolarMutex is locked when calling this.
152
     */
153
    void SetIndexInParent( sal_Int32 nIndex );
154
155
    /** Get the current index in the accessibility parent
156
157
        @attention This method does not lock the SolarMutex,
158
        leaving that to the calling code. This is because only
159
        there potential deadlock situations can be resolved. Thus,
160
        make sure SolarMutex is locked when calling this.
161
     */
162
0
    sal_Int32 GetIndexInParent() const { return mnIndexInParent; }
163
164
    /** Set the current paragraph number
165
166
        @attention This method does not lock the SolarMutex,
167
        leaving that to the calling code. This is because only
168
        there potential deadlock situations can be resolved. Thus,
169
        make sure SolarMutex is locked when calling this.
170
     */
171
    void SetParagraphIndex( sal_Int32 nIndex );
172
173
    /** Query the current paragraph number (0 - nParas-1)
174
175
        @attention This method does not lock the SolarMutex,
176
        leaving that to the calling code. This is because only
177
        there potential deadlock situations can be resolved. Thus,
178
        make sure SolarMutex is locked when calling this.
179
     */
180
0
    sal_Int32 GetParagraphIndex() const { return mnParagraphIndex; }
181
182
    /** Set the edit engine offset
183
184
        @attention This method does not lock the SolarMutex,
185
        leaving that to the calling code. This is because only
186
        there potential deadlock situations can be resolved. Thus,
187
        make sure SolarMutex is locked when calling this.
188
     */
189
    void SetEEOffset( const Point& rOffset );
190
191
    /** Set the EditEngine offset
192
193
        @attention This method does not lock the SolarMutex,
194
        leaving that to the calling code. This is because only
195
        there potential deadlock situations can be resolved. Thus,
196
        make sure SolarMutex is locked when calling this.
197
     */
198
    void SetEditSource( SvxEditSourceAdapter* pEditSource );
199
200
    void SAL_CALL dispose() override;
201
202
    /// Calls all Listener objects to tell them the change. Don't hold locks when calling this!
203
    void FireEvent(const sal_Int16 nEventId, const css::uno::Any& rNewValue = css::uno::Any(), const css::uno::Any& rOldValue = css::uno::Any());
204
205
    /// Sets the given state on the internal state set and fires STATE_CHANGE event. Don't hold locks when calling this!
206
    void SetState( const sal_Int64 nStateId );
207
    /// Unsets the given state on the internal state set and fires STATE_CHANGE event. Don't hold locks when calling this!
208
    void UnSetState( const sal_Int64 nStateId );
209
210
    static tools::Rectangle LogicToPixel( const tools::Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder const & rForwarder );
211
212
    SvxEditSourceAdapter& GetEditSource() const;
213
214
    /** Query the SvxTextForwarder for EditEngine access.
215
216
        @attention This method does not lock the SolarMutex,
217
        leaving that to the calling code. This is because only
218
        there potential deadlock situations can be resolved. Thus,
219
        make sure SolarMutex is locked when calling this.
220
     */
221
    SvxAccessibleTextAdapter&   GetTextForwarder() const;
222
223
    /** Query the SvxViewForwarder for EditEngine access.
224
225
        @attention This method does not lock the SolarMutex,
226
        leaving that to the calling code. This is because only
227
        there potential deadlock situations can be resolved. Thus,
228
        make sure SolarMutex is locked when calling this.
229
     */
230
    SvxViewForwarder&   GetViewForwarder() const;
231
232
    /** Query whether a GetEditViewForwarder( sal_False ) will return a forwarder
233
234
        @attention This method does not lock the SolarMutex,
235
        leaving that to the calling code. This is because only
236
        there potential deadlock situations can be resolved. Thus,
237
        make sure SolarMutex is locked when calling this.
238
     */
239
    bool    HaveEditView() const;
240
241
    /** Query the SvxEditViewForwarder for EditEngine access.
242
243
        @attention This method does not lock the SolarMutex,
244
        leaving that to the calling code. This is because only
245
        there potential deadlock situations can be resolved. Thus,
246
        make sure SolarMutex is locked when calling this.
247
     */
248
    SvxAccessibleTextEditViewAdapter& GetEditViewForwarder( bool bCreate = false ) const;
249
250
    /** Send a TEXT_CHANGED event for this paragraph
251
252
        This method internally caters for calculating text
253
        differences, and sends the appropriate Anys in the
254
        Accessibility::TEXT_CHANGED event
255
     */
256
    void TextChanged();
257
258
private:
259
    AccessibleEditableTextPara( const AccessibleEditableTextPara& ) = delete;
260
    AccessibleEditableTextPara& operator= ( const AccessibleEditableTextPara& ) = delete;
261
262
    /** Calculate character range of similar attributes
263
264
        @param nStartIndex
265
        Therein, the start of the character range with the same attributes is returned
266
267
        @param nEndIndex
268
        Therein, the end (exclusively) of the character range with the same attributes is returned
269
270
        @param nIndex
271
        The character index at where to look for similar character attributes
272
273
        @return false, if the method was not able to determine the range
274
     */
275
    bool GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nIndex );
276
277
    /// Do we have children? This is the case for image bullets
278
    bool HaveChildren();
279
280
    /// If there is a bullet, return it's text length, otherwise return 0
281
    sal_Int32 GetBulletTextLength() const;
282
283
0
    const Point& GetEEOffset() const { return maEEOffset; }
284
285
    // Get text from forwarder
286
    OUString GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex );
287
    sal_Int32 GetTextLen() const;
288
289
    /** Get the current selection of this paragraph
290
291
        @return sal_False, if nothing in this paragraph is selected
292
     */
293
    bool GetSelection(sal_Int32& nStartPos, sal_Int32& nEndPos );
294
295
    /** create selection from Accessible selection.
296
297
    */
298
    ESelection  MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex );
299
    ESelection  MakeSelection( sal_Int32 nEEIndex );
300
    ESelection  MakeCursor( sal_Int32 nEEIndex );
301
302
    // check whether index value is within permitted range
303
304
    /// Check whether 0<=nIndex<=n-1
305
    void CheckIndex( sal_Int32 nIndex );
306
    /// Check whether 0<=nIndex<=n
307
    void CheckPosition( sal_Int32 nIndex );
308
    /// Check whether 0<=nStart<=n and 0<=nEnd<=n
309
    void CheckRange( sal_Int32 nStart, sal_Int32 nEnd );
310
311
    void _correctValues( css::uno::Sequence< css::beans::PropertyValue >& rValues );
312
    sal_Int32 SkipField(sal_Int32 nIndex, bool bForward);
313
    // get overlapped field, extend return string. Only extend forward for now
314
    void ExtendByField( css::accessibility::TextSegment& Segment );
315
    OUString GetFieldTypeNameAtIndex(sal_Int32 nIndex);
316
    // the paragraph index in the edit engine (guarded by solar mutex)
317
    sal_Int32   mnParagraphIndex;
318
319
    // our current index in the parent (guarded by solar mutex)
320
    sal_Int32   mnIndexInParent;
321
322
    // the current edit source (guarded by solar mutex)
323
    SvxEditSourceAdapter* mpEditSource;
324
325
    // the possible child (for image bullets, guarded by solar mutex)
326
    unotools::WeakReference<AccessibleImageBullet> maImageBullet;
327
328
    // the last string used for an Accessibility::TEXT_CHANGED event (guarded by solar mutex)
329
    OUString maLastTextString;
330
331
    // the offset of the underlying EditEngine from the shape/cell (guarded by solar mutex)
332
    Point maEEOffset;
333
334
    // the current state set (updated from SetState/UnSetState and guarded by solar mutex)
335
    sal_Int64 mnStateSet;
336
337
    /// The shape we're the accessible for (unguarded)
338
    css::uno::Reference< css::accessibility::XAccessible > mxParent;
339
340
private:
341
    // Text paragraphs should provide FLOWS_TO and FLOWS_FROM relations (#i27138#)
342
    // the paragraph manager, which created this instance - is NULL, if
343
    // instance isn't created by AccessibleParaManager.
344
    // Needed for method <getAccessibleRelationSet()> to retrieve predecessor
345
    // paragraph and the successor paragraph.
346
    const AccessibleParaManager* mpParaManager;
347
};
348
349
} // end of namespace accessibility
350
351
#endif
352
353
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */