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/AccessibleScrollType.hpp>
28 #include <com/sun/star/accessibility/XAccessibleText.hpp>
29 #include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp>
30 #include <com/sun/star/accessibility/TextSegment.hpp>
31 #include <editeng/editengdllapi.h>
32 
33 namespace com::sun::star::accessibility { class XAccessible; }
34 
35 class SvxEditSource;
36 
37 namespace accessibility
38 {
39 
40     class AccessibleStaticTextBase_Impl;
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 the event source
143 
144             @attention When setting a reference here, you should call
145             Dispose() when you as the owner are disposing, since until
146             then this object will hold that reference
147 
148             @param rInterface
149             The interface that should be set as the source for
150             accessibility events sent by this object.
151          */
152         void SetEventSource( const css::uno::Reference< css::accessibility::XAccessible >& rInterface );
153 
154         /** Set offset of EditEngine from parent
155 
156             @attention You are required to have the solar mutex
157             locked, when calling this method. Thus, the method should
158             only be called from the main office thread.
159 
160             If the origin of the underlying EditEngine does
161             not correspond to the upper left corner of the object
162             using this class, you have to specify the offset.
163 
164             @param rPoint
165             The offset in screen coordinates (i.e. pixel)
166         */
167         void SetOffset( const Point& rPoint );
168 
169         /** Drop all references and enter disposed state
170 
171             This method drops all references to external objects (also
172             the event source reference set via SetEventSource()) and
173             sets the object into the disposed state (i.e. the methods
174             return default values or throw a uno::DisposedException
175             exception).
176          */
177         void Dispose();
178 
179         // XAccessibleText interface implementation
180         virtual sal_Int32 SAL_CALL getCaretPosition() override;
181         virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override;
182         virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override;
183         virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override;
184         virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override;
185         virtual sal_Int32 SAL_CALL getCharacterCount() override;
186         virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override;
187         virtual OUString SAL_CALL getSelectedText() override;
188         virtual sal_Int32 SAL_CALL getSelectionStart() override;
189         virtual sal_Int32 SAL_CALL getSelectionEnd() override;
190         /// This will only work with a functional SvxEditViewForwarder, i.e. an EditEngine/Outliner in edit mode
191         virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override;
192         virtual OUString SAL_CALL getText() override;
193         virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override;
194         /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine)
195         virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override;
196         /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine)
197         virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override;
198         /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine)
199         virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override;
200         /// This will only work with a functional SvxEditViewForwarder, i.e. an EditEngine/Outliner in edit mode
201         virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override;
202         virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override;
203 
204         // XAccessibleTextAttributes
205         virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getDefaultAttributes( const css::uno::Sequence< OUString >& RequestedAttributes ) override;
206         virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getRunAttributes( sal_Int32 Index, const css::uno::Sequence< OUString >& RequestedAttributes ) override;
207 
208         // child-related methods from XAccessibleContext
209         /// @throws css::uno::RuntimeException
210         virtual sal_Int32 SAL_CALL getAccessibleChildCount();
211         /// @throws css::lang::IndexOutOfBoundsException
212         /// @throws css::uno::RuntimeException
213         virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i );
214 
215         // child-related methods from XAccessibleComponent
216         /// @throws css::uno::RuntimeException
217         virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint );
218 
219     protected:
220         tools::Rectangle GetParagraphBoundingBox() const;
221 
222     private:
223 
224         /// @dyn
225         const std::unique_ptr< AccessibleStaticTextBase_Impl > mpImpl;
226 
227     };
228 
229 } // end of namespace accessibility
230 
231 #endif // INCLUDED_EDITENG_ACCESSIBLESTATICTEXTBASE_HXX
232 
233 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
234