Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : //------------------------------------------------------------------------
31 : : //
32 : : // Global header
33 : : //
34 : : //------------------------------------------------------------------------
35 : :
36 : : #include <limits.h>
37 : : #include <memory>
38 : : #include <algorithm>
39 : : #include <deque>
40 : : #include <osl/mutex.hxx>
41 : : #include <com/sun/star/uno/Any.hxx>
42 : : #include <com/sun/star/uno/Reference.hxx>
43 : : #include <cppuhelper/weakref.hxx>
44 : : #include <com/sun/star/awt/Point.hpp>
45 : : #include <com/sun/star/awt/Rectangle.hpp>
46 : : #include <com/sun/star/lang/DisposedException.hpp>
47 : : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
48 : : #include <com/sun/star/accessibility/XAccessible.hpp>
49 : : #include <com/sun/star/accessibility/XAccessibleContext.hpp>
50 : : #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
51 : : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
52 : : #include <comphelper/accessibleeventnotifier.hxx>
53 : : #include <unotools/accessiblestatesethelper.hxx>
54 : : #include <vcl/unohelp.hxx>
55 : : #include <vcl/svapp.hxx>
56 : :
57 : : //------------------------------------------------------------------------
58 : : //
59 : : // Project-local header
60 : : //
61 : : //------------------------------------------------------------------------
62 : : #include "AccessibleTextEventQueue.hxx"
63 : : #include <svx/AccessibleTextHelper.hxx>
64 : : #include <svx/unoshape.hxx>
65 : : #include "editeng/unolingu.hxx"
66 : : #include <editeng/unotext.hxx>
67 : :
68 : : #include "editeng/unoedhlp.hxx"
69 : : #include "editeng/unopracc.hxx"
70 : : #include "editeng/AccessibleParaManager.hxx"
71 : : #include "editeng/AccessibleEditableTextPara.hxx"
72 : : #include <svx/svdmodel.hxx>
73 : : #include <svx/svdpntv.hxx>
74 : : #include <editeng/editdata.hxx>
75 : : #include <editeng/editeng.hxx>
76 : : #include <editeng/editview.hxx>
77 : :
78 : : using namespace ::com::sun::star;
79 : : using namespace ::com::sun::star::accessibility;
80 : :
81 : : namespace accessibility
82 : : {
83 : :
84 : : //------------------------------------------------------------------------
85 : : //
86 : : // AccessibleTextHelper_Impl declaration
87 : : //
88 : : //------------------------------------------------------------------------
89 : :
90 : : DBG_NAME( AccessibleTextHelper_Impl )
91 : :
92 : : template < typename first_type, typename second_type >
93 : 0 : ::std::pair< first_type, second_type > makeSortedPair( first_type first,
94 : : second_type second )
95 : : {
96 [ # # ]: 0 : if( first > second )
97 : 0 : return ::std::make_pair( second, first );
98 : : else
99 : 0 : return ::std::make_pair( first, second );
100 : : }
101 : :
102 : : class AccessibleTextHelper_Impl : public SfxListener
103 : : {
104 : :
105 : : public:
106 : : typedef ::std::vector< sal_Int16 > VectorOfStates;
107 : :
108 : : // receive pointer to our frontend class and view window
109 : : AccessibleTextHelper_Impl();
110 : : ~AccessibleTextHelper_Impl();
111 : :
112 : : // XAccessibleContext child handling methods
113 : : sal_Int32 SAL_CALL getAccessibleChildCount() SAL_THROW((uno::RuntimeException));
114 : : uno::Reference< XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException));
115 : :
116 : : // XAccessibleEventBroadcaster child related methods
117 : : void SAL_CALL addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) SAL_THROW((uno::RuntimeException));
118 : : void SAL_CALL removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) SAL_THROW((uno::RuntimeException));
119 : :
120 : : // XAccessibleComponent child related methods
121 : : uno::Reference< XAccessible > SAL_CALL getAccessibleAtPoint( const awt::Point& aPoint ) SAL_THROW((uno::RuntimeException));
122 : :
123 : : SvxEditSourceAdapter& GetEditSource() const SAL_THROW((uno::RuntimeException));
124 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
125 : : void SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException));
126 : : SAL_WNODEPRECATED_DECLARATIONS_POP
127 : :
128 : 56 : void SetEventSource( const uno::Reference< XAccessible >& rInterface )
129 : : {
130 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
131 : 56 : mxFrontEnd = rInterface;
132 : 56 : }
133 : 0 : uno::Reference< XAccessible > GetEventSource() const
134 : : {
135 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
136 : 0 : return mxFrontEnd;
137 : : }
138 : :
139 : : void SetOffset( const Point& );
140 : 6 : Point GetOffset() const
141 : : {
142 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
143 [ + - ]: 6 : ::osl::MutexGuard aGuard( maMutex ); Point aPoint( maOffset );
144 [ + - ]: 6 : return aPoint;
145 : : }
146 : :
147 : : void SetStartIndex( sal_Int32 nOffset );
148 : 64 : sal_Int32 GetStartIndex() const
149 : : {
150 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
151 : : // Strictly correct only with locked solar mutex, // but
152 : : // here we rely on the fact that sal_Int32 access is
153 : : // atomic
154 : 64 : return mnStartIndex;
155 : : }
156 : :
157 : : void SetAdditionalChildStates( const VectorOfStates& rChildStates );
158 : :
159 : : sal_Bool IsSelected() const;
160 : :
161 : : void Dispose();
162 : :
163 : : // do NOT hold object mutex when calling this! Danger of deadlock
164 : : void FireEvent( const sal_Int16 nEventId, const uno::Any& rNewValue = uno::Any(), const uno::Any& rOldValue = uno::Any() ) const;
165 : : void FireEvent( const AccessibleEventObject& rEvent ) const;
166 : :
167 : : void SetFocus( sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException));
168 : : sal_Bool HaveFocus() SAL_THROW((::com::sun::star::uno::RuntimeException));
169 : : void SetChildFocus( sal_Int32 nChild, sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException));
170 : : void SetShapeFocus( sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException));
171 : : void ChangeChildFocus( sal_Int32 nNewChild ) SAL_THROW((::com::sun::star::uno::RuntimeException));
172 : :
173 : : #ifdef DBG_UTIL
174 : : void CheckInvariants() const;
175 : : #endif
176 : :
177 : : // checks all children for visibility, throws away invisible ones
178 : : void UpdateVisibleChildren( bool bBroadcastEvents=true );
179 : :
180 : : // check all children for changes in position and size
181 : : void UpdateBoundRect();
182 : :
183 : : // calls SetSelection on the forwarder and updates maLastSelection
184 : : // cache.
185 : : void UpdateSelection();
186 : :
187 : : private:
188 : :
189 : : // Process event queue
190 : : void ProcessQueue();
191 : :
192 : : // syntactic sugar for FireEvent
193 [ + - ]: 2 : void GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const { FireEvent( nEventId, rNewValue ); }
194 [ + - ]: 1 : void LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const { FireEvent( nEventId, uno::Any(), rOldValue ); }
195 : :
196 : : // shutdown usage of current edit source on myself and the children.
197 : : void ShutdownEditSource() SAL_THROW((uno::RuntimeException));
198 : :
199 : : void ParagraphsMoved( sal_Int32 nFirst, sal_Int32 nMiddle, sal_Int32 nLast );
200 : :
201 : : virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
202 : :
203 : 117 : int getNotifierClientId() const { return mnNotifierClientId; }
204 : :
205 : : // lock solar mutex before
206 : : SvxTextForwarder& GetTextForwarder() const SAL_THROW((uno::RuntimeException));
207 : : // lock solar mutex before
208 : : SvxViewForwarder& GetViewForwarder() const SAL_THROW((uno::RuntimeException));
209 : : // lock solar mutex before
210 : : SvxEditViewForwarder& GetEditViewForwarder( sal_Bool bCreate = sal_False ) const SAL_THROW((uno::RuntimeException));
211 : :
212 : : // are we in edit mode?
213 : : sal_Bool IsActive() const SAL_THROW((uno::RuntimeException));
214 : :
215 : : // our frontend class (the one implementing the actual
216 : : // interface). That's not necessarily the one containing the impl
217 : : // pointer!
218 : : uno::Reference< XAccessible > mxFrontEnd;
219 : :
220 : : // a wrapper for the text forwarders (guarded by solar mutex)
221 : : mutable SvxEditSourceAdapter maEditSource;
222 : :
223 : : // store last selection (to correctly report selection changes, guarded by solar mutex)
224 : : ESelection maLastSelection;
225 : :
226 : : // cache range of visible children (guarded by solar mutex)
227 : : sal_Int32 mnFirstVisibleChild;
228 : : sal_Int32 mnLastVisibleChild;
229 : :
230 : : // offset to add to all our children (unguarded, relying on
231 : : // the fact that sal_Int32 access is atomic)
232 : : sal_Int32 mnStartIndex;
233 : :
234 : : // the object handling our children (guarded by solar mutex)
235 : : ::accessibility::AccessibleParaManager maParaManager;
236 : :
237 : : // number of not-yet-closed event frames (BEGIN/END sequences) (guarded by solar mutex)
238 : : sal_Int32 maEventOpenFrames;
239 : :
240 : : // Queued events from Notify() (guarded by solar mutex)
241 : : AccessibleTextEventQueue maEventQueue;
242 : :
243 : : // spin lock to prevent notify in notify (guarded by solar mutex)
244 : : sal_Bool mbInNotify;
245 : :
246 : : // whether the object or it's children has the focus set (guarded by solar mutex)
247 : : sal_Bool mbGroupHasFocus;
248 : :
249 : : // whether we (this object) has the focus set (guarded by solar mutex)
250 : : sal_Bool mbThisHasFocus;
251 : :
252 : : mutable ::osl::Mutex maMutex;
253 : :
254 : : /// our current offset to the containing shape/cell (guarded by maMutex)
255 : : Point maOffset;
256 : :
257 : : /// client Id from AccessibleEventNotifier
258 : : int mnNotifierClientId;
259 : : };
260 : :
261 : : //------------------------------------------------------------------------
262 : : //
263 : : // AccessibleTextHelper_Impl implementation
264 : : //
265 : : //------------------------------------------------------------------------
266 : :
267 : 56 : AccessibleTextHelper_Impl::AccessibleTextHelper_Impl() :
268 : : mxFrontEnd( NULL ),
269 : : maLastSelection( EE_PARA_NOT_FOUND,EE_PARA_NOT_FOUND,EE_PARA_NOT_FOUND,EE_PARA_NOT_FOUND ),
270 : : mnFirstVisibleChild( -1 ),
271 : : mnLastVisibleChild( -2 ),
272 : : mnStartIndex( 0 ),
273 : : maEventOpenFrames( 0 ),
274 : : mbInNotify( sal_False ),
275 : : mbGroupHasFocus( sal_False ),
276 : : mbThisHasFocus( sal_False ),
277 : : maOffset(0,0),
278 : : // well, that's strictly exception safe, though not really
279 : : // robust. We rely on the fact that this member is constructed
280 : : // last, and that the constructor body is empty, thus no
281 : : // chance for exceptions once the Id is fetched. Nevertheless,
282 : : // normally should employ RAII here...
283 [ + - ][ + - ]: 56 : mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient())
[ + - ][ + - ]
[ + - ][ + - ]
284 : : {
285 : : DBG_CTOR( AccessibleTextHelper_Impl, NULL );
286 : :
287 : : #ifdef DBG_UTIL
288 : : OSL_TRACE( "AccessibleTextHelper_Impl received ID: %d", mnNotifierClientId );
289 : : #endif
290 : 56 : }
291 : :
292 [ + - ][ + - ]: 45 : AccessibleTextHelper_Impl::~AccessibleTextHelper_Impl()
[ + - ][ + - ]
293 : : {
294 : : DBG_DTOR( AccessibleTextHelper_Impl, NULL );
295 : :
296 [ + - ]: 45 : SolarMutexGuard aGuard;
297 : :
298 : : try
299 : : {
300 : : // call Dispose here, too, since we've some resources not
301 : : // automatically freed otherwise
302 [ + - ]: 45 : Dispose();
303 : : }
304 [ + - # # ]: 45 : catch( const uno::Exception& ) {}
305 [ - + ][ # # ]: 90 : }
306 : :
307 : 216 : SvxTextForwarder& AccessibleTextHelper_Impl::GetTextForwarder() const SAL_THROW((uno::RuntimeException))
308 : : {
309 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
310 : :
311 [ - + ]: 216 : if( !maEditSource.IsValid() )
312 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown edit source")), mxFrontEnd);
313 : :
314 : 216 : SvxTextForwarder* pTextForwarder = maEditSource.GetTextForwarder();
315 : :
316 [ - + ]: 216 : if( !pTextForwarder )
317 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch text forwarder, model might be dead")), mxFrontEnd);
318 : :
319 [ + - ]: 216 : if( pTextForwarder->IsValid() )
320 : 216 : return *pTextForwarder;
321 : : else
322 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text forwarder is invalid, model might be dead")), mxFrontEnd);
323 : : }
324 : :
325 : 82 : SvxViewForwarder& AccessibleTextHelper_Impl::GetViewForwarder() const SAL_THROW((uno::RuntimeException))
326 : : {
327 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
328 : :
329 [ - + ]: 82 : if( !maEditSource.IsValid() )
330 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown edit source")), mxFrontEnd);
331 : :
332 : 82 : SvxViewForwarder* pViewForwarder = maEditSource.GetViewForwarder();
333 : :
334 [ - + ]: 82 : if( !pViewForwarder )
335 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, model might be dead")), mxFrontEnd);
336 : :
337 [ + - ]: 82 : if( pViewForwarder->IsValid() )
338 : 82 : return *pViewForwarder;
339 : : else
340 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, model might be dead")), mxFrontEnd);
341 : : }
342 : :
343 : 19 : SvxEditViewForwarder& AccessibleTextHelper_Impl::GetEditViewForwarder( sal_Bool bCreate ) const SAL_THROW((uno::RuntimeException))
344 : : {
345 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
346 : :
347 [ - + ]: 19 : if( !maEditSource.IsValid() )
348 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown edit source")), mxFrontEnd);
349 : :
350 : 19 : SvxEditViewForwarder* pViewForwarder = maEditSource.GetEditViewForwarder( bCreate );
351 : :
352 [ + + ]: 19 : if( !pViewForwarder )
353 : : {
354 [ - + ]: 15 : if( bCreate )
355 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch edit view forwarder, model might be dead")), mxFrontEnd);
356 : : else
357 [ + - ][ + - ]: 15 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No edit view forwarder, object not in edit mode")), mxFrontEnd);
358 : : }
359 : :
360 [ + - ]: 4 : if( pViewForwarder->IsValid() )
361 : 4 : return *pViewForwarder;
362 : : else
363 : : {
364 [ # # ]: 0 : if( bCreate )
365 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, model might be dead")), mxFrontEnd);
366 : : else
367 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object not in edit mode")), mxFrontEnd);
368 : : }
369 : : }
370 : :
371 : 138 : SvxEditSourceAdapter& AccessibleTextHelper_Impl::GetEditSource() const SAL_THROW((uno::RuntimeException))
372 : : {
373 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
374 : :
375 [ + - ]: 138 : if( maEditSource.IsValid() )
376 : 138 : return maEditSource;
377 : : else
378 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleTextHelper_Impl::GetEditSource: no edit source")), mxFrontEnd );
379 : : }
380 : :
381 : 0 : sal_Bool AccessibleTextHelper_Impl::IsSelected() const
382 : : {
383 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
384 : :
385 : 0 : sal_Bool bRet = sal_False;
386 : :
387 : : try
388 : : {
389 : 0 : ESelection aSelection;
390 [ # # ][ # # ]: 0 : bRet = GetEditViewForwarder().GetSelection( aSelection );
391 : : }
392 : 0 : catch( const uno::Exception& ) {}
393 : :
394 [ # # ]: 0 : return bRet;
395 : : }
396 : :
397 : : // functor for sending child events (no stand-alone function, they are maybe not inlined)
398 : : class AccessibleTextHelper_OffsetChildIndex : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void >
399 : : {
400 : : public:
401 : 0 : AccessibleTextHelper_OffsetChildIndex( sal_Int32 nDifference ) : mnDifference(nDifference) {}
402 : 0 : void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
403 : : {
404 : 0 : rPara.SetIndexInParent( rPara.GetIndexInParent() + mnDifference );
405 : 0 : }
406 : :
407 : : private:
408 : : const sal_Int32 mnDifference;
409 : : };
410 : :
411 : 0 : void AccessibleTextHelper_Impl::SetStartIndex( sal_Int32 nOffset )
412 : : {
413 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
414 : :
415 : 0 : sal_Int32 nOldOffset( mnStartIndex );
416 : :
417 : 0 : mnStartIndex = nOffset;
418 : :
419 [ # # ]: 0 : if( nOldOffset != nOffset )
420 : : {
421 : : // update children
422 : 0 : AccessibleTextHelper_OffsetChildIndex aFunctor( nOffset - nOldOffset );
423 : :
424 : : ::std::for_each( maParaManager.begin(), maParaManager.end(),
425 [ # # ][ # # ]: 0 : AccessibleParaManager::WeakChildAdapter< AccessibleTextHelper_OffsetChildIndex > (aFunctor) );
[ # # ]
426 : : }
427 : 0 : }
428 : :
429 : 15 : void AccessibleTextHelper_Impl::SetAdditionalChildStates( const VectorOfStates& rChildStates )
430 : : {
431 : 15 : maParaManager.SetAdditionalChildStates( rChildStates );
432 : 15 : }
433 : :
434 : 0 : void AccessibleTextHelper_Impl::SetChildFocus( sal_Int32 nChild, sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException))
435 : : {
436 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
437 : :
438 [ # # ]: 0 : if( bHaveFocus )
439 : : {
440 [ # # ]: 0 : if( mbThisHasFocus )
441 : 0 : SetShapeFocus( sal_False );
442 : :
443 : 0 : maParaManager.SetFocus( nChild );
444 : :
445 : : // we just received the focus, also send caret event then
446 : 0 : UpdateSelection();
447 : :
448 : : OSL_TRACE("AccessibleTextHelper_Impl::SetChildFocus(): Paragraph %d received focus", nChild );
449 : : }
450 : : else
451 : : {
452 : 0 : maParaManager.SetFocus( -1 );
453 : :
454 : : OSL_TRACE("AccessibleTextHelper_Impl::SetChildFocus(): Paragraph %d lost focus", nChild );
455 : :
456 [ # # ]: 0 : if( mbGroupHasFocus )
457 : 0 : SetShapeFocus( sal_True );
458 : : }
459 : 0 : }
460 : :
461 : 0 : void AccessibleTextHelper_Impl::ChangeChildFocus( sal_Int32 nNewChild ) SAL_THROW((::com::sun::star::uno::RuntimeException))
462 : : {
463 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
464 : :
465 [ # # ]: 0 : if( mbThisHasFocus )
466 : 0 : SetShapeFocus( sal_False );
467 : :
468 : 0 : mbGroupHasFocus = sal_True;
469 : 0 : maParaManager.SetFocus( nNewChild );
470 : :
471 : : OSL_TRACE("AccessibleTextHelper_Impl::ChangeChildFocus(): Paragraph %d received focus", nNewChild );
472 : 0 : }
473 : :
474 : 2 : void AccessibleTextHelper_Impl::SetShapeFocus( sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException))
475 : : {
476 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
477 : :
478 : 2 : sal_Bool bOldFocus( mbThisHasFocus );
479 : :
480 : 2 : mbThisHasFocus = bHaveFocus;
481 : :
482 [ + - ]: 2 : if( bOldFocus != bHaveFocus )
483 : : {
484 [ + - ]: 2 : if( bHaveFocus )
485 : : {
486 [ + - ]: 2 : GotPropertyEvent( uno::makeAny(AccessibleStateType::FOCUSED), AccessibleEventId::STATE_CHANGED );
487 : : OSL_TRACE("AccessibleTextHelper_Impl::SetShapeFocus(): Parent object received focus" );
488 : : }
489 : : else
490 : : {
491 [ # # ]: 0 : LostPropertyEvent( uno::makeAny(AccessibleStateType::FOCUSED), AccessibleEventId::STATE_CHANGED );
492 : : OSL_TRACE("AccessibleTextHelper_Impl::SetShapeFocus(): Parent object lost focus" );
493 : : }
494 : : }
495 : 2 : }
496 : :
497 : 2 : void AccessibleTextHelper_Impl::SetFocus( sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException))
498 : : {
499 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
500 : :
501 : 2 : sal_Bool bOldFocus( mbGroupHasFocus );
502 : :
503 : 2 : mbGroupHasFocus = bHaveFocus;
504 : :
505 [ - + ]: 2 : if( IsActive() )
506 : : {
507 : : try
508 : : {
509 : : // find the one with the cursor and get/set focus accordingly
510 : 0 : ESelection aSelection;
511 [ # # ][ # # ]: 0 : if( GetEditViewForwarder().GetSelection( aSelection ) )
[ # # ]
512 [ # # ]: 0 : SetChildFocus( aSelection.nEndPara, bHaveFocus );
513 : : }
514 : 0 : catch( const uno::Exception& ) {}
515 : : }
516 [ + - ]: 2 : else if( bOldFocus != bHaveFocus )
517 : : {
518 : 2 : SetShapeFocus( bHaveFocus );
519 : : }
520 : :
521 : : OSL_TRACE("AccessibleTextHelper_Impl::SetFocus: focus changed, Object %d, state: %s", this, bHaveFocus ? "focused" : "not focused");
522 [ # # ]: 2 : }
523 : :
524 : 12 : sal_Bool AccessibleTextHelper_Impl::HaveFocus() SAL_THROW((::com::sun::star::uno::RuntimeException))
525 : : {
526 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
527 : :
528 : : // No locking of solar mutex here, since we rely on the fact
529 : : // that sal_Bool access is atomic
530 : 12 : return mbThisHasFocus;
531 : : }
532 : :
533 : 78 : sal_Bool AccessibleTextHelper_Impl::IsActive() const SAL_THROW((uno::RuntimeException))
534 : : {
535 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
536 : :
537 : : try
538 : : {
539 [ + - ]: 78 : SvxEditSource& rEditSource = GetEditSource();
540 [ + - ]: 78 : SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder();
541 : :
542 [ + + ]: 78 : if( !pViewForwarder )
543 : 74 : return sal_False;
544 : :
545 [ + - ][ + - ]: 4 : if( pViewForwarder->IsValid() )
546 : 4 : return sal_True;
547 : : else
548 [ # # ]: 78 : return sal_False;
549 : : }
550 : 0 : catch( const uno::RuntimeException& )
551 : : {
552 : 0 : return sal_False;
553 : : }
554 : : }
555 : :
556 : 15 : void AccessibleTextHelper_Impl::UpdateSelection()
557 : : {
558 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
559 : :
560 : : try
561 : : {
562 : 15 : ESelection aSelection;
563 [ # # ][ # # ]: 15 : if( GetEditViewForwarder().GetSelection( aSelection ) )
[ - + ]
564 : : {
565 [ # # ][ # # ]: 0 : if( !maLastSelection.IsEqual( aSelection ) &&
[ # # ]
566 [ # # ]: 0 : aSelection.nEndPara < maParaManager.GetNum() )
567 : : {
568 : : // #103998# Not that important, changed from assertion to trace
569 : 0 : if( mbThisHasFocus )
570 : : {
571 : : OSL_TRACE("AccessibleTextHelper_Impl::UpdateSelection(): Parent has focus!");
572 : : }
573 : :
574 [ # # ][ # # ]: 0 : sal_uInt16 nMaxValidParaIndex( static_cast< sal_uInt16 >( GetTextForwarder().GetParagraphCount() ) - 1 );
575 : :
576 : : // notify all affected paragraphs (TODO: may be suboptimal,
577 : : // since some paragraphs might stay selected)
578 [ # # ]: 0 : if( maLastSelection.nStartPara != EE_PARA_NOT_FOUND )
579 : : {
580 : : // Did the caret move from one paragraph to another?
581 : : // #100530# no caret events if not focused.
582 [ # # ][ # # ]: 0 : if( mbGroupHasFocus &&
583 : : maLastSelection.nEndPara != aSelection.nEndPara )
584 : : {
585 [ # # ][ # # ]: 0 : if( maLastSelection.nEndPara < maParaManager.GetNum() )
586 : : {
587 [ # # ]: 0 : maParaManager.FireEvent( ::std::min( maLastSelection.nEndPara, nMaxValidParaIndex ),
588 [ # # ]: 0 : ::std::min( maLastSelection.nEndPara, nMaxValidParaIndex )+1,
589 : : AccessibleEventId::CARET_CHANGED,
590 : : uno::makeAny(static_cast<sal_Int32>(-1)),
591 [ # # ][ # # ]: 0 : uno::makeAny(static_cast<sal_Int32>(maLastSelection.nEndPos)) );
[ # # ]
592 : : }
593 : :
594 [ # # ]: 0 : ChangeChildFocus( aSelection.nEndPara );
595 : :
596 : : OSL_TRACE("AccessibleTextHelper_Impl::UpdateSelection(): focus changed, Object: %d, Paragraph: %d, Last paragraph: %d",
597 : : this, aSelection.nEndPara, maLastSelection.nEndPara);
598 : : }
599 : : }
600 : :
601 : : // #100530# no caret events if not focused.
602 [ # # ]: 0 : if( mbGroupHasFocus )
603 : : {
604 : 0 : uno::Any aOldCursor;
605 : :
606 : : // #i13705# The old cursor can only contain valid
607 : : // values if it's the same paragraph!
608 [ # # ][ # # ]: 0 : if( maLastSelection.nStartPara != EE_PARA_NOT_FOUND &&
609 : : maLastSelection.nEndPara == aSelection.nEndPara )
610 : : {
611 [ # # ]: 0 : aOldCursor <<= static_cast<sal_Int32>(maLastSelection.nEndPos);
612 : : }
613 : : else
614 : : {
615 [ # # ]: 0 : aOldCursor <<= static_cast<sal_Int32>(-1);
616 : : }
617 : :
618 : : maParaManager.FireEvent( aSelection.nEndPara,
619 : : aSelection.nEndPara+1,
620 : : AccessibleEventId::CARET_CHANGED,
621 : : uno::makeAny(static_cast<sal_Int32>(aSelection.nEndPos)),
622 [ # # ][ # # ]: 0 : aOldCursor );
623 : : }
624 : :
625 : : OSL_TRACE("AccessibleTextHelper_Impl::UpdateSelection(): caret changed, Object: %d, New pos: %d, Old pos: %d, New para: %d, Old para: %d",
626 : : this, aSelection.nEndPos, maLastSelection.nEndPos, aSelection.nEndPara, maLastSelection.nEndPara);
627 : :
628 : : // #108947# Sort new range before calling FireEvent
629 : : ::std::pair< xub_StrLen, xub_StrLen > sortedSelection(
630 [ # # ]: 0 : makeSortedPair(::std::min( aSelection.nStartPara, nMaxValidParaIndex ),
631 [ # # ][ # # ]: 0 : ::std::min( aSelection.nEndPara, nMaxValidParaIndex ) ) );
632 : :
633 : : // #108947# Sort last range before calling FireEvent
634 : : ::std::pair< xub_StrLen, xub_StrLen > sortedLastSelection(
635 [ # # ]: 0 : makeSortedPair(::std::min( maLastSelection.nStartPara, nMaxValidParaIndex ),
636 [ # # ][ # # ]: 0 : ::std::min( maLastSelection.nEndPara, nMaxValidParaIndex ) ) );
637 : :
638 : : // event TEXT_SELECTION_CHANGED has to be submitted. (#i27299#)
639 : : const sal_Int16 nTextSelChgEventId =
640 : 0 : AccessibleEventId::TEXT_SELECTION_CHANGED;
641 : : // #107037# notify selection change
642 [ # # ]: 0 : if( maLastSelection.nStartPara == EE_PARA_NOT_FOUND )
643 : : {
644 : : // last selection is undefined
645 : : // use method <ESelection::HasRange()> (#i27299#)
646 [ # # ]: 0 : if ( aSelection.HasRange() )
647 : : {
648 : : // selection was undefined, now is on
649 : : maParaManager.FireEvent( sortedSelection.first,
650 : : sortedSelection.second+1,
651 [ # # ]: 0 : nTextSelChgEventId );
652 : : }
653 : : }
654 : : else
655 : : {
656 : : // last selection is valid
657 : : // use method <ESelection::HasRange()> (#i27299#)
658 [ # # # # ]: 0 : if ( maLastSelection.HasRange() &&
[ # # ]
659 : 0 : !aSelection.HasRange() )
660 : : {
661 : : // selection was on, now is empty
662 : : maParaManager.FireEvent( sortedLastSelection.first,
663 : : sortedLastSelection.second+1,
664 [ # # ]: 0 : nTextSelChgEventId );
665 : : }
666 : : // use method <ESelection::HasRange()> (#i27299#)
667 [ # # # # ]: 0 : else if( !maLastSelection.HasRange() &&
[ # # ]
668 : 0 : aSelection.HasRange() )
669 : : {
670 : : // selection was empty, now is on
671 : : maParaManager.FireEvent( sortedSelection.first,
672 : : sortedSelection.second+1,
673 [ # # ]: 0 : nTextSelChgEventId );
674 : : }
675 : : // no event TEXT_SELECTION_CHANGED event, if new and
676 : : // last selection are empty. (#i27299#)
677 [ # # # # ]: 0 : else if ( maLastSelection.HasRange() &&
[ # # ]
678 : 0 : aSelection.HasRange() )
679 : : {
680 : : // use sorted last and new selection
681 : 0 : ESelection aTmpLastSel( maLastSelection );
682 : 0 : aTmpLastSel.Adjust();
683 : 0 : ESelection aTmpSel( aSelection );
684 : 0 : aTmpSel.Adjust();
685 : : // first submit event for new and changed selection
686 : 0 : sal_uInt32 nPara = aTmpSel.nStartPara;
687 [ # # ]: 0 : for ( ; nPara <= aTmpSel.nEndPara; ++nPara )
688 : : {
689 [ # # ][ # # ]: 0 : if ( nPara < aTmpLastSel.nStartPara ||
690 : : nPara > aTmpLastSel.nEndPara )
691 : : {
692 : : // new selection on paragraph <nPara>
693 : : maParaManager.FireEvent( nPara,
694 [ # # ]: 0 : nTextSelChgEventId );
695 : : }
696 : : else
697 : : {
698 : : // check for changed selection on paragraph <nPara>
699 : : const xub_StrLen nParaStartPos =
700 : : nPara == aTmpSel.nStartPara
701 [ # # ]: 0 : ? aTmpSel.nStartPos : 0;
702 : : const xub_StrLen nParaEndPos =
703 : : nPara == aTmpSel.nEndPara
704 [ # # ]: 0 : ? aTmpSel.nEndPos : STRING_LEN;
705 : : const xub_StrLen nLastParaStartPos =
706 : : nPara == aTmpLastSel.nStartPara
707 [ # # ]: 0 : ? aTmpLastSel.nStartPos : 0;
708 : : const xub_StrLen nLastParaEndPos =
709 : : nPara == aTmpLastSel.nEndPara
710 [ # # ]: 0 : ? aTmpLastSel.nEndPos : STRING_LEN;
711 [ # # ][ # # ]: 0 : if ( nParaStartPos != nLastParaStartPos ||
712 : : nParaEndPos != nLastParaEndPos )
713 : : {
714 : : maParaManager.FireEvent(
715 [ # # ]: 0 : nPara, nTextSelChgEventId );
716 : : }
717 : : }
718 : : }
719 : : // second submit event for 'old' selections
720 : 0 : nPara = aTmpLastSel.nStartPara;
721 [ # # ]: 0 : for ( ; nPara <= aTmpLastSel.nEndPara; ++nPara )
722 : : {
723 [ # # ][ # # ]: 0 : if ( nPara < aTmpSel.nStartPara ||
724 : : nPara > aTmpSel.nEndPara )
725 : : {
726 : : maParaManager.FireEvent( nPara,
727 [ # # ][ - + ]: 15 : nTextSelChgEventId );
728 : : }
729 : : }
730 : : }
731 : : }
732 : :
733 : 0 : maLastSelection = aSelection;
734 : : }
735 : : }
736 : : }
737 : : // no selection? no update actions
738 : 15 : catch( const uno::RuntimeException& ) {}
739 : 15 : }
740 : :
741 : 60 : void AccessibleTextHelper_Impl::ShutdownEditSource() SAL_THROW((uno::RuntimeException))
742 : : {
743 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
744 : :
745 : : // This should only be called with solar mutex locked, i.e. from the main office thread
746 : :
747 : : // This here is somewhat clumsy: As soon as our children have
748 : : // a NULL EditSource (maParaManager.SetEditSource()), they
749 : : // enter the disposed state and cannot be reanimated. Thus, it
750 : : // is unavoidable and a hard requirement to let go and create
751 : : // from scratch each and every child.
752 : :
753 : : // invalidate children
754 : 60 : maParaManager.Dispose();
755 : 60 : maParaManager.SetNum(0);
756 : :
757 : : // lost all children
758 [ + + ]: 60 : if( mxFrontEnd.is() )
759 [ + - ]: 4 : FireEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN);
760 : :
761 : : // quit listen on stale edit source
762 [ + + ]: 60 : if( maEditSource.IsValid() )
763 : 4 : EndListening( maEditSource.GetBroadcaster() );
764 : :
765 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
766 [ + - ][ + - ]: 60 : maEditSource.SetEditSource( ::std::auto_ptr< SvxEditSource >(NULL) );
767 : : SAL_WNODEPRECATED_DECLARATIONS_POP
768 : 60 : }
769 : :
770 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
771 : 60 : void AccessibleTextHelper_Impl::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException))
772 : : {
773 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
774 : :
775 : : // This should only be called with solar mutex locked, i.e. from the main office thread
776 : :
777 : : // shutdown old edit source
778 : 60 : ShutdownEditSource();
779 : :
780 : : // set new edit source
781 [ + - ]: 60 : maEditSource.SetEditSource( pEditSource );
782 : :
783 : : // init child vector to the current child count
784 [ + + ]: 60 : if( maEditSource.IsValid() )
785 : : {
786 : 56 : maParaManager.SetNum( GetTextForwarder().GetParagraphCount() );
787 : :
788 : : // listen on new edit source
789 : 56 : StartListening( maEditSource.GetBroadcaster() );
790 : :
791 : 56 : UpdateVisibleChildren();
792 : : }
793 : 60 : }
794 : : SAL_WNODEPRECATED_DECLARATIONS_POP
795 : :
796 : 0 : void AccessibleTextHelper_Impl::SetOffset( const Point& rPoint )
797 : : {
798 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
799 : :
800 : : // guard against non-atomic access to maOffset data structure
801 : : {
802 [ # # ]: 0 : ::osl::MutexGuard aGuard( maMutex );
803 [ # # ]: 0 : maOffset = rPoint;
804 : : }
805 : :
806 : 0 : maParaManager.SetEEOffset( rPoint );
807 : :
808 : : // in all cases, check visibility afterwards.
809 : 0 : UpdateVisibleChildren();
810 : 0 : UpdateBoundRect();
811 : 0 : }
812 : :
813 : 76 : void AccessibleTextHelper_Impl::UpdateVisibleChildren( bool bBroadcastEvents )
814 : : {
815 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
816 : :
817 : : try
818 : : {
819 [ + - ]: 76 : SvxTextForwarder& rCacheTF = GetTextForwarder();
820 [ + - ]: 76 : SvxViewForwarder& rCacheVF = GetViewForwarder();
821 : :
822 [ + - ]: 76 : Rectangle aViewArea = rCacheVF.GetVisArea();
823 : :
824 [ + - ][ + + ]: 76 : if( IsActive() )
825 : : {
826 : : // maybe the edit view scrolls, adapt aViewArea
827 [ + - ][ + - ]: 4 : Rectangle aEditViewArea = GetEditViewForwarder().GetVisArea();
828 [ + - ]: 4 : aViewArea += aEditViewArea.TopLeft();
829 : :
830 : : // now determine intersection
831 [ + - ]: 4 : aViewArea.Intersection( aEditViewArea );
832 : : }
833 : :
834 [ + - ][ + - ]: 76 : Rectangle aTmpBB, aParaBB;
835 : 76 : sal_Bool bFirstChild = sal_True;
836 : : sal_Int32 nCurrPara;
837 [ + - ]: 76 : sal_Int32 nParas=rCacheTF.GetParagraphCount();
838 : :
839 : 76 : mnFirstVisibleChild = -1;
840 : 76 : mnLastVisibleChild = -2;
841 : :
842 [ + + ]: 152 : for( nCurrPara=0; nCurrPara<nParas; ++nCurrPara )
843 : : {
844 : : DBG_ASSERT(nCurrPara >= 0 && nCurrPara <= USHRT_MAX,
845 : : "AccessibleTextHelper_Impl::UpdateVisibleChildren: index value overflow");
846 : :
847 [ + - ]: 76 : aTmpBB = rCacheTF.GetParaBounds( static_cast< sal_uInt16 >( nCurrPara ) );
848 : :
849 : : // convert to screen coordinates
850 [ + - ][ + - ]: 76 : aParaBB = ::accessibility::AccessibleEditableTextPara::LogicToPixel( aTmpBB, rCacheTF.GetMapMode(), rCacheVF );
[ + - ]
851 : :
852 [ + - ][ + + ]: 76 : if( aParaBB.IsOver( aViewArea ) )
853 : : {
854 : : // at least partially visible
855 [ + - ]: 63 : if( bFirstChild )
856 : : {
857 : 63 : bFirstChild = sal_False;
858 : 63 : mnFirstVisibleChild = nCurrPara;
859 : : }
860 : :
861 : 63 : mnLastVisibleChild = nCurrPara;
862 : :
863 : : // child not yet created?
864 [ + - ]: 63 : ::accessibility::AccessibleParaManager::WeakChild aChild( maParaManager.GetChild(nCurrPara) );
865 [ + + ]: 116 : if( aChild.second.Width == 0 &&
[ + - - + ]
[ # # ][ - + ]
866 : : aChild.second.Height == 0 &&
867 : 53 : mxFrontEnd.is() &&
868 : : bBroadcastEvents )
869 : : {
870 : : GotPropertyEvent( uno::makeAny( maParaManager.CreateChild( nCurrPara - mnFirstVisibleChild,
871 [ # # ]: 0 : mxFrontEnd, GetEditSource(), nCurrPara ).first ),
872 [ # # ][ # # ]: 0 : AccessibleEventId::CHILD );
[ # # ][ # # ]
873 [ + - ]: 63 : }
874 : : }
875 : : else
876 : : {
877 : : // not or no longer visible
878 [ + - ][ + + ]: 13 : if( maParaManager.IsReferencable( nCurrPara ) )
879 : : {
880 [ + - ]: 1 : if( bBroadcastEvents )
881 [ + - ][ + - ]: 2 : LostPropertyEvent( uno::makeAny( maParaManager.GetChild( nCurrPara ).first.get().getRef() ),
[ + - ][ + - ]
882 [ + - ][ + - ]: 1 : AccessibleEventId::CHILD );
883 : :
884 : : // clear reference
885 [ + - ]: 1 : maParaManager.Release( nCurrPara );
886 : : }
887 : : }
888 : : }
889 : : }
890 [ # # ]: 0 : catch( const uno::Exception& )
891 : : {
892 : : OSL_FAIL("AccessibleTextHelper_Impl::UpdateVisibleChildren error while determining visible children");
893 : :
894 : : // something failed - currently no children
895 : 0 : mnFirstVisibleChild = -1;
896 : 0 : mnLastVisibleChild = -2;
897 [ # # ]: 0 : maParaManager.SetNum(0);
898 : :
899 : : // lost all children
900 [ # # ]: 0 : if( bBroadcastEvents )
901 [ # # ]: 0 : FireEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN);
902 : : }
903 : 76 : }
904 : :
905 : : // functor for checking changes in paragraph bounding boxes (no stand-alone function, maybe not inlined)
906 : : class AccessibleTextHelper_UpdateChildBounds : public ::std::unary_function< const ::accessibility::AccessibleParaManager::WeakChild&,
907 : : ::accessibility::AccessibleParaManager::WeakChild >
908 : : {
909 : : public:
910 : 20 : AccessibleTextHelper_UpdateChildBounds( AccessibleTextHelper_Impl& rImpl ) : mrImpl(rImpl) {}
911 : 20 : ::accessibility::AccessibleParaManager::WeakChild operator()( const ::accessibility::AccessibleParaManager::WeakChild& rChild )
912 : : {
913 : : // retrieve hard reference from weak one
914 [ + - ]: 20 : ::accessibility::AccessibleParaManager::WeakPara::HardRefType aHardRef( rChild.first.get() );
915 : :
916 [ + + ]: 20 : if( aHardRef.is() )
917 : : {
918 [ + - ]: 10 : awt::Rectangle aNewRect = aHardRef->getBounds();
919 : 10 : const awt::Rectangle& aOldRect = rChild.second;
920 : :
921 [ + - ][ + - ]: 10 : if( aNewRect.X != aOldRect.X ||
[ + + ][ - + ]
922 : : aNewRect.Y != aOldRect.Y ||
923 : : aNewRect.Width != aOldRect.Width ||
924 : : aNewRect.Height != aOldRect.Height )
925 : : {
926 : : // visible data changed
927 [ + - ]: 4 : aHardRef->FireEvent( AccessibleEventId::BOUNDRECT_CHANGED );
928 : :
929 : : // update internal bounds
930 [ + - ]: 10 : return ::accessibility::AccessibleParaManager::WeakChild( rChild.first, aNewRect );
931 : : }
932 : : }
933 : :
934 : : // identity transform
935 [ + - ][ + - ]: 20 : return rChild;
936 : : }
937 : :
938 : : private:
939 : : AccessibleTextHelper_Impl& mrImpl;
940 : : };
941 : :
942 : 20 : void AccessibleTextHelper_Impl::UpdateBoundRect()
943 : : {
944 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
945 : :
946 : : // send BOUNDRECT_CHANGED to affected children
947 : 20 : AccessibleTextHelper_UpdateChildBounds aFunctor( *this );
948 [ + - ][ + - ]: 20 : ::std::transform( maParaManager.begin(), maParaManager.end(), maParaManager.begin(), aFunctor );
[ + - ][ + - ]
949 : 20 : }
950 : :
951 : : #ifdef DBG_UTIL
952 : : void AccessibleTextHelper_Impl::CheckInvariants() const
953 : : {
954 : : if( mnFirstVisibleChild >= 0 &&
955 : : mnFirstVisibleChild > mnLastVisibleChild )
956 : : {
957 : : OSL_FAIL( "AccessibleTextHelper: range invalid" );
958 : : }
959 : : }
960 : : #endif
961 : :
962 : : // functor for sending child events (no stand-alone function, they are maybe not inlined)
963 : : class AccessibleTextHelper_LostChildEvent : public ::std::unary_function< const ::accessibility::AccessibleParaManager::WeakChild&, void >
964 : : {
965 : : public:
966 : 0 : AccessibleTextHelper_LostChildEvent( AccessibleTextHelper_Impl& rImpl ) : mrImpl(rImpl) {}
967 : 0 : void operator()( const ::accessibility::AccessibleParaManager::WeakChild& rPara )
968 : : {
969 : : // retrieve hard reference from weak one
970 [ # # ]: 0 : ::accessibility::AccessibleParaManager::WeakPara::HardRefType aHardRef( rPara.first.get() );
971 : :
972 [ # # ]: 0 : if( aHardRef.is() )
973 [ # # ][ # # ]: 0 : mrImpl.FireEvent(AccessibleEventId::CHILD, uno::Any(), uno::makeAny( aHardRef.getRef() ) );
[ # # ]
974 : 0 : }
975 : :
976 : : private:
977 : : AccessibleTextHelper_Impl& mrImpl;
978 : : };
979 : :
980 : 0 : void AccessibleTextHelper_Impl::ParagraphsMoved( sal_Int32 nFirst, sal_Int32 nMiddle, sal_Int32 nLast )
981 : : {
982 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
983 : :
984 : 0 : const sal_Int32 nParas = GetTextForwarder().GetParagraphCount();
985 : :
986 : : /* rotate paragraphs
987 : : * =================
988 : : *
989 : : * Three cases:
990 : : *
991 : : * 1.
992 : : * ... nParagraph ... nParam1 ... nParam2 ...
993 : : * |______________[xxxxxxxxxxx]
994 : : * becomes
995 : : * [xxxxxxxxxxx]|______________
996 : : *
997 : : * tail is 0
998 : : *
999 : : * 2.
1000 : : * ... nParam1 ... nParagraph ... nParam2 ...
1001 : : * [xxxxxxxxxxx|xxxxxxxxxxxxxx]____________
1002 : : * becomes
1003 : : * ____________[xxxxxxxxxxx|xxxxxxxxxxxxxx]
1004 : : *
1005 : : * tail is nParagraph - nParam1
1006 : : *
1007 : : * 3.
1008 : : * ... nParam1 ... nParam2 ... nParagraph ...
1009 : : * [xxxxxxxxxxx]___________|____________
1010 : : * becomes
1011 : : * ___________|____________[xxxxxxxxxxx]
1012 : : *
1013 : : * tail is nParam2 - nParam1
1014 : : */
1015 : :
1016 : : // sort nParagraph, nParam1 and nParam2 in ascending order, calc range
1017 [ # # ]: 0 : if( nMiddle < nFirst )
1018 : : {
1019 : 0 : ::std::swap(nFirst, nMiddle);
1020 : : }
1021 [ # # ]: 0 : else if( nMiddle < nLast )
1022 : : {
1023 : 0 : nLast = nLast + nMiddle - nFirst;
1024 : : }
1025 : : else
1026 : : {
1027 : 0 : ::std::swap(nMiddle, nLast);
1028 : 0 : nLast = nLast + nMiddle - nFirst;
1029 : : }
1030 : :
1031 [ # # ][ # # ]: 0 : if( nFirst < nParas && nMiddle < nParas && nLast < nParas )
[ # # ]
1032 : : {
1033 : : // since we have no "paragraph index
1034 : : // changed" event on UAA, remove
1035 : : // [first,last] and insert again later (in
1036 : : // UpdateVisibleChildren)
1037 : :
1038 : : // maParaManager.Rotate( nFirst, nMiddle, nLast );
1039 : :
1040 : : // send CHILD_EVENT to affected children
1041 [ # # ][ # # ]: 0 : ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator begin = maParaManager.begin();
1042 : 0 : ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator end = begin;
1043 : :
1044 [ # # ]: 0 : ::std::advance( begin, nFirst );
1045 [ # # ]: 0 : ::std::advance( end, nLast+1 );
1046 : :
1047 : : // TODO: maybe optimize here in the following way. If the
1048 : : // number of removed children exceeds a certain threshold,
1049 : : // use INVALIDATE_CHILDREN
1050 : 0 : AccessibleTextHelper_LostChildEvent aFunctor( *this );
1051 : :
1052 [ # # ]: 0 : ::std::for_each( begin, end, aFunctor );
1053 : :
1054 [ # # ]: 0 : maParaManager.Release(nFirst, nLast+1);
1055 : : // should be no need for UpdateBoundRect, since all affected children are cleared.
1056 : : }
1057 : 0 : }
1058 : :
1059 : : // functor for sending child events (no stand-alone function, they are maybe not inlined)
1060 : : class AccessibleTextHelper_ChildrenTextChanged : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void >
1061 : : {
1062 : : public:
1063 : 0 : void operator()( ::accessibility::AccessibleEditableTextPara& rPara )
1064 : : {
1065 : 0 : rPara.TextChanged();
1066 : 0 : }
1067 : : };
1068 : :
1069 : : /** functor processing queue events
1070 : :
1071 : : Reacts on TEXT_HINT_PARAINSERTED/REMOVED events and stores
1072 : : their content
1073 : : */
1074 : : class AccessibleTextHelper_QueueFunctor : public ::std::unary_function< const SfxHint*, void >
1075 : : {
1076 : : public:
1077 : 9 : AccessibleTextHelper_QueueFunctor() :
1078 : : mnParasChanged( 0 ),
1079 : : mnParaIndex(-1),
1080 : 9 : mnHintId(-1)
1081 : 9 : {}
1082 : 9 : void operator()( const SfxHint* pEvent )
1083 : : {
1084 [ + - ][ + - ]: 9 : if( pEvent &&
1085 : : mnParasChanged != -1 )
1086 : : {
1087 : : // determine hint type
1088 [ + - ][ + + ]: 9 : const TextHint* pTextHint = PTR_CAST( TextHint, pEvent );
1089 [ + - ][ - + ]: 9 : const SvxEditSourceHint* pEditSourceHint = PTR_CAST( SvxEditSourceHint, pEvent );
1090 : :
1091 [ + - ][ + + : 19 : if( !pEditSourceHint && pTextHint &&
+ - - + ]
[ - + ]
1092 : 5 : (pTextHint->GetId() == TEXT_HINT_PARAINSERTED ||
1093 : 5 : pTextHint->GetId() == TEXT_HINT_PARAREMOVED ) )
1094 : : {
1095 [ # # ]: 0 : if( pTextHint->GetValue() == EE_PARA_ALL )
1096 : : {
1097 : 0 : mnParasChanged = -1;
1098 : : }
1099 : : else
1100 : : {
1101 : 0 : mnHintId = pTextHint->GetId();
1102 : 0 : mnParaIndex = pTextHint->GetValue();
1103 : 0 : ++mnParasChanged;
1104 : : }
1105 : : }
1106 : : }
1107 : 9 : }
1108 : :
1109 : : /** Query number of paragraphs changed during queue processing.
1110 : :
1111 : : @return number of changed paragraphs, -1 for
1112 : : "every paragraph changed"
1113 : : */
1114 : 0 : int GetNumberOfParasChanged() { return mnParasChanged; }
1115 : : /** Query index of last added/removed paragraph
1116 : :
1117 : : @return index of lastly added paragraphs, -1 for none
1118 : : added so far.
1119 : : */
1120 : 0 : int GetParaIndex() { return mnParaIndex; }
1121 : : /** Query hint id of last interesting event
1122 : :
1123 : : @return hint id of last interesting event (REMOVED/INSERTED).
1124 : : */
1125 : 0 : int GetHintId() { return mnHintId; }
1126 : :
1127 : : private:
1128 : : /** number of paragraphs changed during queue processing. -1 for
1129 : : "every paragraph changed"
1130 : : */
1131 : : int mnParasChanged;
1132 : : /// index of paragraph added/removed last
1133 : : int mnParaIndex;
1134 : : /// TextHint ID (removed/inserted) of last interesting event
1135 : : int mnHintId;
1136 : : };
1137 : :
1138 : 9 : void AccessibleTextHelper_Impl::ProcessQueue()
1139 : : {
1140 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
1141 : :
1142 : : // inspect queue for paragraph insert/remove events. If there
1143 : : // is exactly _one_ of those in the queue, and the number of
1144 : : // paragraphs has changed by exactly one, use that event to
1145 : : // determine a priori which paragraph was added/removed. This
1146 : : // is necessary, since I must sync right here with the
1147 : : // EditEngine state (number of paragraphs etc.), since I'm
1148 : : // potentially sending listener events right away.
1149 : 9 : AccessibleTextHelper_QueueFunctor aFunctor;
1150 [ + - ]: 9 : maEventQueue.ForEach( aFunctor );
1151 : :
1152 [ + - ][ + - ]: 9 : const sal_Int32 nNewParas( GetTextForwarder().GetParagraphCount() );
1153 [ + - ]: 9 : const sal_Int32 nCurrParas( maParaManager.GetNum() );
1154 : :
1155 : : // whether every paragraph already is updated (no need to
1156 : : // repeat that later on, e.g. for PARA_MOVED events)
1157 : 9 : bool bEverythingUpdated( false );
1158 : :
1159 [ - + # # ]: 9 : if( labs( nNewParas - nCurrParas ) == 1 &&
[ - + ]
1160 : 0 : aFunctor.GetNumberOfParasChanged() == 1 )
1161 : : {
1162 : : // #103483# Exactly one paragraph added/removed. This is
1163 : : // the normal case, optimize event handling here.
1164 : :
1165 [ # # ]: 0 : if( aFunctor.GetHintId() == TEXT_HINT_PARAINSERTED )
1166 : : {
1167 : : // update num of paras
1168 [ # # ]: 0 : maParaManager.SetNum( nNewParas );
1169 : :
1170 : : // release everything from the insertion position until the end
1171 [ # # ]: 0 : maParaManager.Release(aFunctor.GetParaIndex(), nCurrParas);
1172 : :
1173 : : // TODO: Clarify whether this behaviour _really_ saves
1174 : : // anybody anything!
1175 : : // update children, _don't_ broadcast
1176 [ # # ]: 0 : UpdateVisibleChildren( false );
1177 [ # # ]: 0 : UpdateBoundRect();
1178 : :
1179 : : // send insert event
1180 : : // #109864# Enforce creation of this paragraph
1181 : : try
1182 : : {
1183 : 0 : GotPropertyEvent( uno::makeAny( getAccessibleChild( aFunctor.GetParaIndex() -
1184 : 0 : mnFirstVisibleChild + GetStartIndex() ) ),
1185 [ # # ][ # # ]: 0 : AccessibleEventId::CHILD );
[ # # ][ # # ]
1186 : : }
1187 [ # # ]: 0 : catch( const uno::Exception& )
1188 : : {
1189 : : OSL_FAIL("AccessibleTextHelper_Impl::ProcessQueue: could not create new paragraph");
1190 : : }
1191 : : }
1192 [ # # ]: 0 : else if( aFunctor.GetHintId() == TEXT_HINT_PARAREMOVED )
1193 : : {
1194 [ # # ][ # # ]: 0 : ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator begin = maParaManager.begin();
1195 [ # # ]: 0 : ::std::advance( begin, aFunctor.GetParaIndex() );
1196 : 0 : ::accessibility::AccessibleParaManager::VectorOfChildren::const_iterator end = begin;
1197 [ # # ]: 0 : ::std::advance( end, 1 );
1198 : :
1199 : : // #i61812# remember para to be removed for later notification
1200 : : // AFTER the new state is applied (that after the para got removed)
1201 : 0 : ::uno::Reference< XAccessible > xPara;
1202 [ # # ]: 0 : ::accessibility::AccessibleParaManager::WeakPara::HardRefType aHardRef( begin->first.get() );
1203 [ # # ]: 0 : if( aHardRef.is() )
1204 [ # # ][ # # ]: 0 : xPara = ::uno::Reference< XAccessible >( aHardRef.getRef(), ::uno::UNO_QUERY );
1205 : :
1206 : : // release everything from the remove position until the end
1207 [ # # ]: 0 : maParaManager.Release(aFunctor.GetParaIndex(), nCurrParas);
1208 : :
1209 : : // update num of paras
1210 [ # # ]: 0 : maParaManager.SetNum( nNewParas );
1211 : :
1212 : : // TODO: Clarify whether this behaviour _really_ saves
1213 : : // anybody anything!
1214 : : // update children, _don't_ broadcast
1215 [ # # ]: 0 : UpdateVisibleChildren( false );
1216 [ # # ]: 0 : UpdateBoundRect();
1217 : :
1218 : : // #i61812# notification for removed para
1219 [ # # ]: 0 : if (xPara.is())
1220 [ # # ][ # # ]: 0 : FireEvent(AccessibleEventId::CHILD, uno::Any(), uno::makeAny( xPara) );
[ # # ]
1221 : : }
1222 : : #ifdef DBG_UTIL
1223 : : else
1224 : : OSL_FAIL("AccessibleTextHelper_Impl::ProcessQueue() invalid hint id");
1225 : : #endif
1226 : : }
1227 [ - + ]: 9 : else if( nNewParas != nCurrParas )
1228 : : {
1229 : : // release all paras
1230 [ # # ]: 0 : maParaManager.Release(0, nCurrParas);
1231 : :
1232 : : // update num of paras
1233 [ # # ]: 0 : maParaManager.SetNum( nNewParas );
1234 : :
1235 : : // #109864# create from scratch, don't broadcast
1236 [ # # ]: 0 : UpdateVisibleChildren( false );
1237 [ # # ]: 0 : UpdateBoundRect();
1238 : :
1239 : : // number of paragraphs somehow changed - but we have no
1240 : : // chance determining how. Thus, throw away everything and
1241 : : // create from scratch.
1242 : : // (child events should be broadcast after the changes are done...)
1243 [ # # ]: 0 : FireEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN);
1244 : :
1245 : : // no need for further updates later on
1246 : 0 : bEverythingUpdated = true;
1247 : : }
1248 : :
1249 [ + - ][ + + ]: 18 : while( !maEventQueue.IsEmpty() )
1250 : : {
1251 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1252 [ + - ]: 9 : ::std::auto_ptr< SfxHint > pHint( maEventQueue.PopFront() );
[ + - # # ]
1253 : : SAL_WNODEPRECATED_DECLARATIONS_POP
1254 [ + - ]: 9 : if( pHint.get() )
1255 : : {
1256 : 9 : const SfxHint& rHint = *(pHint.get());
1257 : :
1258 : : // determine hint type
1259 [ + - ][ + - ]: 9 : const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
[ + + ][ + - ]
1260 [ + - ][ + - ]: 9 : const SfxSimpleHint* pSimpleHint = PTR_CAST( SfxSimpleHint, &rHint );
[ + - ][ + + ]
1261 [ + - ][ + - ]: 9 : const TextHint* pTextHint = PTR_CAST( TextHint, &rHint );
[ + - ][ + + ]
1262 [ + - ][ + - ]: 9 : const SvxViewHint* pViewHint = PTR_CAST( SvxViewHint, &rHint );
[ + - ][ - + ]
1263 [ + - ][ + - ]: 9 : const SvxEditSourceHint* pEditSourceHint = PTR_CAST( SvxEditSourceHint, &rHint );
[ + - ][ - + ]
1264 : :
1265 : : try
1266 : : {
1267 [ + - ][ + - ]: 9 : const sal_Int32 nParas = GetTextForwarder().GetParagraphCount();
1268 : :
1269 [ - + ]: 9 : if( pEditSourceHint )
1270 : : {
1271 [ # # # ]: 0 : switch( pEditSourceHint->GetId() )
1272 : : {
1273 : : case EDITSOURCE_HINT_PARASMOVED:
1274 : : {
1275 : : DBG_ASSERT( pEditSourceHint->GetStartValue() < GetTextForwarder().GetParagraphCount() &&
1276 : : pEditSourceHint->GetEndValue() < GetTextForwarder().GetParagraphCount(),
1277 : : "AccessibleTextHelper_Impl::NotifyHdl: Invalid notification");
1278 : :
1279 [ # # ]: 0 : if( !bEverythingUpdated )
1280 : : {
1281 [ # # ]: 0 : ParagraphsMoved(pEditSourceHint->GetStartValue(),
1282 [ # # ]: 0 : pEditSourceHint->GetValue(),
1283 [ # # ][ # # ]: 0 : pEditSourceHint->GetEndValue());
1284 : :
1285 : : // in all cases, check visibility afterwards.
1286 [ # # ]: 0 : UpdateVisibleChildren();
1287 : : }
1288 : 0 : break;
1289 : : }
1290 : :
1291 : : case EDITSOURCE_HINT_SELECTIONCHANGED:
1292 : : // notify listeners
1293 : : try
1294 : : {
1295 [ # # ]: 0 : UpdateSelection();
1296 : : }
1297 : : // maybe we're not in edit mode (this is not an error)
1298 [ # # ]: 0 : catch( const uno::Exception& ) {}
1299 : 0 : break;
1300 : : }
1301 : : }
1302 [ + + ]: 9 : else if( pTextHint )
1303 : : {
1304 [ - - - + : 5 : switch( pTextHint->GetId() )
- - ]
1305 : : {
1306 : : case TEXT_HINT_MODIFIED:
1307 : : {
1308 : : // notify listeners
1309 : 0 : sal_Int32 nPara( pTextHint->GetValue() );
1310 : :
1311 : : // #108900# Delegate change event to children
1312 : : AccessibleTextHelper_ChildrenTextChanged aNotifyChildrenFunctor;
1313 : :
1314 [ # # ]: 0 : if( nPara == static_cast<sal_Int32>(EE_PARA_ALL) )
1315 : : {
1316 : : // #108900# Call every child
1317 : : ::std::for_each( maParaManager.begin(), maParaManager.end(),
1318 [ # # ][ # # ]: 0 : AccessibleParaManager::WeakChildAdapter< AccessibleTextHelper_ChildrenTextChanged > (aNotifyChildrenFunctor) );
[ # # ]
1319 : : }
1320 : : else
1321 [ # # ]: 0 : if( nPara < nParas )
1322 : : {
1323 : : // #108900# Call child at index nPara
1324 [ # # ]: 0 : ::std::for_each( maParaManager.begin()+nPara, maParaManager.begin()+nPara+1,
1325 [ # # ][ # # ]: 0 : AccessibleParaManager::WeakChildAdapter< AccessibleTextHelper_ChildrenTextChanged > (aNotifyChildrenFunctor) );
[ # # ][ # # ]
[ # # ][ # # ]
1326 : : }
1327 : : break;
1328 : : }
1329 : :
1330 : : case TEXT_HINT_PARAINSERTED:
1331 : : // already happened above
1332 : 0 : break;
1333 : :
1334 : : case TEXT_HINT_PARAREMOVED:
1335 : : // already happened above
1336 : 0 : break;
1337 : :
1338 : : case TEXT_HINT_TEXTHEIGHTCHANGED:
1339 : : // visibility changed, done below
1340 : 5 : break;
1341 : :
1342 : : case TEXT_HINT_VIEWSCROLLED:
1343 : : // visibility changed, done below
1344 : 0 : break;
1345 : : }
1346 : :
1347 : : // in all cases, check visibility afterwards.
1348 [ + - ]: 5 : UpdateVisibleChildren();
1349 [ + - ]: 5 : UpdateBoundRect();
1350 : : }
1351 [ - + ]: 4 : else if( pViewHint )
1352 : : {
1353 [ # # ][ # # ]: 0 : switch( pViewHint->GetHintType() )
1354 : : {
1355 : : case SvxViewHint::SVX_HINT_VIEWCHANGED:
1356 : : // just check visibility
1357 [ # # ]: 0 : UpdateVisibleChildren();
1358 [ # # ]: 0 : UpdateBoundRect();
1359 : 0 : break;
1360 : : }
1361 : : }
1362 [ + - ]: 4 : else if( pSdrHint )
1363 : : {
1364 [ + - ]: 4 : switch( pSdrHint->GetKind() )
[ - - + ]
1365 : : {
1366 : : case HINT_BEGEDIT:
1367 : : {
1368 : : // change children state
1369 [ # # ]: 0 : maParaManager.SetActive();
1370 : :
1371 : : // per definition, edit mode text has the focus
1372 [ # # ]: 0 : SetFocus( sal_True );
1373 : 0 : break;
1374 : : }
1375 : :
1376 : : case HINT_ENDEDIT:
1377 : : {
1378 : : // focused child now looses focus
1379 : 0 : ESelection aSelection;
1380 [ # # ][ # # ]: 0 : if( GetEditViewForwarder().GetSelection( aSelection ) )
[ # # ]
1381 [ # # ]: 0 : SetChildFocus( aSelection.nEndPara, sal_False );
1382 : :
1383 : : // change children state
1384 [ # # ]: 0 : maParaManager.SetActive( sal_False );
1385 : :
1386 : : maLastSelection = ESelection( EE_PARA_NOT_FOUND, EE_PARA_NOT_FOUND,
1387 : 0 : EE_PARA_NOT_FOUND, EE_PARA_NOT_FOUND);
1388 : : break;
1389 : : }
1390 : : default:
1391 : 4 : break;
1392 : : }
1393 : : }
1394 : : // it's VITAL to keep the SfxSimpleHint last! It's the base of some classes above!
1395 [ # # ]: 0 : else if( pSimpleHint )
1396 : : {
1397 [ # # ]: 0 : switch( pSimpleHint->GetId() )
1398 : : {
1399 : : case SFX_HINT_DYING:
1400 : : // edit source is dying under us, become defunc then
1401 : : try
1402 : : {
1403 : : // make edit source inaccessible
1404 : : // Note: cannot destroy it here, since we're called from there!
1405 [ # # ]: 0 : ShutdownEditSource();
1406 : : }
1407 [ # # # # ]: 0 : catch( const uno::Exception& ) {}
1408 : :
1409 : 0 : break;
1410 : : }
1411 : : }
1412 : : }
1413 [ # # ]: 0 : catch( const uno::Exception& )
1414 : : {
1415 : : #ifdef DBG_UTIL
1416 : : OSL_TRACE("AccessibleTextHelper_Impl::ProcessQueue: Unhandled exception.");
1417 : : #endif
1418 : : }
1419 : : }
1420 [ + - ]: 9 : }
1421 : 9 : }
1422 : :
1423 : 19 : void AccessibleTextHelper_Impl::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
1424 : : {
1425 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
1426 : :
1427 : : // precondition: solar mutex locked
1428 : : DBG_TESTSOLARMUTEX();
1429 : :
1430 : : // precondition: not in a recursion
1431 [ - + ]: 19 : if( mbInNotify )
1432 [ # # ]: 19 : return;
1433 : :
1434 : 19 : mbInNotify = sal_True;
1435 : :
1436 : : // determine hint type
1437 [ + - ][ + + ]: 19 : const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
1438 [ + - ][ + + ]: 19 : const SfxSimpleHint* pSimpleHint = PTR_CAST( SfxSimpleHint, &rHint );
1439 [ + - ][ + + ]: 19 : const TextHint* pTextHint = PTR_CAST( TextHint, &rHint );
1440 [ + - ][ - + ]: 19 : const SvxViewHint* pViewHint = PTR_CAST( SvxViewHint, &rHint );
1441 [ + - ][ - + ]: 19 : const SvxEditSourceHint* pEditSourceHint = PTR_CAST( SvxEditSourceHint, &rHint );
1442 : :
1443 : : try
1444 : : {
1445 : : // Process notification event
1446 [ - + ]: 19 : if( pEditSourceHint )
1447 : : {
1448 [ # # ]: 0 : maEventQueue.Append( *pEditSourceHint );
1449 : : // EditEngine should emit TEXT_SELECTION_CHANGED events (#i27299#)
1450 [ # # ]: 0 : if( maEventOpenFrames == 0 )
1451 [ # # ]: 0 : ProcessQueue();
1452 : : }
1453 [ + + ]: 19 : else if( pTextHint )
1454 : : {
1455 [ + + + ]: 15 : switch( pTextHint->GetId() )
1456 : : {
1457 : : case TEXT_HINT_BLOCKNOTIFICATION_END:
1458 : : case TEXT_HINT_INPUT_END:
1459 : 5 : --maEventOpenFrames;
1460 : :
1461 [ + - ]: 5 : if( maEventOpenFrames == 0 )
1462 : : {
1463 : : // #103483#
1464 : : /* All information should have arrived
1465 : : * now, process queue. As stated in the
1466 : : * above bug, we can often avoid throwing
1467 : : * away all paragraphs by looking forward
1468 : : * in the event queue (searching for
1469 : : * PARAINSERT/REMOVE events). Furthermore,
1470 : : * processing the event queue only at the
1471 : : * end of an interaction cycle, ensures
1472 : : * that the EditEngine state and the
1473 : : * AccessibleText state are the same
1474 : : * (well, mostly. If there are _multiple_
1475 : : * interaction cycles in the EE queues, it
1476 : : * can still happen that EE state is
1477 : : * different. That's so to say broken by
1478 : : * design with that delayed EE event
1479 : : * concept).
1480 : : */
1481 [ + - ]: 5 : ProcessQueue();
1482 : : }
1483 : 5 : break;
1484 : :
1485 : : case TEXT_HINT_BLOCKNOTIFICATION_START:
1486 : : case TEXT_HINT_INPUT_START:
1487 : 5 : ++maEventOpenFrames;
1488 : : // no FALLTHROUGH reason: event will not be processed,
1489 : : // thus appending the event isn't necessary. (#i27299#)
1490 : 5 : break;
1491 : : default:
1492 [ + - ]: 5 : maEventQueue.Append( *pTextHint );
1493 : : // EditEngine should emit TEXT_SELECTION_CHANGED events (#i27299#)
1494 [ - + ]: 5 : if( maEventOpenFrames == 0 )
1495 [ # # ]: 0 : ProcessQueue();
1496 : 15 : break;
1497 : : }
1498 : : }
1499 [ - + ]: 4 : else if( pViewHint )
1500 : : {
1501 [ # # ]: 0 : maEventQueue.Append( *pViewHint );
1502 : :
1503 : : // process visibility right away, if not within an
1504 : : // open EE notification frame. Otherwise, event
1505 : : // processing would be delayed until next EE
1506 : : // notification sequence.
1507 [ # # ]: 0 : if( maEventOpenFrames == 0 )
1508 [ # # ]: 0 : ProcessQueue();
1509 : : }
1510 [ + - ]: 4 : else if( pSdrHint )
1511 : : {
1512 [ + - ]: 4 : maEventQueue.Append( *pSdrHint );
1513 : :
1514 : : // process drawing layer events right away, if not
1515 : : // within an open EE notification frame. Otherwise,
1516 : : // event processing would be delayed until next EE
1517 : : // notification sequence.
1518 [ + - ]: 4 : if( maEventOpenFrames == 0 )
1519 [ + - ]: 4 : ProcessQueue();
1520 : : }
1521 : : // it's VITAL to keep the SfxSimpleHint last! It's the base of some classes above!
1522 [ # # ]: 0 : else if( pSimpleHint )
1523 : : {
1524 : : // handle this event _at once_, because after that, objects are invalid
1525 [ # # ]: 0 : switch( pSimpleHint->GetId() )
1526 : : {
1527 : : case SFX_HINT_DYING:
1528 : : // edit source is dying under us, become defunc then
1529 [ # # ]: 0 : maEventQueue.Clear();
1530 : : try
1531 : : {
1532 : : // make edit source inaccessible
1533 : : // Note: cannot destroy it here, since we're called from there!
1534 [ # # ]: 0 : ShutdownEditSource();
1535 : : }
1536 [ # # # # ]: 0 : catch( const uno::Exception& ) {}
1537 : :
1538 : 0 : break;
1539 : : }
1540 : : }
1541 : : }
1542 : 0 : catch( const uno::Exception& )
1543 : : {
1544 : : #ifdef DBG_UTIL
1545 : : OSL_TRACE("AccessibleTextHelper_Impl::Notify: Unhandled exception.");
1546 : : #endif
1547 : 0 : mbInNotify = sal_False;
1548 : : }
1549 : :
1550 : 19 : mbInNotify = sal_False;
1551 : : }
1552 : :
1553 : 57 : void AccessibleTextHelper_Impl::Dispose()
1554 : : {
1555 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
1556 : :
1557 [ + + ]: 57 : if( getNotifierClientId() != -1 )
1558 : : {
1559 : : try
1560 : : {
1561 : : // #106234# Unregister from EventNotifier
1562 [ + - ]: 45 : ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() );
1563 : : #ifdef DBG_UTIL
1564 : : OSL_TRACE( "AccessibleTextHelper_Impl disposed ID: %d", mnNotifierClientId );
1565 : : #endif
1566 : : }
1567 [ # # ]: 0 : catch( const uno::Exception& ) {}
1568 : :
1569 : 45 : mnNotifierClientId = -1;
1570 : : }
1571 : :
1572 : : try
1573 : : {
1574 : : // dispose children
1575 [ + - ]: 57 : maParaManager.Dispose();
1576 : : }
1577 : 0 : catch( const uno::Exception& ) {}
1578 : :
1579 : : // quit listen on stale edit source
1580 [ + + ]: 57 : if( maEditSource.IsValid() )
1581 : 41 : EndListening( maEditSource.GetBroadcaster() );
1582 : :
1583 : : // clear references
1584 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1585 [ + - ][ + - ]: 57 : maEditSource.SetEditSource( ::std::auto_ptr< SvxEditSource >(NULL) );
1586 : : SAL_WNODEPRECATED_DECLARATIONS_POP
1587 : 57 : mxFrontEnd = NULL;
1588 [ # # ]: 57 : }
1589 : :
1590 : 7 : void AccessibleTextHelper_Impl::FireEvent( const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue ) const
1591 : : {
1592 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
1593 : :
1594 : : // -- object locked --
1595 [ + - ]: 7 : ::osl::ClearableMutexGuard aGuard( maMutex );
1596 : :
1597 [ + - ]: 7 : AccessibleEventObject aEvent;
1598 : :
1599 : : DBG_ASSERT(mxFrontEnd.is(), "AccessibleTextHelper::FireEvent: no event source set" );
1600 : :
1601 [ + - ]: 7 : if( mxFrontEnd.is() )
1602 [ + - ][ + - ]: 7 : aEvent = AccessibleEventObject(mxFrontEnd->getAccessibleContext(), nEventId, rNewValue, rOldValue);
[ + - ][ + - ]
[ + - ]
1603 : : else
1604 [ # # ][ # # ]: 0 : aEvent = AccessibleEventObject(uno::Reference< uno::XInterface >(), nEventId, rNewValue, rOldValue);
[ # # ]
1605 : :
1606 : : // no locking necessary, FireEvent internally copies listeners
1607 : : // if someone removes/adds in between Further locking,
1608 : : // actually, might lead to deadlocks, since we're calling out
1609 : : // of this object
1610 [ + - ]: 7 : aGuard.clear();
1611 : : // -- until here --
1612 : :
1613 [ + - ][ + - ]: 7 : FireEvent(aEvent);
[ + - ]
1614 : 7 : }
1615 : :
1616 : 7 : void AccessibleTextHelper_Impl::FireEvent( const AccessibleEventObject& rEvent ) const
1617 : : {
1618 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
1619 : :
1620 : : // #102261# Call global queue for focus events
1621 [ - + ]: 7 : if( rEvent.EventId == AccessibleStateType::FOCUSED )
1622 : 0 : vcl::unohelper::NotifyAccessibleStateEventGlobally( rEvent );
1623 : :
1624 : : // #106234# Delegate to EventNotifier
1625 : 7 : ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(),
1626 : 7 : rEvent );
1627 : 7 : }
1628 : :
1629 : : // XAccessibleContext
1630 : 198 : sal_Int32 SAL_CALL AccessibleTextHelper_Impl::getAccessibleChildCount() SAL_THROW((uno::RuntimeException))
1631 : : {
1632 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
1633 : :
1634 : 198 : return mnLastVisibleChild - mnFirstVisibleChild + 1;
1635 : : }
1636 : :
1637 : 60 : uno::Reference< XAccessible > SAL_CALL AccessibleTextHelper_Impl::getAccessibleChild( sal_Int32 i ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
1638 : : {
1639 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
1640 : :
1641 : 60 : i -= GetStartIndex();
1642 : :
1643 [ + - - + ]: 120 : if( 0 > i || i >= getAccessibleChildCount() ||
[ - + ][ + - ]
1644 : 60 : GetTextForwarder().GetParagraphCount() <= i )
1645 : : {
1646 [ # # ][ # # ]: 0 : throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid child index")), mxFrontEnd);
1647 : : }
1648 : :
1649 : : DBG_ASSERT(mxFrontEnd.is(), "AccessibleTextHelper_Impl::UpdateVisibleChildren: no frontend set");
1650 : :
1651 [ + - ]: 60 : if( mxFrontEnd.is() )
1652 : 60 : return maParaManager.CreateChild( i, mxFrontEnd, GetEditSource(), mnFirstVisibleChild + i ).first;
1653 : : else
1654 : 60 : return NULL;
1655 : : }
1656 : :
1657 : 2 : void SAL_CALL AccessibleTextHelper_Impl::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) SAL_THROW((uno::RuntimeException))
1658 : : {
1659 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
1660 : :
1661 [ + - ]: 2 : if( getNotifierClientId() != -1 )
1662 : 2 : ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener );
1663 : 2 : }
1664 : :
1665 : 2 : void SAL_CALL AccessibleTextHelper_Impl::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) SAL_THROW((uno::RuntimeException))
1666 : : {
1667 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
1668 : :
1669 [ + - ]: 2 : if( getNotifierClientId() != -1 )
1670 : 2 : ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener );
1671 : 2 : }
1672 : :
1673 : 6 : uno::Reference< XAccessible > SAL_CALL AccessibleTextHelper_Impl::getAccessibleAtPoint( const awt::Point& _aPoint ) SAL_THROW((uno::RuntimeException))
1674 : : {
1675 : : DBG_CHKTHIS( AccessibleTextHelper_Impl, NULL );
1676 : :
1677 : : // make given position relative
1678 [ - + ]: 6 : if( !mxFrontEnd.is() )
1679 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleTextHelper_Impl::getAccessibleAt: frontend invalid")), mxFrontEnd );
1680 : :
1681 [ + - ][ + - ]: 6 : uno::Reference< XAccessibleContext > xFrontEndContext = mxFrontEnd->getAccessibleContext();
1682 : :
1683 [ - + ]: 6 : if( !xFrontEndContext.is() )
1684 [ # # ][ # # ]: 0 : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleTextHelper_Impl::getAccessibleAt: frontend invalid")), mxFrontEnd );
1685 : :
1686 [ + - ]: 6 : uno::Reference< XAccessibleComponent > xFrontEndComponent( xFrontEndContext, uno::UNO_QUERY );
1687 : :
1688 [ - + ]: 6 : if( !xFrontEndComponent.is() )
1689 : : throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleTextHelper_Impl::getAccessibleAt: frontend is no XAccessibleComponent")),
1690 [ # # ][ # # ]: 0 : mxFrontEnd );
1691 : :
1692 : : // #103862# No longer need to make given position relative
1693 : 6 : Point aPoint( _aPoint.X, _aPoint.Y );
1694 : :
1695 : : // respect EditEngine offset to surrounding shape/cell
1696 [ + - ]: 6 : aPoint -= GetOffset();
1697 : :
1698 : : // convert to EditEngine coordinate system
1699 [ + - ]: 6 : SvxTextForwarder& rCacheTF = GetTextForwarder();
1700 [ + - ][ + - ]: 6 : Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
[ + - ][ + - ]
1701 : :
1702 : : // iterate over all visible children (including those not yet created)
1703 : : sal_Int32 nChild;
1704 [ + + ]: 12 : for( nChild=mnFirstVisibleChild; nChild <= mnLastVisibleChild; ++nChild )
1705 : : {
1706 : : DBG_ASSERT(nChild >= 0 && nChild <= USHRT_MAX,
1707 : : "AccessibleTextHelper_Impl::getAccessibleAt: index value overflow");
1708 : :
1709 [ + - ]: 6 : Rectangle aParaBounds( rCacheTF.GetParaBounds( static_cast< sal_uInt16 > (nChild) ) );
1710 : :
1711 [ + - ][ + + ]: 6 : if( aParaBounds.IsInside( aLogPoint ) )
1712 [ + - ]: 4 : return getAccessibleChild( nChild - mnFirstVisibleChild + GetStartIndex() );
1713 : : }
1714 : :
1715 : : // found none
1716 [ + - ]: 6 : return NULL;
1717 : : }
1718 : :
1719 : : //------------------------------------------------------------------------
1720 : : //
1721 : : // AccessibleTextHelper implementation (simply forwards to impl)
1722 : : //
1723 : : //------------------------------------------------------------------------
1724 : :
1725 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1726 : 56 : AccessibleTextHelper::AccessibleTextHelper( ::std::auto_ptr< SvxEditSource > pEditSource ) :
1727 [ + - ]: 56 : mpImpl( new AccessibleTextHelper_Impl() )
1728 : : {
1729 [ + - ]: 56 : SolarMutexGuard aGuard;
1730 : :
1731 [ + - ][ + - ]: 56 : SetEditSource( pEditSource );
[ + - ]
1732 : 56 : }
1733 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1734 : :
1735 : 45 : AccessibleTextHelper::~AccessibleTextHelper()
1736 : : {
1737 [ - + ]: 90 : }
1738 : :
1739 : 0 : const SvxEditSource& AccessibleTextHelper::GetEditSource() const SAL_THROW((uno::RuntimeException))
1740 : : {
1741 : : #ifdef DBG_UTIL
1742 : : mpImpl->CheckInvariants();
1743 : :
1744 : : const SvxEditSource& aEditSource = mpImpl->GetEditSource();
1745 : :
1746 : : mpImpl->CheckInvariants();
1747 : :
1748 : : return aEditSource;
1749 : : #else
1750 : 0 : return mpImpl->GetEditSource();
1751 : : #endif
1752 : : }
1753 : :
1754 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1755 : 60 : void AccessibleTextHelper::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException))
1756 : : {
1757 : : #ifdef DBG_UTIL
1758 : : // precondition: solar mutex locked
1759 : : DBG_TESTSOLARMUTEX();
1760 : :
1761 : : mpImpl->CheckInvariants();
1762 : : #endif
1763 : :
1764 [ + - ]: 60 : mpImpl->SetEditSource( pEditSource );
1765 : :
1766 : : #ifdef DBG_UTIL
1767 : : mpImpl->CheckInvariants();
1768 : : #endif
1769 : 60 : }
1770 : : SAL_WNODEPRECATED_DECLARATIONS_POP
1771 : :
1772 : 56 : void AccessibleTextHelper::SetEventSource( const uno::Reference< XAccessible >& rInterface )
1773 : : {
1774 : : #ifdef DBG_UTIL
1775 : : mpImpl->CheckInvariants();
1776 : : #endif
1777 : :
1778 : 56 : mpImpl->SetEventSource( rInterface );
1779 : :
1780 : : #ifdef DBG_UTIL
1781 : : mpImpl->CheckInvariants();
1782 : : #endif
1783 : 56 : }
1784 : :
1785 : 0 : uno::Reference< XAccessible > AccessibleTextHelper::GetEventSource() const
1786 : : {
1787 : : #ifdef DBG_UTIL
1788 : : mpImpl->CheckInvariants();
1789 : :
1790 : : uno::Reference< XAccessible > xRet( mpImpl->GetEventSource() );
1791 : :
1792 : : mpImpl->CheckInvariants();
1793 : :
1794 : : return xRet;
1795 : : #else
1796 : 0 : return mpImpl->GetEventSource();
1797 : : #endif
1798 : : }
1799 : :
1800 : 2 : void AccessibleTextHelper::SetFocus( sal_Bool bHaveFocus ) SAL_THROW((::com::sun::star::uno::RuntimeException))
1801 : : {
1802 : : #ifdef DBG_UTIL
1803 : : // precondition: solar mutex locked
1804 : : DBG_TESTSOLARMUTEX();
1805 : :
1806 : : mpImpl->CheckInvariants();
1807 : : #endif
1808 : :
1809 : 2 : mpImpl->SetFocus( bHaveFocus );
1810 : :
1811 : : #ifdef DBG_UTIL
1812 : : mpImpl->CheckInvariants();
1813 : : #endif
1814 : 2 : }
1815 : :
1816 : 12 : sal_Bool AccessibleTextHelper::HaveFocus() SAL_THROW((::com::sun::star::uno::RuntimeException))
1817 : : {
1818 : : #ifdef DBG_UTIL
1819 : : mpImpl->CheckInvariants();
1820 : :
1821 : : sal_Bool bRet( mpImpl->HaveFocus() );
1822 : :
1823 : : mpImpl->CheckInvariants();
1824 : :
1825 : : return bRet;
1826 : : #else
1827 : 12 : return mpImpl->HaveFocus();
1828 : : #endif
1829 : : }
1830 : :
1831 : 0 : void AccessibleTextHelper::FireEvent( const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue ) const
1832 : : {
1833 : : #ifdef DBG_UTIL
1834 : : mpImpl->CheckInvariants();
1835 : : #endif
1836 : :
1837 : 0 : mpImpl->FireEvent( nEventId, rNewValue, rOldValue );
1838 : :
1839 : : #ifdef DBG_UTIL
1840 : : mpImpl->CheckInvariants();
1841 : : #endif
1842 : 0 : }
1843 : :
1844 : 0 : void AccessibleTextHelper::FireEvent( const AccessibleEventObject& rEvent ) const
1845 : : {
1846 : : #ifdef DBG_UTIL
1847 : : mpImpl->CheckInvariants();
1848 : : #endif
1849 : :
1850 : 0 : mpImpl->FireEvent( rEvent );
1851 : :
1852 : : #ifdef DBG_UTIL
1853 : : mpImpl->CheckInvariants();
1854 : : #endif
1855 : 0 : }
1856 : :
1857 : 0 : void AccessibleTextHelper::SetOffset( const Point& rPoint )
1858 : : {
1859 : : #ifdef DBG_UTIL
1860 : : // precondition: solar mutex locked
1861 : : DBG_TESTSOLARMUTEX();
1862 : :
1863 : : mpImpl->CheckInvariants();
1864 : : #endif
1865 : :
1866 : 0 : mpImpl->SetOffset( rPoint );
1867 : :
1868 : : #ifdef DBG_UTIL
1869 : : mpImpl->CheckInvariants();
1870 : : #endif
1871 : 0 : }
1872 : :
1873 : 0 : Point AccessibleTextHelper::GetOffset() const
1874 : : {
1875 : : #ifdef DBG_UTIL
1876 : : mpImpl->CheckInvariants();
1877 : :
1878 : : Point aPoint( mpImpl->GetOffset() );
1879 : :
1880 : : mpImpl->CheckInvariants();
1881 : :
1882 : : return aPoint;
1883 : : #else
1884 : 0 : return mpImpl->GetOffset();
1885 : : #endif
1886 : : }
1887 : :
1888 : 0 : void AccessibleTextHelper::SetStartIndex( sal_Int32 nOffset )
1889 : : {
1890 : : #ifdef DBG_UTIL
1891 : : // precondition: solar mutex locked
1892 : : DBG_TESTSOLARMUTEX();
1893 : :
1894 : : mpImpl->CheckInvariants();
1895 : : #endif
1896 : :
1897 : 0 : mpImpl->SetStartIndex( nOffset );
1898 : :
1899 : : #ifdef DBG_UTIL
1900 : : mpImpl->CheckInvariants();
1901 : : #endif
1902 : 0 : }
1903 : :
1904 : 0 : sal_Int32 AccessibleTextHelper::GetStartIndex() const
1905 : : {
1906 : : #ifdef DBG_UTIL
1907 : : mpImpl->CheckInvariants();
1908 : :
1909 : : sal_Int32 nOffset = mpImpl->GetStartIndex();
1910 : :
1911 : : mpImpl->CheckInvariants();
1912 : :
1913 : : return nOffset;
1914 : : #else
1915 : 0 : return mpImpl->GetStartIndex();
1916 : : #endif
1917 : : }
1918 : :
1919 : 15 : void AccessibleTextHelper::SetAdditionalChildStates( const VectorOfStates& rChildStates )
1920 : : {
1921 : 15 : mpImpl->SetAdditionalChildStates( rChildStates );
1922 : 15 : }
1923 : :
1924 : 15 : void AccessibleTextHelper::UpdateChildren() SAL_THROW((::com::sun::star::uno::RuntimeException))
1925 : : {
1926 : : #ifdef DBG_UTIL
1927 : : // precondition: solar mutex locked
1928 : : DBG_TESTSOLARMUTEX();
1929 : :
1930 : : mpImpl->CheckInvariants();
1931 : : #endif
1932 : :
1933 : 15 : mpImpl->UpdateVisibleChildren();
1934 : 15 : mpImpl->UpdateBoundRect();
1935 : :
1936 : 15 : mpImpl->UpdateSelection();
1937 : :
1938 : : #ifdef DBG_UTIL
1939 : : mpImpl->CheckInvariants();
1940 : : #endif
1941 : 15 : }
1942 : :
1943 : 12 : void AccessibleTextHelper::Dispose()
1944 : : {
1945 : : // As Dispose calls ShutdownEditSource, which in turn
1946 : : // deregisters as listener on the edit source, have to lock
1947 : : // here
1948 [ + - ]: 12 : SolarMutexGuard aGuard;
1949 : :
1950 : : #ifdef DBG_UTIL
1951 : : mpImpl->CheckInvariants();
1952 : : #endif
1953 : :
1954 [ + - ][ + - ]: 12 : mpImpl->Dispose();
1955 : :
1956 : : #ifdef DBG_UTIL
1957 : : mpImpl->CheckInvariants();
1958 : : #endif
1959 : 12 : }
1960 : :
1961 : 0 : sal_Bool AccessibleTextHelper::IsSelected() const
1962 : : {
1963 [ # # ]: 0 : SolarMutexGuard aGuard;
1964 : :
1965 : : #ifdef DBG_UTIL
1966 : : mpImpl->CheckInvariants();
1967 : :
1968 : : sal_Bool aRet = mpImpl->IsSelected();
1969 : :
1970 : : mpImpl->CheckInvariants();
1971 : :
1972 : : return aRet;
1973 : : #else
1974 [ # # ][ # # ]: 0 : return mpImpl->IsSelected();
1975 : : #endif
1976 : : }
1977 : :
1978 : : // XAccessibleContext
1979 : 138 : sal_Int32 AccessibleTextHelper::GetChildCount() SAL_THROW((uno::RuntimeException))
1980 : : {
1981 [ + - ]: 138 : SolarMutexGuard aGuard;
1982 : :
1983 : : #ifdef DBG_UTIL
1984 : : mpImpl->CheckInvariants();
1985 : :
1986 : : sal_Int32 nRet = mpImpl->getAccessibleChildCount();
1987 : :
1988 : : mpImpl->CheckInvariants();
1989 : :
1990 : : return nRet;
1991 : : #else
1992 [ + - ]: 138 : return mpImpl->getAccessibleChildCount();
1993 : : #endif
1994 : : }
1995 : :
1996 : 56 : uno::Reference< XAccessible > AccessibleTextHelper::GetChild( sal_Int32 i ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
1997 : : {
1998 [ + - ]: 56 : SolarMutexGuard aGuard;
1999 : :
2000 : : #ifdef DBG_UTIL
2001 : : mpImpl->CheckInvariants();
2002 : :
2003 : : uno::Reference< XAccessible > xRet = mpImpl->getAccessibleChild( i );
2004 : :
2005 : : mpImpl->CheckInvariants();
2006 : :
2007 : : return xRet;
2008 : : #else
2009 [ + - ][ + - ]: 56 : return mpImpl->getAccessibleChild( i );
2010 : : #endif
2011 : : }
2012 : :
2013 : 2 : void AccessibleTextHelper::AddEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) SAL_THROW((uno::RuntimeException))
2014 : : {
2015 : : #ifdef DBG_UTIL
2016 : : mpImpl->CheckInvariants();
2017 : :
2018 : : mpImpl->addEventListener( xListener );
2019 : :
2020 : : mpImpl->CheckInvariants();
2021 : : #else
2022 : 2 : mpImpl->addEventListener( xListener );
2023 : : #endif
2024 : 2 : }
2025 : :
2026 : 2 : void AccessibleTextHelper::RemoveEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) SAL_THROW((uno::RuntimeException))
2027 : : {
2028 : : #ifdef DBG_UTIL
2029 : : mpImpl->CheckInvariants();
2030 : :
2031 : : mpImpl->removeEventListener( xListener );
2032 : :
2033 : : mpImpl->CheckInvariants();
2034 : : #else
2035 : 2 : mpImpl->removeEventListener( xListener );
2036 : : #endif
2037 : 2 : }
2038 : :
2039 : : // XAccessibleComponent
2040 : 6 : uno::Reference< XAccessible > AccessibleTextHelper::GetAt( const awt::Point& aPoint ) SAL_THROW((uno::RuntimeException))
2041 : : {
2042 [ + - ]: 6 : SolarMutexGuard aGuard;
2043 : :
2044 : : #ifdef DBG_UTIL
2045 : : mpImpl->CheckInvariants();
2046 : :
2047 : : uno::Reference< XAccessible > xChild = mpImpl->getAccessibleAtPoint( aPoint );
2048 : :
2049 : : mpImpl->CheckInvariants();
2050 : :
2051 : : return xChild;
2052 : : #else
2053 [ + - ][ + - ]: 6 : return mpImpl->getAccessibleAtPoint( aPoint );
2054 : : #endif
2055 : : }
2056 : :
2057 : : } // end of namespace accessibility
2058 : :
2059 : : //------------------------------------------------------------------------
2060 : :
2061 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|