xref: /AOO41X/main/svx/inc/svx/AccessibleTextHelper.hxx (revision 3334a7e6acdae9820fa1a6f556bb10129a8de6b2)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _SVX_ACCESSILE_TEXT_HELPER_HXX_
25 #define _SVX_ACCESSILE_TEXT_HELPER_HXX_
26 
27 #include <memory>
28 #include <sal/types.h>
29 #include <tools/gen.hxx>
30 #include <com/sun/star/uno/Any.hxx>
31 #include <com/sun/star/uno/Reference.hxx>
32 #include <com/sun/star/accessibility/XAccessible.hpp>
33 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
34 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
35 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
36 #include "svx/svxdllapi.h"
37 
38 
39 class SvxTextForwarder;
40 class SvxViewForwarder;
41 class SvxEditSource;
42 
43 namespace accessibility
44 {
45 
46     class AccessibleTextHelper_Impl;
47 
48     /** Helper class for objects containing EditEngine/Outliner text
49 
50         This class provides the methods from the XAccessibleContext,
51         XAccessibleEventBroadcaster and XAccessibleComponent
52         interfaces, that are common to all accessible objects
53         containing an edit engine.
54 
55         The text contained in the EditEngine/Outliner is presented as
56         children of this class, namely for every text paragraph a
57         AccessibleEditableTextPara child object is generated. As this
58         class manages these children for itself, it has to send out
59         AccessibleEventId::CHILD events on your
60         behalf. Thus, you must forward every call to your
61         addEventListener()/removeEventListener() methods to the
62         AccessibleTextHelper (methods
63         AddEventListener/RemoveEventListener), otherwise none or not
64         every one of your event listener will notice child changes.
65 
66         You have to implement the SvxEditSource, SvxTextForwarder,
67         SvxViewForwarder and SvxEditViewForwarder interfaces in order
68         to enable your object to cooperate with this
69         class. SvxTextForwarder encapsulates the fact that text
70         objects do not necessarily have an EditEngine at their
71         disposal, SvxViewForwarder and SvxEditViewForwarder do the
72         same for the document and the edit view. The three mentioned
73         forwarder objects are not stored by the AccessibleTextHelper,
74         but fetched every time from the SvxEditSource. So you are best
75         off making your SvxEditSource::Get*Forwarder methods cache the
76         current forwarder.
77 
78         To support changes in edit mode or conversion of fixed text
79         into EditEngine text, you can change the SvxEditSource this
80         class is referring to. This might render all children invalid
81         and change the child count, since the AccessibleTextHelper
82         reinitializes itself from scratch.
83 
84         This class registers itself at the SvxEditSource as a state
85         listener and manages the state of its children (i.e. the
86         paragraphs). See the method documentation of
87         AccessibleTextHelper::SetEditSource for the expected
88         events. Generally, be prepared that when sending any of these
89         events via SvxEditSource::GetBroadcaster() broadcaster, the
90         AccessibleTextHelper will call the SvxEditSource and their
91         forwarder to update it's state. Avoid being inconsistent in
92         the facts you tell in the events, e.g. when sending a
93         TEXT_HINT_PARAINSERTED event, the
94         SvxEditSource::GetTextForwarder().GetParagraphCount() should
95         already include the newly inserted paragraph.
96 
97         @attention All public methods must not be called with any
98         mutex hold, except when calling from the main thread (with
99         holds the solar mutex), unless stated otherwise. This is
100         because they themselves might need the solar mutex in addition
101         to the object mutex, and the ordering of the locking must be:
102         first solar mutex, then object mutex. Furthermore, state
103         change events might be fired internally.
104 
105         @derive Use this class in an aggregation and forward, or
106         derive from it and overwrite. If the Remove/AddEventListener
107         methods are overwritten, make sure FireEvent is adapted,
108         too.
109 
110         @see SvxEditSource
111         @see SvxTextForwarder
112         @see SvxViewForwarder
113         @see SvxEditViewForwarder
114     */
115     class SVX_DLLPUBLIC AccessibleTextHelper
116     {
117 
118     public:
119         typedef ::std::vector< sal_Int16 > VectorOfStates;
120 
121         /** Create accessible text object for given edit source
122 
123             @param pEditSource
124             The edit source to use. Object ownership is transferred
125             from the caller to the callee. The object listens on the
126             SvxEditSource for object disposal, so no provisions have
127             to be taken if the caller destroys the data (e.g. the
128             model) contained in the given SvxEditSource.
129 
130         */
131         explicit AccessibleTextHelper( ::std::auto_ptr< SvxEditSource > pEditSource );
132         virtual ~AccessibleTextHelper();
133 
134     protected:
135 
136         // declared, but not defined
137         AccessibleTextHelper( const AccessibleTextHelper& );
138         // declared, but not defined
139         AccessibleTextHelper& operator= ( const AccessibleTextHelper& );
140 
141     public:
142         /** Query the current edit source
143 
144             @attention This method returns by reference, so you are
145             responsible for serialization (typically, you aquired the
146             solar mutex when calling this method). Thus, the method
147             should only be called from the main office thread.
148 
149          */
150         virtual const SvxEditSource& GetEditSource() const SAL_THROW((::com::sun::star::uno::RuntimeException));
151 
152         /** Set the current edit source
153 
154             @attention Might fire state change events, therefore,
155             don't hold any mutex except solar mutex, which you are
156             required to lock before. This method should only be called
157             from the main office thread.
158 
159             The EditSource set here is required to broadcast out the
160             following hints: EDITSOURCE_HINT_PARASMOVED,
161             EDITSOURCE_HINT_SELECTIONCHANGED, TEXT_HINT_MODIFIED,
162             TEXT_HINT_PARAINSERTED, TEXT_HINT_PARAREMOVED,
163             TEXT_HINT_TEXTHEIGHTCHANGED,
164             TEXT_HINT_VIEWSCROLLED. Otherwise, not all state changes
165             will get noticed by the accessibility object. Further
166             more, when the corresponding core object or the model is
167             dying, either the edit source must be set to NULL or it
168             has to broadcast a SFX_HINT_DYING hint.
169 
170             If the SvxEditSource's managed text can change between
171             edit/non-edit mode (i.e. there are times when
172             SvxEditSource::GetEditViewForwarder(sal_False) returns
173             NULL), then the two additional hints are required:
174             HINT_BEGEDIT and HINT_ENDEDIT. When the
175             AccessibleTextHelper receives a HINT_BEGEDIT, it expects
176             the SvxEditSource already in edit mode. On a HINT_ENDEDIT,
177             edit mode must already been left. The rationale for these
178             events are the fact that focus and selection have to be
179             updated in edit mode, and completely relinquished and
180             reset to the parent (for the focus) in non-edit mode.
181 
182             This class does not have a dispose method, since it is not
183             a UNO component. Nevertheless, it holds C++ references to
184             several core objects, so you should issue a
185             SetEditSource(::std::auto_ptr<SvxEditSource>(NULL)) in
186             your dispose() method.
187 
188             @param pEditSource
189             The new edit source to set. Object ownership is transferred
190             from the caller to the callee.
191         */
192         virtual void SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((::com::sun::star::uno::RuntimeException));
193 
194         /** Set the event source
195 
196             You should set the event source before registering any
197             event listener and before requesting any child. Children
198             of this object receive the event source as their parent
199             accessible object. That is, the event source is best set
200             in your object's init method.
201 
202             @attention When setting a reference here, you should call
203             Dispose() when you as the owner are disposing, since until
204             then this object will hold that reference
205 
206             @param rInterface
207             The interface that should be set as the source for
208             accessibility events sent by this object.
209          */
210         virtual void SetEventSource( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& rInterface );
211 
212         /** Get the event source
213 
214             @return the interface that is set as the source for
215             accessibility events sent by this object.
216          */
217         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > GetEventSource() const;
218 
219         /** Set offset of EditEngine/Outliner from parent
220 
221             If the origin of the underlying EditEngine/Outliner does
222             not correspond to the upper left corner of the object
223             using this class, you have to specify the offset.
224 
225             @attention Might fire state change events, therefore,
226             don't hold any mutex except solar mutex, which you are
227             required to lock before. This method should only be called
228             from the main office thread.
229 
230             @param rPoint
231             The offset in screen coordinates (i.e. pixel)
232         */
233         virtual void SetOffset( const Point& rPoint );
234 
235         /** Query offset of EditEngine/Outliner from parent
236 
237             @return the offset in screen coordinates (i.e. pixel)
238         */
239         virtual Point GetOffset() const;
240 
241         /** Set offset the object adds to all children's indices
242 
243             This can be used if the owner of this object has children
244             handled by itself. Setting an offset different from 0
245             leads to this object mimicking that all it's children are
246             within the range [nOffset, GetChildCount()+nOffset). That
247             means, GetChild() also expects the index to be in this
248             range.
249 
250             @attention Might fire state change events, therefore,
251             don't hold any mutex except solar mutex, which you are
252             required to lock before. This method should only be called
253             from the main office thread.
254 
255             @param nOffset
256             The offset to add to every children's index.
257         */
258         virtual void SetStartIndex( sal_Int32 nOffset );
259 
260         /** Query offset the object adds to all children's indices
261 
262             @return the offset to add to every children's index.
263         */
264         virtual sal_Int32 GetStartIndex() const;
265 
266         /** Sets a vector of additional accessible states.
267 
268             The states are passed to every created child object
269             (text paragraph). The state values are defined in
270             com::sun::star::accessibility::AccessibleStateType.
271 
272             This function has to be called before querying for
273             any children (e.g. with GetChild()).
274          */
275         void SetAdditionalChildStates( const VectorOfStates& rChildStates );
276 
277         /** Returns the additional accessible states for children.
278          */
279         const VectorOfStates& GetAdditionalChildStates() const;
280 
281         /** Update the visible children
282 
283             @attention Might fire state change events, therefore,
284             don't hold any mutex except solar mutex, which you are
285             required to lock before. This method should only be called
286             from the main office thread.
287 
288             This method reevaluates the visibility of all
289             childrens. Call this method if your visibility state has
290             changed somehow, e.g. if the visible area has changed and
291             the AccessibleTextHelper isn't notified internally
292             (e.g. via TEXT_HINT_VIEWSCROLLED). Normally, there should
293             not be a need to call this method.
294         */
295         virtual void UpdateChildren() SAL_THROW((::com::sun::star::uno::RuntimeException));
296 
297         /** Drop all references and enter disposed state
298 
299             This method drops all references to external objects (also
300             the event source reference set via SetEventSource()) and
301             sets the object into the disposed state (i.e. the methods
302             return default values or throw a uno::DisposedException
303             exception).
304          */
305         virtual void Dispose();
306 
307         /** Set the focus state of the accessibility object
308 
309             Since this class handles children which also might get the
310             focus, the user of this class is encouraged to delegate
311             focus handling. Whenever the focus state of the
312             surrounding object changes, this method has to be called.
313 
314             The protocol of focus handling for a user of this class is
315             then to call SetFocus() with the appropriate focus state,
316             and HaveFocus() to determine the focus state you tell the
317             outside.
318 
319             @attention Might fire state change events, therefore,
320             don't hold any mutex except solar mutex, which you are
321             required to lock before. This method should only be called
322             from the main office thread.
323 
324             @param bHaveFocus
325             Whether we got or we lost the focus. Set to sal_True if
326             focus is gotten, sal_False otherwise.
327 
328             @see HaveFocus()
329          */
330         virtual void SetFocus( sal_Bool bHaveFocus = sal_True ) SAL_THROW((::com::sun::star::uno::RuntimeException));
331 
332         /** Query the focus state of the surrounding object
333 
334             If focus handling is delegated to this class, determine
335             focus state with this method. Be prepared that even if you
336             set the focus with SetFocus(sal_True), this method might
337             return sal_False. This is the case if one of the children
338             actually got the focus.
339 
340             @return the state of the focus ownership
341          */
342         virtual sal_Bool HaveFocus() SAL_THROW((::com::sun::star::uno::RuntimeException));
343 
344         /** Call this method to invoke all event listeners with the given event
345 
346             @attention Fires state change events, therefore, don't hold any mutex
347 
348             @param nEventId
349             Id of the event to send, @see AccessibleEventId
350 
351             @param rNewValue
352             The value we've changed into
353 
354             @param rOldValue
355             The old value before the change
356         */
357         virtual void FireEvent( const sal_Int16 nEventId,
358                                 const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(),
359                                 const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const;
360 
361         /** Call this method to invoke all event listeners with the given event
362 
363             @attention Fires state change events, therefore, don't hold any mutex
364 
365             @param rEvent
366             The event to send, @see AccessibleEventObject
367 
368         */
369         // TODO: make that virtual next time
370         void FireEvent( const ::com::sun::star::accessibility::AccessibleEventObject& rEvent ) const;
371 
372         /** Query select state of the text managed by this object
373 
374             @attention Don't call with locked mutexes. You may hold
375             the solar mutex, but this method aquires it anyway.
376 
377             @return sal_True, if the text or parts of it are currently selected
378         */
379         virtual sal_Bool IsSelected() const;
380 
381         // XAccessibleContext child handling methods
382         //-----------------------------------------------------------------
383         /** Implements getAccessibleChildCount
384 
385             @attention Don't call with locked mutexes. You may hold
386             the solar mutex, but this method aquires it anyway.
387         */
388         virtual sal_Int32 GetChildCount() SAL_THROW((::com::sun::star::uno::RuntimeException));
389         /** Implements getAccessibleChild
390 
391             @attention Don't call with locked mutexes. You may hold
392             the solar mutex, but this method aquires it anyway.
393         */
394         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > GetChild( sal_Int32 i ) SAL_THROW((::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException));
395 
396         // XAccessibleEventBroadcaster child related methods
397         //-----------------------------------------------------------------
398         /** Implements addEventListener
399 
400             @attention Don't call with locked mutexes
401         */
402         virtual void AddEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) SAL_THROW((::com::sun::star::uno::RuntimeException));
403         /** Implements removeEventListener
404 
405             @attention Don't call with locked mutexes
406         */
407         virtual void RemoveEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) SAL_THROW((::com::sun::star::uno::RuntimeException));
408 
409         // XAccessibleComponent child related methods
410         //-----------------------------------------------------------------
411         /** Implements getAccessibleAt
412 
413             @attention Don't call with locked mutexes. You may hold
414             the solar mutex, but this method aquires it anyway.
415         */
416         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL GetAt( const ::com::sun::star::awt::Point& aPoint ) SAL_THROW((::com::sun::star::uno::RuntimeException));
417 
418     private:
419 
420         /// @dyn
421         const std::auto_ptr< AccessibleTextHelper_Impl > mpImpl;
422 
423     };
424 
425 } // end of namespace accessibility
426 
427 #endif /* _SVX_ACCESSILE_TEXT_HELPER_HXX_ */
428