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 <vector>
38 : : #include <algorithm>
39 : : #include <boost/ref.hpp>
40 : : #include <osl/mutex.hxx>
41 : : #include <vcl/window.hxx>
42 : : #include <vcl/svapp.hxx>
43 : : #include <comphelper/sequenceasvector.hxx>
44 : : #include <com/sun/star/uno/Any.hxx>
45 : : #include <com/sun/star/uno/Reference.hxx>
46 : : #include <com/sun/star/awt/Point.hpp>
47 : : #include <com/sun/star/awt/Rectangle.hpp>
48 : : #include <com/sun/star/accessibility/AccessibleTextType.hpp>
49 : :
50 : : //------------------------------------------------------------------------
51 : : //
52 : : // Project-local header
53 : : //
54 : : //------------------------------------------------------------------------
55 : :
56 : : #include <editeng/editdata.hxx>
57 : : #include <editeng/unopracc.hxx>
58 : : #include "editeng/unoedprx.hxx"
59 : : #include <editeng/AccessibleStaticTextBase.hxx>
60 : : #include "editeng/AccessibleEditableTextPara.hxx"
61 : :
62 : :
63 : : using namespace ::com::sun::star;
64 : : using namespace ::com::sun::star::accessibility;
65 : :
66 : : /* TODO:
67 : : =====
68 : :
69 : : - separate adapter functionality from AccessibleStaticText class
70 : :
71 : : - refactor common loops into templates, using mem_fun
72 : :
73 : : */
74 : :
75 : : namespace accessibility
76 : : {
77 : : typedef ::comphelper::SequenceAsVector< beans::PropertyValue > PropertyValueVector;
78 : :
79 : : class PropertyValueEqualFunctor : public ::std::binary_function< beans::PropertyValue, beans::PropertyValue, bool >
80 : : {
81 : : public:
82 : 0 : PropertyValueEqualFunctor()
83 : 0 : {}
84 : 0 : bool operator() ( const beans::PropertyValue& lhs, const beans::PropertyValue& rhs ) const
85 : : {
86 [ # # ][ # # ]: 0 : return ( lhs.Name == rhs.Name && lhs.Value == rhs.Value );
87 : : }
88 : : };
89 : :
90 : : //------------------------------------------------------------------------
91 : : //
92 : : // Static Helper
93 : : //
94 : : //------------------------------------------------------------------------
95 : 0 : ESelection MakeSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
96 : : sal_Int32 nEndPara, sal_Int32 nEndIndex )
97 : : {
98 : : DBG_ASSERT(nStartPara >= 0 && nStartPara <= USHRT_MAX &&
99 : : nStartIndex >= 0 && nStartIndex <= USHRT_MAX &&
100 : : nEndPara >= 0 && nEndPara <= USHRT_MAX &&
101 : : nEndIndex >= 0 && nEndIndex <= USHRT_MAX ,
102 : : "AccessibleStaticTextBase_Impl::MakeSelection: index value overflow");
103 : :
104 : : return ESelection( static_cast< sal_uInt16 >(nStartPara), static_cast< sal_uInt16 >(nStartIndex),
105 : 0 : static_cast< sal_uInt16 >(nEndPara), static_cast< sal_uInt16 >(nEndIndex) );
106 : : }
107 : :
108 : : //------------------------------------------------------------------------
109 : : //
110 : : // AccessibleStaticTextBase_Impl declaration
111 : : //
112 : : //------------------------------------------------------------------------
113 : :
114 : : DBG_NAME( AccessibleStaticTextBase_Impl );
115 : :
116 : : /** AccessibleStaticTextBase_Impl
117 : :
118 : : This class implements the AccessibleStaticTextBase
119 : : functionality, mainly by forwarding the calls to an aggregated
120 : : AccessibleEditableTextPara. As this is a therefore non-trivial
121 : : adapter, factoring out the common functionality from
122 : : AccessibleEditableTextPara might be a profitable future task.
123 : : */
124 : : class AccessibleStaticTextBase_Impl
125 : : {
126 : :
127 : : public:
128 : :
129 : : // receive pointer to our frontend class and view window
130 : : AccessibleStaticTextBase_Impl();
131 : : ~AccessibleStaticTextBase_Impl();
132 : :
133 : 0 : SvxEditSourceAdapter& GetEditSource() const SAL_THROW((uno::RuntimeException))
134 : : {
135 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
136 : :
137 : 0 : return maEditSource;
138 : : }
139 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
140 : : void SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException));
141 : : SAL_WNODEPRECATED_DECLARATIONS_POP
142 : :
143 : 25 : void SetEventSource( const uno::Reference< XAccessible >& rInterface )
144 : : {
145 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
146 : :
147 : 25 : mxThis = rInterface;
148 : 25 : }
149 : 0 : uno::Reference< XAccessible > GetEventSource() const
150 : : {
151 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
152 : :
153 : 0 : return mxThis;
154 : : }
155 : :
156 : : void SetOffset( const Point& );
157 : 0 : Point GetOffset() const
158 : : {
159 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
160 : :
161 [ # # ]: 0 : ::osl::MutexGuard aGuard( maMutex ); Point aPoint( maOffset );
162 [ # # ]: 0 : return aPoint;
163 : : }
164 : :
165 : : void UpdateChildren();
166 : : void Dispose();
167 : :
168 : : #ifdef DBG_UTIL
169 : : void CheckInvariants() const;
170 : : #endif
171 : :
172 : : AccessibleEditableTextPara& GetParagraph( sal_Int32 nPara ) const;
173 : : sal_Int32 GetParagraphCount() const;
174 : :
175 : 0 : EPosition Index2Internal( sal_Int32 nFlatIndex ) const
176 : : {
177 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
178 : :
179 : 0 : return ImpCalcInternal( nFlatIndex, false );
180 : : }
181 : :
182 : 0 : EPosition Range2Internal( sal_Int32 nFlatIndex ) const
183 : : {
184 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
185 : :
186 : 0 : return ImpCalcInternal( nFlatIndex, true );
187 : : }
188 : :
189 : : sal_Int32 Internal2Index( EPosition nEEIndex ) const;
190 : :
191 : : void CorrectTextSegment( TextSegment& aTextSegment,
192 : : int nPara ) const;
193 : :
194 : : sal_Bool SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
195 : : sal_Int32 nEndPara, sal_Int32 nEndIndex );
196 : : sal_Bool CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex,
197 : : sal_Int32 nEndPara, sal_Int32 nEndIndex );
198 : :
199 : : Rectangle GetParagraphBoundingBox() const;
200 : :
201 : : private:
202 : :
203 : : EPosition ImpCalcInternal( sal_Int32 nFlatIndex, bool bExclusive ) const;
204 : :
205 : : // our frontend class (the one implementing the actual
206 : : // interface). That's not necessarily the one containing the impl
207 : : // pointer
208 : : uno::Reference< XAccessible > mxThis;
209 : :
210 : : // implements our functionality, we're just an adapter (guarded by solar mutex)
211 : : mutable AccessibleEditableTextPara* mpTextParagraph;
212 : :
213 : : uno::Reference< XAccessible > mxParagraph;
214 : :
215 : : // a wrapper for the text forwarders (guarded by solar mutex)
216 : : mutable SvxEditSourceAdapter maEditSource;
217 : :
218 : : // guard for maOffset
219 : : mutable ::osl::Mutex maMutex;
220 : :
221 : : /// our current offset to the containing shape/cell (guarded by maMutex)
222 : : Point maOffset;
223 : :
224 : : };
225 : :
226 : : //------------------------------------------------------------------------
227 : : //
228 : : // AccessibleStaticTextBase_Impl implementation
229 : : //
230 : : //------------------------------------------------------------------------
231 : :
232 : 11 : AccessibleStaticTextBase_Impl::AccessibleStaticTextBase_Impl() :
233 : : mxThis( NULL ),
234 [ + - ]: 11 : mpTextParagraph( new AccessibleEditableTextPara(NULL) ),
235 : : mxParagraph( mpTextParagraph ),
236 : : maEditSource(),
237 : : maMutex(),
238 [ + - ][ + - ]: 22 : maOffset(0,0)
[ + - ][ + - ]
[ + - ]
239 : : {
240 : : DBG_CTOR( AccessibleStaticTextBase_Impl, NULL );
241 : :
242 : : // TODO: this is still somewhat of a hack, all the more since
243 : : // now the maTextParagraph has an empty parent reference set
244 : 11 : }
245 : :
246 [ + - ][ + - ]: 11 : AccessibleStaticTextBase_Impl::~AccessibleStaticTextBase_Impl()
247 : : {
248 : : DBG_DTOR( AccessibleStaticTextBase_Impl, NULL );
249 : 11 : }
250 : :
251 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
252 : 11 : void AccessibleStaticTextBase_Impl::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException))
253 : : {
254 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
255 : :
256 [ + - ]: 11 : maEditSource.SetEditSource( pEditSource );
257 [ + - ]: 11 : if( mpTextParagraph )
258 : 11 : mpTextParagraph->SetEditSource( &maEditSource );
259 : 11 : }
260 : : SAL_WNODEPRECATED_DECLARATIONS_POP
261 : :
262 : 22 : void AccessibleStaticTextBase_Impl::SetOffset( const Point& rPoint )
263 : : {
264 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
265 : :
266 : : // guard against non-atomic access to maOffset data structure
267 : : {
268 [ + - ]: 22 : ::osl::MutexGuard aGuard( maMutex );
269 [ + - ]: 22 : maOffset = rPoint;
270 : : }
271 : :
272 [ + - ]: 22 : if( mpTextParagraph )
273 : 22 : mpTextParagraph->SetEEOffset( rPoint );
274 : :
275 : : // in all cases, check visibility afterwards.
276 : 22 : UpdateChildren();
277 : 22 : }
278 : :
279 : 22 : void AccessibleStaticTextBase_Impl::UpdateChildren()
280 : : {
281 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
282 : :
283 : : // currently no children
284 : 22 : }
285 : :
286 : 11 : void AccessibleStaticTextBase_Impl::Dispose()
287 : : {
288 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
289 : :
290 : : // we're the owner of the paragraph, so destroy it, too
291 [ + - ]: 11 : if( mpTextParagraph )
292 : 11 : mpTextParagraph->Dispose();
293 : :
294 : : // drop references
295 : 11 : mxParagraph = NULL;
296 : 11 : mxThis = NULL;
297 : 11 : mpTextParagraph = NULL;
298 : 11 : }
299 : :
300 : : #ifdef DBG_UTIL
301 : : void AccessibleStaticTextBase_Impl::CheckInvariants() const
302 : : {
303 : : // TODO
304 : : }
305 : : #endif
306 : :
307 : 0 : AccessibleEditableTextPara& AccessibleStaticTextBase_Impl::GetParagraph( sal_Int32 nPara ) const
308 : : {
309 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
310 : :
311 [ # # ]: 0 : if( !mpTextParagraph )
312 : : throw lang::DisposedException (
313 [ # # ][ # # ]: 0 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), mxThis );
314 : :
315 : : // TODO: Have a differnt method on AccessibleEditableTextPara
316 : : // that does not care about state changes
317 : 0 : mpTextParagraph->SetParagraphIndex( nPara );
318 : :
319 : 0 : return *mpTextParagraph;
320 : : }
321 : :
322 : 0 : sal_Int32 AccessibleStaticTextBase_Impl::GetParagraphCount() const
323 : : {
324 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
325 : :
326 [ # # ]: 0 : if( !mpTextParagraph )
327 : 0 : return 0;
328 : : else
329 : 0 : return mpTextParagraph->GetTextForwarder().GetParagraphCount();
330 : : }
331 : :
332 : 0 : sal_Int32 AccessibleStaticTextBase_Impl::Internal2Index( EPosition nEEIndex ) const
333 : : {
334 : 0 : sal_Int32 aRes(0);
335 : : int i;
336 [ # # ]: 0 : for(i=0; i<nEEIndex.nPara; ++i)
337 : 0 : aRes += GetParagraph(i).getCharacterCount();
338 : :
339 : 0 : return aRes + nEEIndex.nIndex;
340 : : }
341 : :
342 : 0 : void AccessibleStaticTextBase_Impl::CorrectTextSegment( TextSegment& aTextSegment,
343 : : int nPara ) const
344 : : {
345 : : // Keep 'invalid' values at the TextSegment
346 [ # # ][ # # ]: 0 : if( aTextSegment.SegmentStart != -1 &&
347 : : aTextSegment.SegmentEnd != -1 )
348 : : {
349 : : // #112814# Correct TextSegment by paragraph offset
350 : 0 : sal_Int32 nOffset(0);
351 : : int i;
352 [ # # ]: 0 : for(i=0; i<nPara; ++i)
353 : 0 : nOffset += GetParagraph(i).getCharacterCount();
354 : :
355 : 0 : aTextSegment.SegmentStart += nOffset;
356 : 0 : aTextSegment.SegmentEnd += nOffset;
357 : : }
358 : 0 : }
359 : :
360 : 0 : EPosition AccessibleStaticTextBase_Impl::ImpCalcInternal( sal_Int32 nFlatIndex, bool bExclusive ) const
361 : : {
362 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
363 : :
364 [ # # ]: 0 : if( nFlatIndex < 0 )
365 : : throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds")),
366 [ # # ][ # # ]: 0 : mxThis);
367 : : // gratuitously accepting larger indices here, AccessibleEditableTextPara will throw eventually
368 : :
369 : : sal_Int32 nCurrPara, nCurrIndex, nParas, nCurrCount;
370 [ # # ]: 0 : for( nCurrPara=0, nParas=GetParagraphCount(), nCurrCount=0, nCurrIndex=0; nCurrPara<nParas; ++nCurrPara )
371 : : {
372 : 0 : nCurrCount = GetParagraph( nCurrPara ).getCharacterCount();
373 : 0 : nCurrIndex += nCurrCount;
374 : :
375 [ # # ]: 0 : if( nCurrIndex > nFlatIndex )
376 : : {
377 : : // check overflow
378 : : DBG_ASSERT(nCurrPara >= 0 && nCurrPara <= USHRT_MAX &&
379 : : nFlatIndex - nCurrIndex + nCurrCount >= 0 && nFlatIndex - nCurrIndex + nCurrCount <= USHRT_MAX ,
380 : : "AccessibleStaticTextBase_Impl::Index2Internal: index value overflow");
381 : :
382 : 0 : return EPosition( static_cast< sal_uInt16 >(nCurrPara), static_cast< sal_uInt16 >(nFlatIndex - nCurrIndex + nCurrCount) );
383 : : }
384 : : }
385 : :
386 : : // #102170# Allow one-past the end for ranges
387 [ # # ][ # # ]: 0 : if( bExclusive && nCurrIndex == nFlatIndex )
388 : : {
389 : : // check overflow
390 : : DBG_ASSERT(nCurrPara >= 0 && nCurrPara <= USHRT_MAX &&
391 : : nFlatIndex - nCurrIndex + nCurrCount >= 0 && nFlatIndex - nCurrIndex + nCurrCount <= USHRT_MAX ,
392 : : "AccessibleStaticTextBase_Impl::Index2Internal: index value overflow");
393 : :
394 : 0 : return EPosition( static_cast< sal_uInt16 >(nCurrPara-1), static_cast< sal_uInt16 >(nFlatIndex - nCurrIndex + nCurrCount) );
395 : : }
396 : :
397 : : // not found? Out of bounds
398 : : throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds")),
399 [ # # ][ # # ]: 0 : mxThis);
400 : : }
401 : :
402 : 0 : sal_Bool AccessibleStaticTextBase_Impl::SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
403 : : sal_Int32 nEndPara, sal_Int32 nEndIndex )
404 : : {
405 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
406 : :
407 [ # # ]: 0 : if( !mpTextParagraph )
408 : 0 : return sal_False;
409 : :
410 : : try
411 : : {
412 [ # # ]: 0 : SvxEditViewForwarder& rCacheVF = mpTextParagraph->GetEditViewForwarder( sal_True );
413 [ # # ][ # # ]: 0 : return rCacheVF.SetSelection( MakeSelection(nStartPara, nStartIndex, nEndPara, nEndIndex) );
414 : : }
415 : 0 : catch( const uno::RuntimeException& )
416 : : {
417 : 0 : return sal_False;
418 : : }
419 : : }
420 : :
421 : 0 : sal_Bool AccessibleStaticTextBase_Impl::CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex,
422 : : sal_Int32 nEndPara, sal_Int32 nEndIndex )
423 : : {
424 : : DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
425 : :
426 [ # # ]: 0 : if( !mpTextParagraph )
427 : 0 : return sal_False;
428 : :
429 : : try
430 : : {
431 [ # # ]: 0 : SvxEditViewForwarder& rCacheVF = mpTextParagraph->GetEditViewForwarder( sal_True );
432 [ # # ]: 0 : mpTextParagraph->GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
433 : : sal_Bool aRetVal;
434 : :
435 : : // save current selection
436 : 0 : ESelection aOldSelection;
437 : :
438 [ # # ]: 0 : rCacheVF.GetSelection( aOldSelection );
439 [ # # # # ]: 0 : rCacheVF.SetSelection( MakeSelection(nStartPara, nStartIndex, nEndPara, nEndIndex) );
440 [ # # ]: 0 : aRetVal = rCacheVF.Copy();
441 [ # # ]: 0 : rCacheVF.SetSelection( aOldSelection ); // restore
442 : :
443 : 0 : return aRetVal;
444 : : }
445 : 0 : catch( const uno::RuntimeException& )
446 : : {
447 : 0 : return sal_False;
448 : : }
449 : : }
450 : :
451 : 0 : Rectangle AccessibleStaticTextBase_Impl::GetParagraphBoundingBox() const
452 : : {
453 : 0 : Rectangle aRect;
454 [ # # ]: 0 : if( mpTextParagraph )
455 : : {
456 [ # # ]: 0 : awt::Rectangle aAwtRect = mpTextParagraph->getBounds();
457 [ # # ]: 0 : aRect = Rectangle( Point( aAwtRect.X, aAwtRect.Y ), Size( aAwtRect.Width, aAwtRect.Height ) );
458 : : }
459 : : else
460 : : {
461 : 0 : aRect.SetEmpty();
462 : : }
463 : 0 : return aRect;
464 : : }
465 : :
466 : : //------------------------------------------------------------------------
467 : : //
468 : : // AccessibleStaticTextBase implementation
469 : : //
470 : : //------------------------------------------------------------------------
471 : :
472 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
473 : 11 : AccessibleStaticTextBase::AccessibleStaticTextBase( ::std::auto_ptr< SvxEditSource > pEditSource ) :
474 [ + - ][ + - ]: 11 : mpImpl( new AccessibleStaticTextBase_Impl() )
475 : : {
476 [ + - ]: 11 : SolarMutexGuard aGuard;
477 : :
478 [ + - ][ + - ]: 11 : SetEditSource( pEditSource );
[ + - ]
479 : 11 : }
480 : : SAL_WNODEPRECATED_DECLARATIONS_POP
481 : :
482 [ + - ]: 11 : AccessibleStaticTextBase::~AccessibleStaticTextBase()
483 : : {
484 [ - + ]: 11 : }
485 : :
486 : 0 : const SvxEditSource& AccessibleStaticTextBase::GetEditSource() const SAL_THROW((::com::sun::star::uno::RuntimeException))
487 : : {
488 : : #ifdef DBG_UTIL
489 : : mpImpl->CheckInvariants();
490 : :
491 : : const SvxEditSource& aEditSource = mpImpl->GetEditSource();
492 : :
493 : : mpImpl->CheckInvariants();
494 : :
495 : : return aEditSource;
496 : : #else
497 : 0 : return mpImpl->GetEditSource();
498 : : #endif
499 : : }
500 : :
501 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
502 : 11 : void AccessibleStaticTextBase::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((::com::sun::star::uno::RuntimeException))
503 : : {
504 : : #ifdef DBG_UTIL
505 : : // precondition: solar mutex locked
506 : : DBG_TESTSOLARMUTEX();
507 : :
508 : : mpImpl->CheckInvariants();
509 : :
510 : : mpImpl->SetEditSource( pEditSource );
511 : :
512 : : mpImpl->CheckInvariants();
513 : : #else
514 [ + - ]: 11 : mpImpl->SetEditSource( pEditSource );
515 : : #endif
516 : 11 : }
517 : : SAL_WNODEPRECATED_DECLARATIONS_POP
518 : :
519 : 25 : void AccessibleStaticTextBase::SetEventSource( const uno::Reference< XAccessible >& rInterface )
520 : : {
521 : : #ifdef DBG_UTIL
522 : : mpImpl->CheckInvariants();
523 : : #endif
524 : :
525 : 25 : mpImpl->SetEventSource( rInterface );
526 : :
527 : : #ifdef DBG_UTIL
528 : : mpImpl->CheckInvariants();
529 : : #endif
530 : 25 : }
531 : :
532 : 0 : uno::Reference< XAccessible > AccessibleStaticTextBase::GetEventSource() const
533 : : {
534 : : #ifdef DBG_UTIL
535 : : mpImpl->CheckInvariants();
536 : :
537 : : uno::Reference< XAccessible > xRet( mpImpl->GetEventSource() );
538 : :
539 : : mpImpl->CheckInvariants();
540 : :
541 : : return xRet;
542 : : #else
543 : 0 : return mpImpl->GetEventSource();
544 : : #endif
545 : : }
546 : :
547 : 22 : void AccessibleStaticTextBase::SetOffset( const Point& rPoint )
548 : : {
549 : : #ifdef DBG_UTIL
550 : : // precondition: solar mutex locked
551 : : DBG_TESTSOLARMUTEX();
552 : :
553 : : mpImpl->CheckInvariants();
554 : :
555 : : mpImpl->SetOffset( rPoint );
556 : :
557 : : mpImpl->CheckInvariants();
558 : : #else
559 : 22 : mpImpl->SetOffset( rPoint );
560 : : #endif
561 : 22 : }
562 : :
563 : 0 : Point AccessibleStaticTextBase::GetOffset() const
564 : : {
565 : : #ifdef DBG_UTIL
566 : : mpImpl->CheckInvariants();
567 : :
568 : : Point aPoint( mpImpl->GetOffset() );
569 : :
570 : : mpImpl->CheckInvariants();
571 : :
572 : : return aPoint;
573 : : #else
574 : 0 : return mpImpl->GetOffset();
575 : : #endif
576 : : }
577 : :
578 : 0 : void AccessibleStaticTextBase::UpdateChildren() SAL_THROW((::com::sun::star::uno::RuntimeException))
579 : : {
580 : : #ifdef DBG_UTIL
581 : : // precondition: solar mutex locked
582 : : DBG_TESTSOLARMUTEX();
583 : :
584 : : mpImpl->CheckInvariants();
585 : :
586 : : mpImpl->UpdateChildren();
587 : :
588 : : mpImpl->CheckInvariants();
589 : : #else
590 : 0 : mpImpl->UpdateChildren();
591 : : #endif
592 : 0 : }
593 : :
594 : 11 : void AccessibleStaticTextBase::Dispose()
595 : : {
596 : : #ifdef DBG_UTIL
597 : : mpImpl->CheckInvariants();
598 : : #endif
599 : :
600 : 11 : mpImpl->Dispose();
601 : :
602 : : #ifdef DBG_UTIL
603 : : mpImpl->CheckInvariants();
604 : : #endif
605 : 11 : }
606 : :
607 : : // XAccessibleContext
608 : 18 : sal_Int32 SAL_CALL AccessibleStaticTextBase::getAccessibleChildCount() throw (uno::RuntimeException)
609 : : {
610 : : // no children at all
611 : 18 : return 0;
612 : : }
613 : :
614 : 0 : uno::Reference< XAccessible > SAL_CALL AccessibleStaticTextBase::getAccessibleChild( sal_Int32 /*i*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
615 : : {
616 : : // no children at all
617 : 0 : return uno::Reference< XAccessible >();
618 : : }
619 : :
620 : 0 : uno::Reference< XAccessible > SAL_CALL AccessibleStaticTextBase::getAccessibleAtPoint( const awt::Point& /*_aPoint*/ ) throw (uno::RuntimeException)
621 : : {
622 : : // no children at all
623 : 0 : return uno::Reference< XAccessible >();
624 : : }
625 : :
626 : : // XAccessibleText
627 : 0 : sal_Int32 SAL_CALL AccessibleStaticTextBase::getCaretPosition() throw (uno::RuntimeException)
628 : : {
629 [ # # ]: 0 : SolarMutexGuard aGuard;
630 : :
631 : : sal_Int32 i, nPos, nParas;
632 [ # # ][ # # ]: 0 : for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
633 : : {
634 [ # # ][ # # ]: 0 : if( (nPos=mpImpl->GetParagraph(i).getCaretPosition()) != -1 )
[ # # ]
635 : 0 : return nPos;
636 : : }
637 : :
638 [ # # ]: 0 : return nPos;
639 : : }
640 : :
641 : 0 : sal_Bool SAL_CALL AccessibleStaticTextBase::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
642 : : {
643 : 0 : return setSelection(nIndex, nIndex);
644 : : }
645 : :
646 : 0 : sal_Unicode SAL_CALL AccessibleStaticTextBase::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
647 : : {
648 [ # # ]: 0 : SolarMutexGuard aGuard;
649 : :
650 [ # # ]: 0 : EPosition aPos( mpImpl->Index2Internal(nIndex) );
651 : :
652 [ # # ][ # # ]: 0 : return mpImpl->GetParagraph( aPos.nPara ).getCharacter( aPos.nIndex );
[ # # ]
653 : : }
654 : :
655 : 0 : uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
656 : : {
657 [ # # ]: 0 : SolarMutexGuard aGuard;
658 : :
659 [ # # ]: 0 : EPosition aPos( mpImpl->Index2Internal(nIndex) );
660 : :
661 [ # # ][ # # ]: 0 : return mpImpl->GetParagraph( aPos.nPara ).getCharacterAttributes( aPos.nIndex, aRequestedAttributes );
[ # # ]
662 : : }
663 : :
664 : 0 : awt::Rectangle SAL_CALL AccessibleStaticTextBase::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
665 : : {
666 [ # # ]: 0 : SolarMutexGuard aGuard;
667 : :
668 : : // #108900# Allow ranges for nIndex, as one-past-the-end
669 : : // values are now legal, too.
670 [ # # ]: 0 : EPosition aPos( mpImpl->Range2Internal(nIndex) );
671 : :
672 : : // #i70916# Text in spread sheet cells return the wrong extents
673 [ # # ]: 0 : AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( aPos.nPara );
674 [ # # ]: 0 : awt::Rectangle aParaBounds( rPara.getBounds() );
675 [ # # ]: 0 : awt::Rectangle aBounds( rPara.getCharacterBounds( aPos.nIndex ) );
676 : 0 : aBounds.X += aParaBounds.X;
677 : 0 : aBounds.Y += aParaBounds.Y;
678 : :
679 [ # # ]: 0 : return aBounds;
680 : : }
681 : :
682 : 0 : sal_Int32 SAL_CALL AccessibleStaticTextBase::getCharacterCount() throw (uno::RuntimeException)
683 : : {
684 [ # # ]: 0 : SolarMutexGuard aGuard;
685 : :
686 : : sal_Int32 i, nCount, nParas;
687 [ # # ][ # # ]: 0 : for( i=0, nCount=0, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
688 [ # # ][ # # ]: 0 : nCount += mpImpl->GetParagraph(i).getCharacterCount();
689 : :
690 [ # # ]: 0 : return nCount;
691 : : }
692 : :
693 : 0 : sal_Int32 SAL_CALL AccessibleStaticTextBase::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException)
694 : : {
695 [ # # ]: 0 : SolarMutexGuard aGuard;
696 : :
697 [ # # ]: 0 : const sal_Int32 nParas( mpImpl->GetParagraphCount() );
698 : : sal_Int32 nIndex;
699 : : int i;
700 [ # # ]: 0 : for( i=0; i<nParas; ++i )
701 : : {
702 : : // TODO: maybe exploit the fact that paragraphs are
703 : : // ordered vertically for early exit
704 : :
705 : : // #i70916# Text in spread sheet cells return the wrong extents
706 [ # # ]: 0 : AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( i );
707 [ # # ]: 0 : awt::Rectangle aParaBounds( rPara.getBounds() );
708 : 0 : awt::Point aPoint( rPoint );
709 : 0 : aPoint.X -= aParaBounds.X;
710 : 0 : aPoint.Y -= aParaBounds.Y;
711 : :
712 : : // #112814# Use correct index offset
713 [ # # ][ # # ]: 0 : if ( ( nIndex = rPara.getIndexAtPoint( aPoint ) ) != -1 )
714 : 0 : return mpImpl->Internal2Index( EPosition(sal::static_int_cast<sal_uInt16>(i),
715 [ # # ]: 0 : sal::static_int_cast<sal_uInt16>(nIndex)) );
716 : : }
717 : :
718 [ # # ]: 0 : return -1;
719 : : }
720 : :
721 : 0 : ::rtl::OUString SAL_CALL AccessibleStaticTextBase::getSelectedText() throw (uno::RuntimeException)
722 : : {
723 [ # # ]: 0 : SolarMutexGuard aGuard;
724 : :
725 [ # # ]: 0 : sal_Int32 nStart( getSelectionStart() );
726 [ # # ]: 0 : sal_Int32 nEnd( getSelectionEnd() );
727 : :
728 : : // #104481# Return the empty string for 'no selection'
729 [ # # ][ # # ]: 0 : if( nStart < 0 || nEnd < 0 )
730 : 0 : return ::rtl::OUString();
731 : :
732 [ # # ][ # # ]: 0 : return getTextRange( nStart, nEnd );
733 : : }
734 : :
735 : 0 : sal_Int32 SAL_CALL AccessibleStaticTextBase::getSelectionStart() throw (uno::RuntimeException)
736 : : {
737 [ # # ]: 0 : SolarMutexGuard aGuard;
738 : :
739 : : sal_Int32 i, nPos, nParas;
740 [ # # ][ # # ]: 0 : for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
741 : : {
742 [ # # ][ # # ]: 0 : if( (nPos=mpImpl->GetParagraph(i).getSelectionStart()) != -1 )
[ # # ]
743 : 0 : return nPos;
744 : : }
745 : :
746 [ # # ]: 0 : return nPos;
747 : : }
748 : :
749 : 0 : sal_Int32 SAL_CALL AccessibleStaticTextBase::getSelectionEnd() throw (uno::RuntimeException)
750 : : {
751 [ # # ]: 0 : SolarMutexGuard aGuard;
752 : :
753 : : sal_Int32 i, nPos, nParas;
754 [ # # ][ # # ]: 0 : for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
755 : : {
756 [ # # ][ # # ]: 0 : if( (nPos=mpImpl->GetParagraph(i).getSelectionEnd()) != -1 )
[ # # ]
757 : 0 : return nPos;
758 : : }
759 : :
760 [ # # ]: 0 : return nPos;
761 : : }
762 : :
763 : 0 : sal_Bool SAL_CALL AccessibleStaticTextBase::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
764 : : {
765 [ # # ]: 0 : SolarMutexGuard aGuard;
766 : :
767 [ # # ]: 0 : EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
768 [ # # ]: 0 : EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
769 : :
770 : : return mpImpl->SetSelection( aStartIndex.nPara, aStartIndex.nIndex,
771 [ # # ][ # # ]: 0 : aEndIndex.nPara, aEndIndex.nIndex );
772 : : }
773 : :
774 : 0 : ::rtl::OUString SAL_CALL AccessibleStaticTextBase::getText() throw (uno::RuntimeException)
775 : : {
776 [ # # ]: 0 : SolarMutexGuard aGuard;
777 : :
778 : : sal_Int32 i, nParas;
779 : 0 : ::rtl::OUString aRes;
780 [ # # ][ # # ]: 0 : for( i=0, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
781 [ # # ][ # # ]: 0 : aRes += mpImpl->GetParagraph(i).getText();
782 : :
783 [ # # ]: 0 : return aRes;
784 : : }
785 : :
786 : 0 : ::rtl::OUString SAL_CALL AccessibleStaticTextBase::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
787 : : {
788 [ # # ]: 0 : SolarMutexGuard aGuard;
789 : :
790 [ # # ]: 0 : if( nStartIndex > nEndIndex )
791 : 0 : ::std::swap(nStartIndex, nEndIndex);
792 : :
793 [ # # ]: 0 : EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
794 [ # # ]: 0 : EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
795 : :
796 : : // #102170# Special case: start and end paragraph are identical
797 [ # # ]: 0 : if( aStartIndex.nPara == aEndIndex.nPara )
798 : : {
799 [ # # ][ # # ]: 0 : return mpImpl->GetParagraph( aStartIndex.nPara ).getTextRange( aStartIndex.nIndex, aEndIndex.nIndex );
800 : : }
801 : : else
802 : : {
803 : 0 : sal_Int32 i( aStartIndex.nPara );
804 [ # # ]: 0 : ::rtl::OUString aRes( mpImpl->GetParagraph(i).getTextRange( aStartIndex.nIndex,
805 [ # # ][ # # ]: 0 : mpImpl->GetParagraph(i).getCharacterCount()-1) );
[ # # ]
806 : 0 : ++i;
807 : :
808 : : // paragraphs inbetween are fully included
809 [ # # ]: 0 : for( ; i<aEndIndex.nPara; ++i )
810 [ # # ][ # # ]: 0 : aRes += mpImpl->GetParagraph(i).getText();
811 : :
812 [ # # ]: 0 : if( i<=aEndIndex.nPara )
813 [ # # ][ # # ]: 0 : aRes += mpImpl->GetParagraph(i).getTextRange( 0, aEndIndex.nIndex );
814 : :
815 : 0 : return aRes;
816 [ # # ]: 0 : }
817 : : }
818 : :
819 : 0 : ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
820 : : {
821 [ # # ]: 0 : SolarMutexGuard aGuard;
822 : :
823 [ # # ]: 0 : EPosition aPos( mpImpl->Range2Internal(nIndex) );
824 : :
825 : 0 : ::com::sun::star::accessibility::TextSegment aResult;
826 : :
827 [ # # ]: 0 : if( AccessibleTextType::PARAGRAPH == aTextType )
828 : : {
829 : : // #106393# Special casing one behind last paragraph is
830 : : // not necessary, since then, we return the content and
831 : : // boundary of that last paragraph. Range2Internal is
832 : : // tolerant against that, and returns the last paragraph
833 : : // in aPos.nPara.
834 : :
835 : : // retrieve full text of the paragraph
836 [ # # ][ # # ]: 0 : aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara ).getText();
837 : :
838 : : // #112814# Adapt the start index with the paragraph offset
839 [ # # ]: 0 : aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara, 0 ) );
840 : 0 : aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
841 : : }
842 : : else
843 : : {
844 : : // No special handling required, forward to wrapped class
845 [ # # ][ # # ]: 0 : aResult = mpImpl->GetParagraph( aPos.nPara ).getTextAtIndex( aPos.nIndex, aTextType );
846 : :
847 : : // #112814# Adapt the start index with the paragraph offset
848 [ # # ]: 0 : mpImpl->CorrectTextSegment( aResult, aPos.nPara );
849 : : }
850 : :
851 [ # # ]: 0 : return aResult;
852 : : }
853 : :
854 : 0 : ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
855 : : {
856 [ # # ]: 0 : SolarMutexGuard aGuard;
857 : :
858 [ # # ]: 0 : EPosition aPos( mpImpl->Range2Internal(nIndex) );
859 : :
860 : 0 : ::com::sun::star::accessibility::TextSegment aResult;
861 : :
862 [ # # ]: 0 : if( AccessibleTextType::PARAGRAPH == aTextType )
863 : : {
864 [ # # ][ # # ]: 0 : if( aPos.nIndex == mpImpl->GetParagraph( aPos.nPara ).getCharacterCount() )
[ # # ]
865 : : {
866 : : // #103589# Special casing one behind the last paragraph
867 [ # # ][ # # ]: 0 : aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara ).getText();
868 : :
869 : : // #112814# Adapt the start index with the paragraph offset
870 [ # # ]: 0 : aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara, 0 ) );
871 : : }
872 [ # # ]: 0 : else if( aPos.nPara > 0 )
873 : : {
874 [ # # ][ # # ]: 0 : aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara - 1 ).getText();
875 : :
876 : : // #112814# Adapt the start index with the paragraph offset
877 [ # # ]: 0 : aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara - 1, 0 ) );
878 : : }
879 : :
880 : 0 : aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
881 : : }
882 : : else
883 : : {
884 : : // No special handling required, forward to wrapped class
885 [ # # ][ # # ]: 0 : aResult = mpImpl->GetParagraph( aPos.nPara ).getTextBeforeIndex( aPos.nIndex, aTextType );
886 : :
887 : : // #112814# Adapt the start index with the paragraph offset
888 [ # # ]: 0 : mpImpl->CorrectTextSegment( aResult, aPos.nPara );
889 : : }
890 : :
891 [ # # ]: 0 : return aResult;
892 : : }
893 : :
894 : 0 : ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
895 : : {
896 [ # # ]: 0 : SolarMutexGuard aGuard;
897 : :
898 [ # # ]: 0 : EPosition aPos( mpImpl->Range2Internal(nIndex) );
899 : :
900 : 0 : ::com::sun::star::accessibility::TextSegment aResult;
901 : :
902 [ # # ]: 0 : if( AccessibleTextType::PARAGRAPH == aTextType )
903 : : {
904 : : // Special casing one behind the last paragraph is not
905 : : // necessary, this case is invalid here for
906 : : // getTextBehindIndex
907 [ # # ][ # # ]: 0 : if( aPos.nPara + 1 < mpImpl->GetParagraphCount() )
908 : : {
909 [ # # ][ # # ]: 0 : aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara + 1 ).getText();
910 : :
911 : : // #112814# Adapt the start index with the paragraph offset
912 [ # # ]: 0 : aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara + 1, 0 ) );
913 : 0 : aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
914 : : }
915 : : }
916 : : else
917 : : {
918 : : // No special handling required, forward to wrapped class
919 [ # # ][ # # ]: 0 : aResult = mpImpl->GetParagraph( aPos.nPara ).getTextBehindIndex( aPos.nIndex, aTextType );
920 : :
921 : : // #112814# Adapt the start index with the paragraph offset
922 [ # # ]: 0 : mpImpl->CorrectTextSegment( aResult, aPos.nPara );
923 : : }
924 : :
925 [ # # ]: 0 : return aResult;
926 : : }
927 : :
928 : 0 : sal_Bool SAL_CALL AccessibleStaticTextBase::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
929 : : {
930 [ # # ]: 0 : SolarMutexGuard aGuard;
931 : :
932 [ # # ]: 0 : if( nStartIndex > nEndIndex )
933 : 0 : ::std::swap(nStartIndex, nEndIndex);
934 : :
935 [ # # ]: 0 : EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
936 [ # # ]: 0 : EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
937 : :
938 : : return mpImpl->CopyText( aStartIndex.nPara, aStartIndex.nIndex,
939 [ # # ][ # # ]: 0 : aEndIndex.nPara, aEndIndex.nIndex );
940 : : }
941 : :
942 : : // XAccessibleTextAttributes
943 : 0 : uno::Sequence< beans::PropertyValue > AccessibleStaticTextBase::getDefaultAttributes( const uno::Sequence< ::rtl::OUString >& RequestedAttributes ) throw (uno::RuntimeException)
944 : : {
945 : : // get the intersection of the default attributes of all paragraphs
946 : :
947 [ # # ]: 0 : SolarMutexGuard aGuard;
948 : :
949 [ # # ][ # # ]: 0 : PropertyValueVector aDefAttrVec( mpImpl->GetParagraph( 0 ).getDefaultAttributes( RequestedAttributes ) );
[ # # ][ # # ]
950 : :
951 [ # # ]: 0 : const sal_Int32 nParaCount = mpImpl->GetParagraphCount();
952 [ # # ]: 0 : for ( sal_Int32 nPara = 1; nPara < nParaCount; ++nPara )
953 : : {
954 [ # # ][ # # ]: 0 : uno::Sequence< beans::PropertyValue > aSeq = mpImpl->GetParagraph( nPara ).getDefaultAttributes( RequestedAttributes );
955 [ # # ]: 0 : PropertyValueVector aIntersectionVec;
956 : :
957 [ # # ]: 0 : PropertyValueVector::const_iterator aEnd = aDefAttrVec.end();
958 [ # # ][ # # ]: 0 : for ( PropertyValueVector::const_iterator aItr = aDefAttrVec.begin(); aItr != aEnd; ++aItr )
[ # # ]
959 : : {
960 : 0 : const beans::PropertyValue* pItr = aSeq.getConstArray();
961 : 0 : const beans::PropertyValue* pEnd = pItr + aSeq.getLength();
962 [ # # ][ # # ]: 0 : const beans::PropertyValue* pFind = ::std::find_if( pItr, pEnd, ::std::bind2nd( PropertyValueEqualFunctor(), boost::cref( *aItr ) ) );
[ # # ]
963 [ # # ]: 0 : if ( pFind != pEnd )
964 : : {
965 [ # # ]: 0 : aIntersectionVec.push_back( *pFind );
966 : : }
967 : : }
968 : :
969 : 0 : aDefAttrVec.swap( aIntersectionVec );
970 : :
971 [ # # ]: 0 : if ( aDefAttrVec.empty() )
972 : : {
973 : : break;
974 : : }
975 [ # # ][ # # ]: 0 : }
[ # # ]
976 : :
977 [ # # ][ # # ]: 0 : return aDefAttrVec.getAsConstList();
978 : : }
979 : :
980 : 0 : uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getRunAttributes( sal_Int32 nIndex, const uno::Sequence< ::rtl::OUString >& RequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
981 : : {
982 : : // get those default attributes of the paragraph, which are not part
983 : : // of the intersection of all paragraphs and add them to the run attributes
984 : :
985 [ # # ]: 0 : SolarMutexGuard aGuard;
986 : :
987 [ # # ]: 0 : EPosition aPos( mpImpl->Index2Internal( nIndex ) );
988 [ # # ]: 0 : AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( aPos.nPara );
989 [ # # ]: 0 : uno::Sequence< beans::PropertyValue > aDefAttrSeq = rPara.getDefaultAttributes( RequestedAttributes );
990 [ # # ]: 0 : uno::Sequence< beans::PropertyValue > aRunAttrSeq = rPara.getRunAttributes( aPos.nIndex, RequestedAttributes );
991 [ # # ]: 0 : uno::Sequence< beans::PropertyValue > aIntersectionSeq = getDefaultAttributes( RequestedAttributes );
992 [ # # ]: 0 : PropertyValueVector aDiffVec;
993 : :
994 : 0 : const beans::PropertyValue* pDefAttr = aDefAttrSeq.getConstArray();
995 : 0 : const sal_Int32 nLength = aDefAttrSeq.getLength();
996 [ # # ]: 0 : for ( sal_Int32 i = 0; i < nLength; ++i )
997 : : {
998 : 0 : const beans::PropertyValue* pItr = aIntersectionSeq.getConstArray();
999 : 0 : const beans::PropertyValue* pEnd = pItr + aIntersectionSeq.getLength();
1000 [ # # ][ # # ]: 0 : const beans::PropertyValue* pFind = ::std::find_if( pItr, pEnd, ::std::bind2nd( PropertyValueEqualFunctor(), boost::cref( pDefAttr[i] ) ) );
[ # # ]
1001 [ # # ][ # # ]: 0 : if ( pFind == pEnd && pDefAttr[i].Handle != 0)
1002 : : {
1003 [ # # ]: 0 : aDiffVec.push_back( pDefAttr[i] );
1004 : : }
1005 : : }
1006 : :
1007 [ # # ][ # # ]: 0 : return ::comphelper::concatSequences( aRunAttrSeq, aDiffVec.getAsConstList() );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1008 : : }
1009 : :
1010 : 0 : Rectangle AccessibleStaticTextBase::GetParagraphBoundingBox() const
1011 : : {
1012 : 0 : return mpImpl->GetParagraphBoundingBox();
1013 : : }
1014 : :
1015 : : } // end of namespace accessibility
1016 : :
1017 : : //------------------------------------------------------------------------
1018 : :
1019 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|