Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 :
22 :
23 : // Global header
24 :
25 :
26 :
27 : #include <limits.h>
28 : #include <vector>
29 : #include <algorithm>
30 : #include <osl/mutex.hxx>
31 : #include <vcl/window.hxx>
32 : #include <vcl/svapp.hxx>
33 : #include <editeng/flditem.hxx>
34 : #include <com/sun/star/uno/Any.hxx>
35 : #include <com/sun/star/uno/Reference.hxx>
36 : #include <com/sun/star/awt/Point.hpp>
37 : #include <com/sun/star/awt/Rectangle.hpp>
38 : #include <com/sun/star/lang/DisposedException.hpp>
39 : #include <com/sun/star/accessibility/AccessibleRole.hpp>
40 : #include <com/sun/star/accessibility/AccessibleTextType.hpp>
41 : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
42 : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
43 : #include <comphelper/accessibleeventnotifier.hxx>
44 : #include <comphelper/sequenceashashmap.hxx>
45 : #include <cppuhelper/supportsservice.hxx>
46 : #include <unotools/accessiblestatesethelper.hxx>
47 : #include <unotools/accessiblerelationsethelper.hxx>
48 : #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
49 : #include <vcl/unohelp.hxx>
50 : #include <vcl/settings.hxx>
51 :
52 : #include <editeng/editeng.hxx>
53 : #include <editeng/unoprnms.hxx>
54 : #include <editeng/unoipset.hxx>
55 : #include <editeng/outliner.hxx>
56 : #include <svl/intitem.hxx>
57 :
58 :
59 :
60 : // Project-local header
61 :
62 :
63 :
64 : #include <com/sun/star/beans/PropertyState.hpp>
65 :
66 : #include <editeng/unolingu.hxx>
67 : #include <editeng/unopracc.hxx>
68 : #include "editeng/AccessibleEditableTextPara.hxx"
69 : #include "AccessibleHyperlink.hxx"
70 :
71 : #include <svtools/colorcfg.hxx>
72 : using namespace std;
73 : #include "editeng.hrc"
74 : #include <editeng/eerdll.hxx>
75 : #include <editeng/numitem.hxx>
76 : #include <boost/scoped_array.hpp>
77 :
78 : using namespace ::com::sun::star;
79 : using namespace ::com::sun::star::beans;
80 : using namespace ::com::sun::star::accessibility;
81 :
82 :
83 :
84 : // AccessibleEditableTextPara implementation
85 :
86 :
87 :
88 : namespace accessibility
89 : {
90 2 : const SvxItemPropertySet* ImplGetSvxCharAndParaPropertiesSet()
91 : {
92 : // PropertyMap for character and paragraph properties
93 : static const SfxItemPropertyMapEntry aPropMap[] =
94 : {
95 5 : SVX_UNOEDIT_OUTLINER_PROPERTIES,
96 50 : SVX_UNOEDIT_CHAR_PROPERTIES,
97 14 : SVX_UNOEDIT_PARA_PROPERTIES,
98 2 : SVX_UNOEDIT_NUMBERING_PROPERTIE,
99 1 : {OUString("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS, cppu::UnoType<com::sun::star::container::XNameContainer>::get(), 0, 0},
100 1 : {OUString("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS, cppu::UnoType<com::sun::star::container::XNameContainer>::get(), 0, 0},
101 : { OUString(), 0, css::uno::Type(), 0, 0 }
102 76 : };
103 2 : static SvxItemPropertySet aPropSet( aPropMap, EditEngine::GetGlobalItemPool() );
104 2 : return &aPropSet;
105 : }
106 :
107 : // #i27138# - add parameter <_pParaManager>
108 32 : AccessibleEditableTextPara::AccessibleEditableTextPara(
109 : const uno::Reference< XAccessible >& rParent,
110 : const AccessibleParaManager* _pParaManager )
111 : : AccessibleTextParaInterfaceBase( m_aMutex ),
112 : mnParagraphIndex( 0 ),
113 : mnIndexInParent( 0 ),
114 : mpEditSource( NULL ),
115 : maEEOffset( 0, 0 ),
116 : mxParent( rParent ),
117 : // well, that's strictly (UNO) exception safe, though not
118 : // really robust. We rely on the fact that this member is
119 : // constructed last, and that the constructor body catches
120 : // exceptions, thus no chance for exceptions once the Id is
121 : // fetched. Nevertheless, normally should employ RAII here...
122 32 : mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient()),
123 : // #i27138#
124 64 : mpParaManager( _pParaManager )
125 : {
126 : #ifdef DBG_UTIL
127 : OSL_TRACE( "AccessibleEditableTextPara received ID: %d", mnNotifierClientId );
128 : #endif
129 :
130 : try
131 : {
132 : // Create the state set.
133 32 : ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper ();
134 32 : mxStateSet = pStateSet;
135 :
136 : // these are always on
137 32 : pStateSet->AddState( AccessibleStateType::MULTI_LINE );
138 32 : pStateSet->AddState( AccessibleStateType::FOCUSABLE );
139 32 : pStateSet->AddState( AccessibleStateType::VISIBLE );
140 32 : pStateSet->AddState( AccessibleStateType::SHOWING );
141 32 : pStateSet->AddState( AccessibleStateType::ENABLED );
142 32 : pStateSet->AddState( AccessibleStateType::SENSITIVE );
143 : }
144 0 : catch (const uno::Exception&)
145 : {
146 : }
147 32 : }
148 :
149 96 : AccessibleEditableTextPara::~AccessibleEditableTextPara()
150 : {
151 : // sign off from event notifier
152 32 : if( getNotifierClientId() != -1 )
153 : {
154 : try
155 : {
156 8 : ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() );
157 : #ifdef DBG_UTIL
158 : OSL_TRACE( "AccessibleEditableTextPara revoked ID: %d", mnNotifierClientId );
159 : #endif
160 : }
161 0 : catch (const uno::Exception&)
162 : {
163 : }
164 : }
165 64 : }
166 :
167 135 : OUString AccessibleEditableTextPara::implGetText()
168 : {
169 135 : return GetTextRange( 0, GetTextLen() );
170 : }
171 :
172 3 : ::com::sun::star::lang::Locale AccessibleEditableTextPara::implGetLocale()
173 : {
174 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_INT32,
175 : "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
176 :
177 : // return locale of first character in the paragraph
178 3 : return LanguageTag(GetTextForwarder().GetLanguage( GetParagraphIndex(), 0 )).getLocale();
179 : }
180 :
181 0 : void AccessibleEditableTextPara::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
182 : {
183 : sal_Int32 nStart, nEnd;
184 :
185 0 : if( GetSelection( nStart, nEnd ) )
186 : {
187 0 : nStartIndex = nStart;
188 0 : nEndIndex = nEnd;
189 : }
190 : else
191 : {
192 : // #102234# No exception, just set to 'invalid'
193 0 : nStartIndex = -1;
194 0 : nEndIndex = -1;
195 : }
196 0 : }
197 :
198 4 : void AccessibleEditableTextPara::implGetParagraphBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 /*nIndex*/ )
199 : {
200 : DBG_WARNING( "AccessibleEditableTextPara::implGetParagraphBoundary: only a base implementation, ignoring the index" );
201 :
202 4 : rBoundary.startPos = 0;
203 : //rBoundary.endPos = GetTextLen();
204 4 : OUString sText( implGetText() );
205 4 : sal_Int32 nLength = sText.getLength();
206 4 : rBoundary.endPos = nLength;
207 4 : }
208 :
209 0 : void AccessibleEditableTextPara::implGetLineBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex )
210 : {
211 0 : SvxTextForwarder& rCacheTF = GetTextForwarder();
212 0 : const sal_Int32 nParaIndex = GetParagraphIndex();
213 :
214 : DBG_ASSERT(nParaIndex >= 0 && nParaIndex <= SAL_MAX_INT32,
215 : "AccessibleEditableTextPara::implGetLineBoundary: paragraph index value overflow");
216 :
217 0 : const sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex );
218 :
219 0 : CheckPosition(nIndex);
220 :
221 0 : rBoundary.startPos = rBoundary.endPos = -1;
222 :
223 0 : const sal_Int32 nLineCount=rCacheTF.GetLineCount( nParaIndex );
224 :
225 0 : if( nIndex == nTextLen )
226 : {
227 : // #i17014# Special-casing one-behind-the-end character
228 0 : if( nLineCount <= 1 )
229 0 : rBoundary.startPos = 0;
230 : else
231 0 : rBoundary.startPos = nTextLen - rCacheTF.GetLineLen( nParaIndex,
232 0 : nLineCount-1 );
233 :
234 0 : rBoundary.endPos = nTextLen;
235 : }
236 : else
237 : {
238 : // normal line search
239 : sal_Int32 nLine;
240 : sal_Int32 nCurIndex;
241 0 : for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
242 : {
243 0 : nCurIndex += rCacheTF.GetLineLen( nParaIndex, nLine);
244 :
245 0 : if( nCurIndex > nIndex )
246 : {
247 0 : rBoundary.startPos = nCurIndex - rCacheTF.GetLineLen( nParaIndex, nLine);
248 0 : rBoundary.endPos = nCurIndex;
249 0 : break;
250 : }
251 : }
252 : }
253 0 : }
254 :
255 :
256 27 : void AccessibleEditableTextPara::SetIndexInParent( sal_Int32 nIndex )
257 : {
258 27 : mnIndexInParent = nIndex;
259 27 : }
260 :
261 :
262 27 : void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex )
263 : {
264 27 : sal_Int32 nOldIndex = mnParagraphIndex;
265 :
266 27 : mnParagraphIndex = nIndex;
267 :
268 27 : WeakBullet::HardRefType aChild( maImageBullet.get() );
269 27 : if( aChild.is() )
270 0 : aChild->SetParagraphIndex(mnParagraphIndex);
271 :
272 : try
273 : {
274 27 : if( nOldIndex != nIndex )
275 : {
276 0 : uno::Any aOldDesc;
277 0 : uno::Any aOldName;
278 :
279 : try
280 : {
281 0 : aOldDesc <<= getAccessibleDescription();
282 0 : aOldName <<= getAccessibleName();
283 : }
284 0 : catch (const uno::Exception&) // optional behaviour
285 : {
286 : }
287 : // index and therefore description changed
288 0 : FireEvent( AccessibleEventId::DESCRIPTION_CHANGED, uno::makeAny( getAccessibleDescription() ), aOldDesc );
289 0 : FireEvent( AccessibleEventId::NAME_CHANGED, uno::makeAny( getAccessibleName() ), aOldName );
290 : }
291 : }
292 0 : catch (const uno::Exception&) // optional behaviour
293 : {
294 27 : }
295 27 : }
296 :
297 :
298 27 : void AccessibleEditableTextPara::Dispose()
299 : {
300 27 : int nClientId( getNotifierClientId() );
301 :
302 : // #108212# drop all references before notifying dispose
303 27 : mxParent = NULL;
304 27 : mnNotifierClientId = -1;
305 27 : mpEditSource = NULL;
306 :
307 : // notify listeners
308 27 : if( nClientId != -1 )
309 : {
310 : try
311 : {
312 24 : uno::Reference < XAccessibleContext > xThis = getAccessibleContext();
313 :
314 : // #106234# Delegate to EventNotifier
315 24 : ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, xThis );
316 : #ifdef DBG_UTIL
317 : OSL_TRACE( "Disposed ID: %d", nClientId );
318 : #endif
319 : }
320 0 : catch (const uno::Exception&)
321 : {
322 : }
323 : }
324 27 : }
325 :
326 34 : void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter* pEditSource )
327 : {
328 34 : WeakBullet::HardRefType aChild( maImageBullet.get() );
329 34 : if( aChild.is() )
330 0 : aChild->SetEditSource(pEditSource);
331 :
332 34 : if( !pEditSource )
333 : {
334 : // going defunc
335 2 : UnSetState( AccessibleStateType::SHOWING );
336 2 : UnSetState( AccessibleStateType::VISIBLE );
337 2 : SetState( AccessibleStateType::INVALID );
338 2 : SetState( AccessibleStateType::DEFUNC );
339 :
340 2 : Dispose();
341 : }
342 34 : mpEditSource = pEditSource;
343 : // #108900# Init last text content
344 : try
345 : {
346 34 : TextChanged();
347 : }
348 2 : catch (const uno::RuntimeException&)
349 : {
350 34 : }
351 34 : }
352 :
353 143 : ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex )
354 : {
355 : // check overflow
356 : DBG_ASSERT(nStartEEIndex >= 0 && nStartEEIndex <= USHRT_MAX &&
357 : nEndEEIndex >= 0 && nEndEEIndex <= USHRT_MAX &&
358 : GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_INT32,
359 : "AccessibleEditableTextPara::MakeSelection: index value overflow");
360 :
361 143 : sal_Int32 nParaIndex = GetParagraphIndex();
362 143 : return ESelection(nParaIndex, nStartEEIndex, nParaIndex, nEndEEIndex);
363 : }
364 :
365 1 : ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nEEIndex )
366 : {
367 1 : return MakeSelection( nEEIndex, nEEIndex+1 );
368 : }
369 :
370 0 : ESelection AccessibleEditableTextPara::MakeCursor( sal_Int32 nEEIndex )
371 : {
372 0 : return MakeSelection( nEEIndex, nEEIndex );
373 : }
374 :
375 4 : void AccessibleEditableTextPara::CheckIndex( sal_Int32 nIndex )
376 : {
377 4 : if( nIndex < 0 || nIndex >= getCharacterCount() )
378 : throw lang::IndexOutOfBoundsException("AccessibleEditableTextPara: character index out of bounds",
379 : uno::Reference< uno::XInterface >
380 2 : ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy
381 2 : }
382 :
383 35 : void AccessibleEditableTextPara::CheckPosition( sal_Int32 nIndex )
384 : {
385 35 : if( nIndex < 0 || nIndex > getCharacterCount() )
386 : throw lang::IndexOutOfBoundsException("AccessibleEditableTextPara: character position out of bounds",
387 : uno::Reference< uno::XInterface >
388 4 : ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy
389 31 : }
390 :
391 3 : void AccessibleEditableTextPara::CheckRange( sal_Int32 nStart, sal_Int32 nEnd )
392 : {
393 3 : CheckPosition( nStart );
394 1 : CheckPosition( nEnd );
395 1 : }
396 :
397 0 : bool AccessibleEditableTextPara::GetSelection(sal_Int32 &nStartPos, sal_Int32 &nEndPos)
398 : {
399 0 : ESelection aSelection;
400 0 : sal_Int32 nPara = GetParagraphIndex();
401 0 : if( !GetEditViewForwarder().GetSelection( aSelection ) )
402 0 : return false;
403 :
404 0 : if( aSelection.nStartPara < aSelection.nEndPara )
405 : {
406 0 : if( aSelection.nStartPara > nPara ||
407 0 : aSelection.nEndPara < nPara )
408 0 : return false;
409 :
410 0 : if( nPara == aSelection.nStartPara )
411 0 : nStartPos = aSelection.nStartPos;
412 : else
413 0 : nStartPos = 0;
414 :
415 0 : if( nPara == aSelection.nEndPara )
416 0 : nEndPos = aSelection.nEndPos;
417 : else
418 0 : nEndPos = GetTextLen();
419 : }
420 : else
421 : {
422 0 : if( aSelection.nStartPara < nPara ||
423 0 : aSelection.nEndPara > nPara )
424 0 : return false;
425 :
426 0 : if( nPara == aSelection.nStartPara )
427 0 : nStartPos = aSelection.nStartPos;
428 : else
429 0 : nStartPos = GetTextLen();
430 :
431 0 : if( nPara == aSelection.nEndPara )
432 0 : nEndPos = aSelection.nEndPos;
433 : else
434 0 : nEndPos = 0;
435 : }
436 :
437 0 : return true;
438 : }
439 :
440 141 : OUString AccessibleEditableTextPara::GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
441 : {
442 141 : return GetTextForwarder().GetText( MakeSelection(nStartIndex, nEndIndex) );
443 : }
444 :
445 136 : sal_Int32 AccessibleEditableTextPara::GetTextLen() const
446 : {
447 136 : return GetTextForwarder().GetTextLen(GetParagraphIndex());
448 : }
449 :
450 577 : SvxEditSourceAdapter& AccessibleEditableTextPara::GetEditSource() const
451 : {
452 577 : if( mpEditSource )
453 1150 : return *mpEditSource;
454 : else
455 : throw uno::RuntimeException("No edit source, object is defunct",
456 : uno::Reference< uno::XInterface >
457 : ( static_cast< ::cppu::OWeakObject* >
458 2 : ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
459 : }
460 :
461 468 : SvxAccessibleTextAdapter& AccessibleEditableTextPara::GetTextForwarder() const
462 : {
463 468 : SvxEditSourceAdapter& rEditSource = GetEditSource();
464 466 : SvxAccessibleTextAdapter* pTextForwarder = rEditSource.GetTextForwarderAdapter();
465 :
466 466 : if( !pTextForwarder )
467 : throw uno::RuntimeException("Unable to fetch text forwarder, object is defunct",
468 : uno::Reference< uno::XInterface >
469 : ( static_cast< ::cppu::OWeakObject* >
470 0 : ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
471 :
472 466 : if( pTextForwarder->IsValid() )
473 932 : return *pTextForwarder;
474 : else
475 : throw uno::RuntimeException("Text forwarder is invalid, object is defunct",
476 : uno::Reference< uno::XInterface >
477 : ( static_cast< ::cppu::OWeakObject* >
478 0 : ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
479 : }
480 :
481 106 : SvxViewForwarder& AccessibleEditableTextPara::GetViewForwarder() const
482 : {
483 106 : SvxEditSource& rEditSource = GetEditSource();
484 106 : SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder();
485 :
486 106 : if( !pViewForwarder )
487 : {
488 : throw uno::RuntimeException("Unable to fetch view forwarder, object is defunct",
489 : uno::Reference< uno::XInterface >
490 : ( static_cast< ::cppu::OWeakObject* >
491 0 : ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
492 : }
493 :
494 106 : if( pViewForwarder->IsValid() )
495 212 : return *pViewForwarder;
496 : else
497 : throw uno::RuntimeException("View forwarder is invalid, object is defunct",
498 : uno::Reference< uno::XInterface >
499 : ( static_cast< ::cppu::OWeakObject* >
500 0 : ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
501 : }
502 :
503 1 : SvxAccessibleTextEditViewAdapter& AccessibleEditableTextPara::GetEditViewForwarder( bool bCreate ) const
504 : {
505 1 : SvxEditSourceAdapter& rEditSource = GetEditSource();
506 1 : SvxAccessibleTextEditViewAdapter* pTextEditViewForwarder = rEditSource.GetEditViewForwarderAdapter( bCreate );
507 :
508 1 : if( !pTextEditViewForwarder )
509 : {
510 1 : if( bCreate )
511 : throw uno::RuntimeException("Unable to fetch view forwarder, object is defunct",
512 : uno::Reference< uno::XInterface >
513 : ( static_cast< ::cppu::OWeakObject* >
514 1 : ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
515 : else
516 : throw uno::RuntimeException("No view forwarder, object not in edit mode",
517 : uno::Reference< uno::XInterface >
518 : ( static_cast< ::cppu::OWeakObject* >
519 0 : ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
520 : }
521 :
522 0 : if( pTextEditViewForwarder->IsValid() )
523 0 : return *pTextEditViewForwarder;
524 : else
525 : {
526 0 : if( bCreate )
527 : throw uno::RuntimeException("View forwarder is invalid, object is defunct",
528 : uno::Reference< uno::XInterface >
529 : ( static_cast< ::cppu::OWeakObject* >
530 0 : ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
531 : else
532 : throw uno::RuntimeException("View forwarder is invalid, object not in edit mode",
533 : uno::Reference< uno::XInterface >
534 : ( static_cast< ::cppu::OWeakObject* >
535 0 : ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
536 : }
537 : }
538 :
539 0 : bool AccessibleEditableTextPara::HaveEditView() const
540 : {
541 0 : SvxEditSource& rEditSource = GetEditSource();
542 0 : SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder();
543 :
544 0 : if( !pViewForwarder )
545 0 : return false;
546 :
547 0 : if( !pViewForwarder->IsValid() )
548 0 : return false;
549 :
550 0 : return true;
551 : }
552 :
553 53 : bool AccessibleEditableTextPara::HaveChildren()
554 : {
555 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_INT32,
556 : "AccessibleEditableTextPara::HaveChildren: paragraph index value overflow");
557 :
558 53 : return GetTextForwarder().HaveImageBullet( GetParagraphIndex() );
559 : }
560 :
561 150 : Rectangle AccessibleEditableTextPara::LogicToPixel( const Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder& rForwarder )
562 : {
563 : // convert to screen coordinates
564 300 : return Rectangle( rForwarder.LogicToPixel( rRect.TopLeft(), rMapMode ),
565 450 : rForwarder.LogicToPixel( rRect.BottomRight(), rMapMode ) );
566 : }
567 :
568 :
569 37 : void AccessibleEditableTextPara::SetEEOffset( const Point& rOffset )
570 : {
571 37 : WeakBullet::HardRefType aChild( maImageBullet.get() );
572 37 : if( aChild.is() )
573 0 : aChild->SetEEOffset(rOffset);
574 :
575 37 : maEEOffset = rOffset;
576 37 : }
577 :
578 42 : void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue) const
579 : {
580 42 : uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleEditableTextPara* > (this)->getAccessibleContext() );
581 :
582 84 : AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue);
583 :
584 : // #102261# Call global queue for focus events
585 42 : if( nEventId == AccessibleEventId::STATE_CHANGED )
586 14 : vcl::unohelper::NotifyAccessibleStateEventGlobally( aEvent );
587 :
588 : // #106234# Delegate to EventNotifier
589 42 : if( getNotifierClientId() != -1 )
590 34 : ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(),
591 76 : aEvent );
592 42 : }
593 :
594 10 : void AccessibleEditableTextPara::GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const
595 : {
596 10 : FireEvent( nEventId, rNewValue );
597 10 : }
598 :
599 4 : void AccessibleEditableTextPara::LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const
600 : {
601 4 : FireEvent( nEventId, uno::Any(), rOldValue );
602 4 : }
603 :
604 10 : void AccessibleEditableTextPara::SetState( const sal_Int16 nStateId )
605 : {
606 10 : ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
607 20 : if( pStateSet != NULL &&
608 10 : !pStateSet->contains(nStateId) )
609 : {
610 10 : pStateSet->AddState( nStateId );
611 10 : GotPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED );
612 : }
613 10 : }
614 :
615 4 : void AccessibleEditableTextPara::UnSetState( const sal_Int16 nStateId )
616 : {
617 4 : ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
618 8 : if( pStateSet != NULL &&
619 4 : pStateSet->contains(nStateId) )
620 : {
621 4 : pStateSet->RemoveState( nStateId );
622 4 : LostPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED );
623 : }
624 4 : }
625 :
626 34 : void AccessibleEditableTextPara::TextChanged()
627 : {
628 34 : OUString aCurrentString( OCommonAccessibleText::getText() );
629 64 : uno::Any aDeleted;
630 64 : uno::Any aInserted;
631 32 : if( OCommonAccessibleText::implInitTextChangedEvent( maLastTextString, aCurrentString,
632 32 : aDeleted, aInserted) )
633 : {
634 22 : FireEvent( AccessibleEventId::TEXT_CHANGED, aInserted, aDeleted );
635 22 : maLastTextString = aCurrentString;
636 32 : }
637 32 : }
638 :
639 0 : bool AccessibleEditableTextPara::GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nIndex )
640 : {
641 : DBG_ASSERT(nIndex >= 0 && nIndex <= SAL_MAX_INT32,
642 : "AccessibleEditableTextPara::GetAttributeRun: index value overflow");
643 :
644 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_INT32,
645 : "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
646 :
647 0 : return GetTextForwarder().GetAttributeRun( nStartIndex,
648 : nEndIndex,
649 : GetParagraphIndex(),
650 0 : nIndex );
651 : }
652 :
653 391 : uno::Any SAL_CALL AccessibleEditableTextPara::queryInterface (const uno::Type & rType) throw (uno::RuntimeException, std::exception)
654 : {
655 391 : uno::Any aRet;
656 :
657 : // must provide XAccesibleText by hand, since it comes publicly inherited by XAccessibleEditableText
658 391 : if ( rType == cppu::UnoType<XAccessibleText>::get())
659 : {
660 1 : uno::Reference< XAccessibleText > aAccText = static_cast< XAccessibleEditableText * >(this);
661 1 : aRet <<= aAccText;
662 : }
663 390 : else if ( rType == cppu::UnoType<XAccessibleEditableText>::get())
664 : {
665 0 : uno::Reference< XAccessibleEditableText > aAccEditText = this;
666 0 : aRet <<= aAccEditText;
667 : }
668 390 : else if ( rType == cppu::UnoType<XAccessibleHypertext>::get())
669 : {
670 0 : uno::Reference< XAccessibleHypertext > aAccHyperText = this;
671 0 : aRet <<= aAccHyperText;
672 : }
673 : else
674 : {
675 390 : aRet = AccessibleTextParaInterfaceBase::queryInterface(rType);
676 : }
677 :
678 391 : return aRet;
679 : }
680 :
681 : // XAccessible
682 115 : uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext() throw (uno::RuntimeException, std::exception)
683 : {
684 : // We implement the XAccessibleContext interface in the same object
685 115 : return uno::Reference< XAccessibleContext > ( this );
686 : }
687 :
688 : // XAccessibleContext
689 53 : sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleChildCount() throw (uno::RuntimeException, std::exception)
690 : {
691 53 : SolarMutexGuard aGuard;
692 :
693 53 : return HaveChildren() ? 1 : 0;
694 : }
695 :
696 0 : uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
697 : {
698 0 : SolarMutexGuard aGuard;
699 :
700 0 : if( !HaveChildren() )
701 : throw lang::IndexOutOfBoundsException("No children available",
702 : uno::Reference< uno::XInterface >
703 0 : ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy
704 :
705 0 : if( i != 0 )
706 : throw lang::IndexOutOfBoundsException("Invalid child index",
707 : uno::Reference< uno::XInterface >
708 0 : ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy
709 :
710 0 : WeakBullet::HardRefType aChild( maImageBullet.get() );
711 :
712 0 : if( !aChild.is() )
713 : {
714 : // there is no hard reference available, create object then
715 0 : AccessibleImageBullet* pChild = new AccessibleImageBullet( uno::Reference< XAccessible >( this ) );
716 0 : uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY );
717 :
718 0 : if( !xChild.is() )
719 : throw uno::RuntimeException("Child creation failed",
720 : uno::Reference< uno::XInterface >
721 0 : ( static_cast< ::cppu::OWeakObject* > (this) ) );
722 :
723 0 : aChild = WeakBullet::HardRefType( xChild, pChild );
724 :
725 0 : aChild->SetEditSource( &GetEditSource() );
726 0 : aChild->SetParagraphIndex( GetParagraphIndex() );
727 0 : aChild->SetIndexInParent( i );
728 :
729 0 : maImageBullet = aChild;
730 : }
731 :
732 0 : return aChild.getRef();
733 : }
734 :
735 62 : uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleParent() throw (uno::RuntimeException, std::exception)
736 : {
737 :
738 : #ifdef DBG_UTIL
739 : if( !mxParent.is() )
740 : OSL_TRACE( "AccessibleEditableTextPara::getAccessibleParent: no frontend set, did somebody forgot to call AccessibleTextHelper::SetEventSource()?");
741 : #endif
742 :
743 62 : return mxParent;
744 : }
745 :
746 8 : sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleIndexInParent() throw (uno::RuntimeException, std::exception)
747 : {
748 8 : return mnIndexInParent;
749 : }
750 :
751 40 : sal_Int16 SAL_CALL AccessibleEditableTextPara::getAccessibleRole() throw (uno::RuntimeException, std::exception)
752 : {
753 40 : return AccessibleRole::PARAGRAPH;
754 : }
755 :
756 19 : OUString SAL_CALL AccessibleEditableTextPara::getAccessibleDescription() throw (uno::RuntimeException, std::exception)
757 : {
758 19 : SolarMutexGuard aGuard;
759 :
760 : // append first 40 characters from text, or first line, if shorter
761 : // (writer takes first sentence here, but that's not supported
762 : // from EditEngine)
763 : // throws if defunc
764 38 : OUString aLine;
765 :
766 19 : if( getCharacterCount() )
767 8 : aLine = getTextAtIndex(0, AccessibleTextType::LINE).SegmentText;
768 :
769 : // Get the string from the resource for the specified id.
770 38 : OUString sStr(EditResId(RID_SVXSTR_A11Y_PARAGRAPH_DESCRIPTION));
771 38 : OUString sParaIndex = OUString::number(GetParagraphIndex());
772 19 : sStr = sStr.replaceFirst("$(ARG)", sParaIndex);
773 :
774 19 : if( aLine.getLength() > MaxDescriptionLen )
775 : {
776 0 : OUString aCurrWord;
777 : sal_Int32 i;
778 :
779 : // search backward from MaxDescriptionLen for previous word start
780 0 : for( aCurrWord=getTextAtIndex(MaxDescriptionLen, AccessibleTextType::WORD).SegmentText,
781 : i=MaxDescriptionLen,
782 0 : aLine=OUString();
783 : i>=0;
784 : --i )
785 : {
786 0 : if( getTextAtIndex(i, AccessibleTextType::WORD).SegmentText != aCurrWord )
787 : {
788 0 : if( i == 0 )
789 : // prevent completely empty string
790 0 : aLine = getTextAtIndex(0, AccessibleTextType::WORD).SegmentText;
791 : else
792 0 : aLine = getTextRange(0, i);
793 : }
794 0 : }
795 : }
796 :
797 38 : return OUString( sStr ) + aLine;
798 : }
799 :
800 21 : OUString SAL_CALL AccessibleEditableTextPara::getAccessibleName() throw (uno::RuntimeException, std::exception)
801 : {
802 21 : SolarMutexGuard aGuard;
803 :
804 : // throws if defunc
805 21 : sal_Int32 nPara( GetParagraphIndex() );
806 :
807 : // Get the string from the resource for the specified id.
808 42 : OUString sStr(EditResId(RID_SVXSTR_A11Y_PARAGRAPH_NAME));
809 42 : OUString sParaIndex = OUString::number(nPara);
810 42 : return sStr.replaceFirst("$(ARG)", sParaIndex);
811 : }
812 :
813 1 : uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleEditableTextPara::getAccessibleRelationSet() throw (uno::RuntimeException, std::exception)
814 : {
815 : // #i27138# - provide relations CONTENT_FLOWS_FROM
816 : // and CONTENT_FLOWS_TO
817 1 : if ( mpParaManager )
818 : {
819 : utl::AccessibleRelationSetHelper* pAccRelSetHelper =
820 1 : new utl::AccessibleRelationSetHelper();
821 1 : sal_Int32 nMyParaIndex( GetParagraphIndex() );
822 : // relation CONTENT_FLOWS_FROM
823 1 : if ( nMyParaIndex > 0 &&
824 0 : mpParaManager->IsReferencable( nMyParaIndex - 1 ) )
825 : {
826 0 : uno::Sequence<uno::Reference<XInterface> > aSequence(1);
827 0 : aSequence[0] =
828 0 : mpParaManager->GetChild( nMyParaIndex - 1 ).first.get().getRef();
829 : AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM,
830 0 : aSequence );
831 0 : pAccRelSetHelper->AddRelation( aAccRel );
832 : }
833 :
834 : // relation CONTENT_FLOWS_TO
835 1 : if ( (nMyParaIndex + 1) < (sal_Int32)mpParaManager->GetNum() &&
836 0 : mpParaManager->IsReferencable( nMyParaIndex + 1 ) )
837 : {
838 0 : uno::Sequence<uno::Reference<XInterface> > aSequence(1);
839 0 : aSequence[0] =
840 0 : mpParaManager->GetChild( nMyParaIndex + 1 ).first.get().getRef();
841 : AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO,
842 0 : aSequence );
843 0 : pAccRelSetHelper->AddRelation( aAccRel );
844 : }
845 :
846 1 : return pAccRelSetHelper;
847 : }
848 : else
849 : {
850 : // no relations, therefore empty
851 0 : return uno::Reference< XAccessibleRelationSet >();
852 : }
853 : }
854 :
855 0 : static uno::Sequence< OUString > getAttributeNames()
856 : {
857 : static uno::Sequence< OUString >* pNames = NULL;
858 :
859 0 : if( pNames == NULL )
860 : {
861 0 : uno::Sequence< OUString >* pSeq = new uno::Sequence< OUString >( 21 );
862 0 : OUString* pStrings = pSeq->getArray();
863 0 : sal_Int32 i = 0;
864 : #define STR(x) pStrings[i++] = x
865 0 : STR("CharColor");
866 0 : STR("CharContoured");
867 0 : STR("CharEmphasis");
868 0 : STR("CharEscapement");
869 0 : STR("CharFontName");
870 0 : STR("CharHeight");
871 0 : STR("CharPosture");
872 0 : STR("CharShadowed");
873 0 : STR("CharStrikeout");
874 0 : STR("CharCaseMap");
875 0 : STR("CharUnderline");
876 0 : STR("CharUnderlineColor");
877 0 : STR("CharWeight");
878 0 : STR("NumberingLevel");
879 0 : STR("NumberingRules");
880 0 : STR("ParaAdjust");
881 0 : STR("ParaBottomMargin");
882 0 : STR("ParaFirstLineIndent");
883 0 : STR("ParaLeftMargin");
884 0 : STR("ParaLineSpacing");
885 0 : STR("ParaRightMargin");
886 0 : STR("ParaTabStops");
887 : #undef STR
888 : DBG_ASSERT( i == pSeq->getLength(), "Please adjust length" );
889 0 : if( i != pSeq->getLength() )
890 0 : pSeq->realloc( i );
891 0 : pNames = pSeq;
892 : }
893 0 : return *pNames;
894 : }
895 :
896 : struct IndexCompare
897 : {
898 : const PropertyValue* pValues;
899 0 : IndexCompare( const PropertyValue* pVals ) : pValues(pVals) {}
900 0 : bool operator() ( const sal_Int32& a, const sal_Int32& b ) const
901 : {
902 0 : return pValues[a].Name < pValues[b].Name;
903 : }
904 : };
905 :
906 0 : OUString AccessibleEditableTextPara::GetFieldTypeNameAtIndex(sal_Int32 nIndex)
907 : {
908 0 : OUString strFldType;
909 0 : SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();
910 : //For field object info
911 0 : sal_Int32 nParaIndex = GetParagraphIndex();
912 0 : sal_Int32 nAllFieldLen = 0;
913 0 : sal_Int32 nField = rCacheTF.GetFieldCount(nParaIndex), nFoundFieldIndex = -1;
914 0 : EFieldInfo ree;
915 : sal_Int32 reeBegin, reeEnd;
916 0 : sal_Int32 nFieldType = -1;
917 0 : for(sal_Int32 j = 0; j < nField; j++)
918 : {
919 0 : ree = rCacheTF.GetFieldInfo(nParaIndex, j);
920 0 : reeBegin = ree.aPosition.nIndex + nAllFieldLen;
921 0 : reeEnd = reeBegin + ree.aCurrentText.getLength();
922 0 : nAllFieldLen += (ree.aCurrentText.getLength() - 1);
923 0 : if( reeBegin > nIndex )
924 : {
925 0 : break;
926 : }
927 0 : if( nIndex >= reeBegin && nIndex < reeEnd )
928 : {
929 0 : nFoundFieldIndex = j;
930 0 : break;
931 : }
932 : }
933 0 : if (nFoundFieldIndex >= 0 && ree.pFieldItem)
934 : {
935 : // So we get a field, check its type now.
936 0 : nFieldType = ree.pFieldItem->GetField()->GetClassId() ;
937 : }
938 0 : switch(nFieldType)
939 : {
940 : case text::textfield::Type::DATE:
941 : {
942 0 : const SvxDateField* pDateField = static_cast< const SvxDateField* >(ree.pFieldItem->GetField());
943 0 : if (pDateField)
944 : {
945 0 : if (pDateField->GetType() == SVXDATETYPE_FIX)
946 0 : strFldType = "date (fixed)";
947 0 : else if (pDateField->GetType() == SVXDATETYPE_VAR)
948 0 : strFldType = "date (variable)";
949 : }
950 : }
951 0 : break;
952 : case text::textfield::Type::PAGE:
953 0 : strFldType = "page-number";
954 0 : break;
955 : //support the sheet name & pages fields
956 : case text::textfield::Type::PAGES:
957 0 : strFldType = "page-count";
958 0 : break;
959 : case text::textfield::Type::TABLE:
960 0 : strFldType = "sheet-name";
961 0 : break;
962 : //End
963 : case text::textfield::Type::TIME:
964 0 : strFldType = "time";
965 0 : break;
966 : case text::textfield::Type::EXTENDED_TIME:
967 : {
968 0 : const SvxExtTimeField* pTimeField = static_cast< const SvxExtTimeField* >(ree.pFieldItem->GetField());
969 0 : if (pTimeField)
970 : {
971 0 : if (pTimeField->GetType() == SVXTIMETYPE_FIX)
972 0 : strFldType = "time (fixed)";
973 0 : else if (pTimeField->GetType() == SVXTIMETYPE_VAR)
974 0 : strFldType = "time (variable)";
975 : }
976 : }
977 0 : break;
978 : case text::textfield::Type::AUTHOR:
979 0 : strFldType = "author";
980 0 : break;
981 : case text::textfield::Type::EXTENDED_FILE:
982 : case text::textfield::Type::DOCINFO_TITLE:
983 0 : strFldType = "file name";
984 : default:
985 0 : break;
986 : }
987 0 : return strFldType;
988 : }
989 :
990 23 : uno::Reference< XAccessibleStateSet > SAL_CALL AccessibleEditableTextPara::getAccessibleStateSet() throw (uno::RuntimeException, std::exception)
991 : {
992 23 : SolarMutexGuard aGuard;
993 :
994 : // Create a copy of the state set and return it.
995 23 : ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
996 :
997 23 : if( !pStateSet )
998 0 : return uno::Reference<XAccessibleStateSet>();
999 46 : uno::Reference<XAccessibleStateSet> xParentStates;
1000 23 : if (getAccessibleParent().is())
1001 : {
1002 23 : uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
1003 23 : xParentStates = xParentContext->getAccessibleStateSet();
1004 : }
1005 23 : if (xParentStates.is() && xParentStates->contains(AccessibleStateType::EDITABLE) )
1006 : {
1007 1 : pStateSet->AddState(AccessibleStateType::EDITABLE);
1008 : }
1009 46 : return uno::Reference<XAccessibleStateSet>( new ::utl::AccessibleStateSetHelper (*pStateSet) );
1010 : }
1011 :
1012 1 : lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale() throw (IllegalAccessibleComponentStateException, uno::RuntimeException, std::exception)
1013 : {
1014 1 : SolarMutexGuard aGuard;
1015 :
1016 1 : return implGetLocale();
1017 : }
1018 :
1019 1 : void SAL_CALL AccessibleEditableTextPara::addAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException, std::exception)
1020 : {
1021 1 : if( getNotifierClientId() != -1 )
1022 1 : ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener );
1023 1 : }
1024 :
1025 2 : void SAL_CALL AccessibleEditableTextPara::removeAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException, std::exception)
1026 : {
1027 2 : if( getNotifierClientId() != -1 )
1028 : {
1029 0 : const sal_Int32 nListenerCount = ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener );
1030 0 : if ( !nListenerCount )
1031 : {
1032 : // no listeners anymore
1033 : // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
1034 : // and at least to us not firing any events anymore, in case somebody calls
1035 : // NotifyAccessibleEvent, again
1036 0 : ::comphelper::AccessibleEventNotifier::TClientId nId( getNotifierClientId() );
1037 0 : mnNotifierClientId = -1;
1038 0 : ::comphelper::AccessibleEventNotifier::revokeClient( nId );
1039 : }
1040 : }
1041 2 : }
1042 :
1043 : // XAccessibleComponent
1044 3 : sal_Bool SAL_CALL AccessibleEditableTextPara::containsPoint( const awt::Point& aTmpPoint ) throw (uno::RuntimeException, std::exception)
1045 : {
1046 3 : SolarMutexGuard aGuard;
1047 :
1048 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_INT32,
1049 : "AccessibleEditableTextPara::contains: index value overflow");
1050 :
1051 3 : awt::Rectangle aTmpRect = getBounds();
1052 3 : Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) );
1053 3 : Point aPoint( aTmpPoint.X, aTmpPoint.Y );
1054 :
1055 3 : return aRect.IsInside( aPoint );
1056 : }
1057 :
1058 0 : uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point& _aPoint ) throw (uno::RuntimeException, std::exception)
1059 : {
1060 0 : SolarMutexGuard aGuard;
1061 :
1062 0 : if( HaveChildren() )
1063 : {
1064 : // #103862# No longer need to make given position relative
1065 0 : Point aPoint( _aPoint.X, _aPoint.Y );
1066 :
1067 : // respect EditEngine offset to surrounding shape/cell
1068 0 : aPoint -= GetEEOffset();
1069 :
1070 : // convert to EditEngine coordinate system
1071 0 : SvxTextForwarder& rCacheTF = GetTextForwarder();
1072 0 : Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
1073 :
1074 0 : EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(GetParagraphIndex());
1075 :
1076 0 : if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
1077 0 : aBulletInfo.bVisible &&
1078 0 : aBulletInfo.nType == SVX_NUM_BITMAP )
1079 : {
1080 0 : Rectangle aRect = aBulletInfo.aBounds;
1081 :
1082 0 : if( aRect.IsInside( aLogPoint ) )
1083 0 : return getAccessibleChild(0);
1084 0 : }
1085 : }
1086 :
1087 : // no children at all, or none at given position
1088 0 : return uno::Reference< XAccessible >();
1089 : }
1090 :
1091 74 : awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds() throw (uno::RuntimeException, std::exception)
1092 : {
1093 74 : SolarMutexGuard aGuard;
1094 :
1095 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_INT32,
1096 : "AccessibleEditableTextPara::getBounds: index value overflow");
1097 :
1098 74 : SvxTextForwarder& rCacheTF = GetTextForwarder();
1099 74 : Rectangle aRect = rCacheTF.GetParaBounds( GetParagraphIndex() );
1100 :
1101 : // convert to screen coordinates
1102 : Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
1103 74 : rCacheTF.GetMapMode(),
1104 148 : GetViewForwarder() );
1105 :
1106 : // offset from shape/cell
1107 74 : Point aOffset = GetEEOffset();
1108 :
1109 148 : return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
1110 148 : aScreenRect.Top() + aOffset.Y(),
1111 148 : aScreenRect.GetSize().Width(),
1112 518 : aScreenRect.GetSize().Height() );
1113 : }
1114 :
1115 0 : awt::Point SAL_CALL AccessibleEditableTextPara::getLocation( ) throw (uno::RuntimeException, std::exception)
1116 : {
1117 0 : SolarMutexGuard aGuard;
1118 :
1119 0 : awt::Rectangle aRect = getBounds();
1120 :
1121 0 : return awt::Point( aRect.X, aRect.Y );
1122 : }
1123 :
1124 0 : awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen( ) throw (uno::RuntimeException, std::exception)
1125 : {
1126 0 : SolarMutexGuard aGuard;
1127 :
1128 : // relate us to parent
1129 0 : uno::Reference< XAccessible > xParent = getAccessibleParent();
1130 0 : if( xParent.is() )
1131 : {
1132 0 : uno::Reference< XAccessibleComponent > xParentComponent( xParent, uno::UNO_QUERY );
1133 0 : if( xParentComponent.is() )
1134 : {
1135 0 : awt::Point aRefPoint = xParentComponent->getLocationOnScreen();
1136 0 : awt::Point aPoint = getLocation();
1137 0 : aPoint.X += aRefPoint.X;
1138 0 : aPoint.Y += aRefPoint.Y;
1139 :
1140 0 : return aPoint;
1141 : }
1142 : // #i88070#
1143 : // fallback to parent's <XAccessibleContext> instance
1144 : else
1145 : {
1146 0 : uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext();
1147 0 : if ( xParentContext.is() )
1148 : {
1149 0 : uno::Reference< XAccessibleComponent > xParentContextComponent( xParentContext, uno::UNO_QUERY );
1150 0 : if( xParentContextComponent.is() )
1151 : {
1152 0 : awt::Point aRefPoint = xParentContextComponent->getLocationOnScreen();
1153 0 : awt::Point aPoint = getLocation();
1154 0 : aPoint.X += aRefPoint.X;
1155 0 : aPoint.Y += aRefPoint.Y;
1156 :
1157 0 : return aPoint;
1158 0 : }
1159 0 : }
1160 0 : }
1161 : }
1162 :
1163 : throw uno::RuntimeException("Cannot access parent",
1164 : uno::Reference< uno::XInterface >
1165 0 : ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
1166 : }
1167 :
1168 0 : awt::Size SAL_CALL AccessibleEditableTextPara::getSize( ) throw (uno::RuntimeException, std::exception)
1169 : {
1170 0 : SolarMutexGuard aGuard;
1171 :
1172 0 : awt::Rectangle aRect = getBounds();
1173 :
1174 0 : return awt::Size( aRect.Width, aRect.Height );
1175 : }
1176 :
1177 0 : void SAL_CALL AccessibleEditableTextPara::grabFocus( ) throw (uno::RuntimeException, std::exception)
1178 : {
1179 : // set cursor to this paragraph
1180 0 : setSelection(0,0);
1181 0 : }
1182 :
1183 0 : sal_Int32 SAL_CALL AccessibleEditableTextPara::getForeground( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
1184 : {
1185 : // #104444# Added to XAccessibleComponent interface
1186 0 : svtools::ColorConfig aColorConfig;
1187 0 : sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
1188 0 : return static_cast<sal_Int32>(nColor);
1189 : }
1190 :
1191 0 : sal_Int32 SAL_CALL AccessibleEditableTextPara::getBackground( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
1192 : {
1193 : // #104444# Added to XAccessibleComponent interface
1194 0 : Color aColor( Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor() );
1195 :
1196 : // the background is transparent
1197 0 : aColor.SetTransparency( 0xFF);
1198 :
1199 0 : return static_cast<sal_Int32>( aColor.GetColor() );
1200 : }
1201 :
1202 : // XAccessibleText
1203 0 : sal_Int32 SAL_CALL AccessibleEditableTextPara::getCaretPosition() throw (uno::RuntimeException, std::exception)
1204 : {
1205 0 : SolarMutexGuard aGuard;
1206 :
1207 0 : if( !HaveEditView() )
1208 0 : return -1;
1209 :
1210 0 : ESelection aSelection;
1211 0 : if( GetEditViewForwarder().GetSelection( aSelection ) &&
1212 0 : GetParagraphIndex() == aSelection.nEndPara )
1213 : {
1214 : // caret is always nEndPara,nEndPos
1215 0 : EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
1216 0 : if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
1217 0 : aBulletInfo.bVisible &&
1218 0 : aBulletInfo.nType != SVX_NUM_BITMAP )
1219 : {
1220 0 : sal_Int32 nBulletLen = aBulletInfo.aText.getLength();
1221 0 : if( aSelection.nEndPos - nBulletLen >= 0 )
1222 0 : return aSelection.nEndPos - nBulletLen;
1223 : }
1224 0 : return aSelection.nEndPos;
1225 : }
1226 :
1227 : // not within this paragraph
1228 0 : return -1;
1229 : }
1230 :
1231 3 : sal_Bool SAL_CALL AccessibleEditableTextPara::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1232 : {
1233 3 : return setSelection(nIndex, nIndex);
1234 : }
1235 :
1236 7 : sal_Unicode SAL_CALL AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1237 : {
1238 7 : SolarMutexGuard aGuard;
1239 :
1240 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1241 : "AccessibleEditableTextPara::getCharacter: index value overflow");
1242 :
1243 7 : return OCommonAccessibleText::getCharacter( nIndex );
1244 : }
1245 :
1246 3 : uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< OUString >& rRequestedAttributes ) throw (lang::IndexOutOfBoundsException, beans::UnknownPropertyException, uno::RuntimeException, std::exception)
1247 : {
1248 3 : SolarMutexGuard aGuard;
1249 :
1250 : //Skip the bullet range to ingnore the bullet text
1251 3 : SvxTextForwarder& rCacheTF = GetTextForwarder();
1252 6 : EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(GetParagraphIndex());
1253 3 : if (aBulletInfo.bVisible)
1254 0 : nIndex += aBulletInfo.aText.getLength();
1255 3 : CheckIndex(nIndex); // may throw IndexOutOfBoundsException
1256 :
1257 1 : bool bSupplementalMode = false;
1258 2 : uno::Sequence< OUString > aPropertyNames = rRequestedAttributes;
1259 1 : if (aPropertyNames.getLength() == 0)
1260 : {
1261 0 : bSupplementalMode = true;
1262 0 : aPropertyNames = getAttributeNames();
1263 : }
1264 :
1265 : // get default attribues...
1266 2 : ::comphelper::SequenceAsHashMap aPropHashMap( getDefaultAttributes( aPropertyNames ) );
1267 :
1268 : // ... and override them with the direct attributes from the specific position
1269 2 : uno::Sequence< beans::PropertyValue > aRunAttribs( getRunAttributes( nIndex, aPropertyNames ) );
1270 1 : sal_Int32 nRunAttribs = aRunAttribs.getLength();
1271 1 : const beans::PropertyValue *pRunAttrib = aRunAttribs.getConstArray();
1272 1 : for (sal_Int32 k = 0; k < nRunAttribs; ++k)
1273 : {
1274 0 : const beans::PropertyValue &rRunAttrib = pRunAttrib[k];
1275 0 : aPropHashMap[ rRunAttrib.Name ] = rRunAttrib.Value; //!! should not only be the value !!
1276 : }
1277 :
1278 : // get resulting sequence
1279 2 : uno::Sequence< beans::PropertyValue > aRes;
1280 1 : aPropHashMap >> aRes;
1281 :
1282 : // since SequenceAsHashMap ignores property handles and property state
1283 : // we have to restore the property state here (property handles are
1284 : // of no use to the accessibility API).
1285 1 : sal_Int32 nRes = aRes.getLength();
1286 1 : beans::PropertyValue *pRes = aRes.getArray();
1287 1 : for (sal_Int32 i = 0; i < nRes; ++i)
1288 : {
1289 0 : beans::PropertyValue &rRes = pRes[i];
1290 0 : bool bIsDirectVal = false;
1291 0 : for (sal_Int32 k = 0; k < nRunAttribs && !bIsDirectVal; ++k)
1292 : {
1293 0 : if (rRes.Name == pRunAttrib[k].Name)
1294 0 : bIsDirectVal = true;
1295 : }
1296 0 : rRes.Handle = -1;
1297 0 : rRes.State = bIsDirectVal ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
1298 : }
1299 1 : if( bSupplementalMode )
1300 : {
1301 0 : _correctValues( nIndex, aRes );
1302 : // NumberingPrefix
1303 0 : nRes = aRes.getLength();
1304 0 : aRes.realloc( nRes + 1 );
1305 0 : pRes = aRes.getArray();
1306 0 : beans::PropertyValue &rRes = pRes[nRes];
1307 0 : rRes.Name = "NumberingPrefix";
1308 0 : OUString numStr;
1309 0 : if (aBulletInfo.nType != SVX_NUM_CHAR_SPECIAL && aBulletInfo.nType != SVX_NUM_BITMAP)
1310 0 : numStr = aBulletInfo.aText;
1311 0 : rRes.Value <<= numStr;
1312 0 : rRes.Handle = -1;
1313 0 : rRes.State = PropertyState_DIRECT_VALUE;
1314 : //For field object.
1315 0 : OUString strFieldType = GetFieldTypeNameAtIndex(nIndex);
1316 0 : if (!strFieldType.isEmpty())
1317 : {
1318 0 : nRes = aRes.getLength();
1319 0 : aRes.realloc( nRes + 1 );
1320 0 : pRes = aRes.getArray();
1321 0 : beans::PropertyValue &rResField = pRes[nRes];
1322 0 : beans::PropertyValue aFieldType;
1323 0 : rResField.Name = "FieldType";
1324 0 : rResField.Value <<= strFieldType.toAsciiLowerCase();
1325 0 : rResField.Handle = -1;
1326 0 : rResField.State = PropertyState_DIRECT_VALUE;
1327 : }
1328 : //sort property values
1329 : // build sorted index array
1330 0 : sal_Int32 nLength = aRes.getLength();
1331 0 : const beans::PropertyValue* pPairs = aRes.getConstArray();
1332 0 : boost::scoped_array<sal_Int32> pIndices(new sal_Int32[nLength]);
1333 0 : sal_Int32 i = 0;
1334 0 : for( i = 0; i < nLength; i++ )
1335 0 : pIndices[i] = i;
1336 0 : sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) );
1337 : // create sorted sequences according to index array
1338 0 : uno::Sequence<beans::PropertyValue> aNewValues( nLength );
1339 0 : beans::PropertyValue* pNewValues = aNewValues.getArray();
1340 0 : for( i = 0; i < nLength; i++ )
1341 : {
1342 0 : pNewValues[i] = pPairs[pIndices[i]];
1343 : }
1344 :
1345 0 : return aNewValues;
1346 : }
1347 4 : return aRes;
1348 : }
1349 :
1350 23 : awt::Rectangle SAL_CALL AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1351 : {
1352 23 : SolarMutexGuard aGuard;
1353 :
1354 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1355 : "AccessibleEditableTextPara::getCharacterBounds: index value overflow");
1356 :
1357 : // #108900# Have position semantics now for nIndex, as
1358 : // one-past-the-end values are legal, too.
1359 23 : CheckPosition( nIndex );
1360 :
1361 21 : SvxTextForwarder& rCacheTF = GetTextForwarder();
1362 21 : Rectangle aRect = rCacheTF.GetCharBounds(GetParagraphIndex(), nIndex);
1363 :
1364 : // convert to screen
1365 : Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
1366 21 : rCacheTF.GetMapMode(),
1367 42 : GetViewForwarder() );
1368 : // #109864# offset from parent (paragraph), but in screen
1369 : // coordinates. This makes sure the internal text offset in
1370 : // the outline view forwarder gets cancelled out here
1371 21 : awt::Rectangle aParaRect( getBounds() );
1372 21 : aScreenRect.Move( -aParaRect.X, -aParaRect.Y );
1373 :
1374 : // offset from shape/cell
1375 21 : Point aOffset = GetEEOffset();
1376 :
1377 42 : return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
1378 42 : aScreenRect.Top() + aOffset.Y(),
1379 42 : aScreenRect.GetSize().Width(),
1380 149 : aScreenRect.GetSize().Height() );
1381 : }
1382 :
1383 57 : sal_Int32 SAL_CALL AccessibleEditableTextPara::getCharacterCount() throw (uno::RuntimeException, std::exception)
1384 : {
1385 57 : SolarMutexGuard aGuard;
1386 :
1387 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1388 : "AccessibleEditableTextPara::getCharacterCount: index value overflow");
1389 :
1390 57 : return OCommonAccessibleText::getCharacterCount();
1391 : }
1392 :
1393 11 : sal_Int32 SAL_CALL AccessibleEditableTextPara::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException, std::exception)
1394 : {
1395 11 : SolarMutexGuard aGuard;
1396 :
1397 : sal_Int32 nPara;
1398 : sal_Int32 nIndex;
1399 :
1400 : // offset from surrounding cell/shape
1401 11 : Point aOffset( GetEEOffset() );
1402 11 : Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() );
1403 :
1404 : // convert to logical coordinates
1405 11 : SvxTextForwarder& rCacheTF = GetTextForwarder();
1406 11 : Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
1407 :
1408 : // re-offset to parent (paragraph)
1409 11 : Rectangle aParaRect = rCacheTF.GetParaBounds( GetParagraphIndex() );
1410 11 : aLogPoint.Move( aParaRect.Left(), aParaRect.Top() );
1411 :
1412 22 : if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) &&
1413 11 : GetParagraphIndex() == nPara )
1414 : {
1415 : // #102259# Double-check if we're _really_ on the given character
1416 : try
1417 : {
1418 11 : awt::Rectangle aRect1( getCharacterBounds(nIndex) );
1419 : Rectangle aRect2( aRect1.X, aRect1.Y,
1420 11 : aRect1.Width + aRect1.X, aRect1.Height + aRect1.Y );
1421 11 : if( aRect2.IsInside( Point( rPoint.X, rPoint.Y ) ) )
1422 10 : return nIndex;
1423 : else
1424 1 : return -1;
1425 : }
1426 0 : catch (const lang::IndexOutOfBoundsException&)
1427 : {
1428 : // #103927# Don't throw for invalid nIndex values
1429 0 : return -1;
1430 : }
1431 : }
1432 : else
1433 : {
1434 : // not within our paragraph
1435 0 : return -1;
1436 11 : }
1437 : }
1438 :
1439 0 : OUString SAL_CALL AccessibleEditableTextPara::getSelectedText() throw (uno::RuntimeException, std::exception)
1440 : {
1441 0 : SolarMutexGuard aGuard;
1442 :
1443 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1444 : "AccessibleEditableTextPara::getSelectedText: index value overflow");
1445 :
1446 0 : if( !HaveEditView() )
1447 0 : return OUString();
1448 :
1449 0 : return OCommonAccessibleText::getSelectedText();
1450 : }
1451 :
1452 0 : sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart() throw (uno::RuntimeException, std::exception)
1453 : {
1454 0 : SolarMutexGuard aGuard;
1455 :
1456 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1457 : "AccessibleEditableTextPara::getSelectionStart: index value overflow");
1458 :
1459 0 : if( !HaveEditView() )
1460 0 : return -1;
1461 :
1462 0 : return OCommonAccessibleText::getSelectionStart();
1463 : }
1464 :
1465 0 : sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd() throw (uno::RuntimeException, std::exception)
1466 : {
1467 0 : SolarMutexGuard aGuard;
1468 :
1469 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1470 : "AccessibleEditableTextPara::getSelectionEnd: index value overflow");
1471 :
1472 0 : if( !HaveEditView() )
1473 0 : return -1;
1474 :
1475 0 : return OCommonAccessibleText::getSelectionEnd();
1476 : }
1477 :
1478 3 : sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1479 : {
1480 3 : SolarMutexGuard aGuard;
1481 :
1482 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1483 : "AccessibleEditableTextPara::setSelection: paragraph index value overflow");
1484 :
1485 3 : CheckRange(nStartIndex, nEndIndex);
1486 :
1487 : try
1488 : {
1489 1 : SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( true );
1490 0 : return rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
1491 : }
1492 2 : catch (const uno::RuntimeException&)
1493 : {
1494 1 : return sal_False;
1495 3 : }
1496 : }
1497 :
1498 2 : OUString SAL_CALL AccessibleEditableTextPara::getText() throw (uno::RuntimeException, std::exception)
1499 : {
1500 2 : SolarMutexGuard aGuard;
1501 :
1502 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1503 : "AccessibleEditableTextPara::getText: paragraph index value overflow");
1504 :
1505 2 : return OCommonAccessibleText::getText();
1506 : }
1507 :
1508 7 : OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
1509 : {
1510 7 : SolarMutexGuard aGuard;
1511 :
1512 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1513 : "AccessibleEditableTextPara::getTextRange: paragraph index value overflow");
1514 :
1515 7 : return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex);
1516 : }
1517 :
1518 0 : void AccessibleEditableTextPara::_correctValues( const sal_Int32 /* nIndex */,
1519 : uno::Sequence< PropertyValue >& rValues)
1520 : {
1521 0 : SvxTextForwarder& rCacheTF = GetTextForwarder();
1522 0 : sal_Int32 nRes = rValues.getLength();
1523 0 : beans::PropertyValue *pRes = rValues.getArray();
1524 0 : for (sal_Int32 i = 0; i < nRes; ++i)
1525 : {
1526 0 : beans::PropertyValue &rRes = pRes[i];
1527 : // Char color
1528 0 : if (rRes.Name == "CharColor")
1529 : {
1530 0 : uno::Any &anyChar = rRes.Value;
1531 0 : sal_uInt32 crChar = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved));
1532 0 : if (COL_AUTO == crChar )
1533 : {
1534 0 : uno::Reference< ::com::sun::star::accessibility::XAccessibleComponent > xComponent;
1535 0 : if (mxParent.is())
1536 : {
1537 0 : xComponent.set(mxParent,uno::UNO_QUERY);
1538 : }
1539 : else
1540 : {
1541 0 : xComponent.set(m_xAccInfo,uno::UNO_QUERY);
1542 : }
1543 0 : if (xComponent.is())
1544 : {
1545 0 : uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY);
1546 0 : if (xContext->getAccessibleRole() == AccessibleRole::SHAPE
1547 0 : || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL)
1548 : {
1549 0 : anyChar <<= COL_BLACK;
1550 : }
1551 : else
1552 : {
1553 0 : Color cr(xComponent->getBackground());
1554 0 : crChar = cr.IsDark() ? COL_WHITE : COL_BLACK;
1555 0 : anyChar <<= crChar;
1556 0 : }
1557 0 : }
1558 : }
1559 0 : continue;
1560 : }
1561 : // Underline
1562 0 : if (rRes.Name == "CharUnderline")
1563 : {
1564 0 : continue;
1565 : }
1566 : // Underline color && Mis-spell
1567 0 : if (rRes.Name == "CharUnderlineColor")
1568 : {
1569 0 : uno::Any &anyCharUnderLine = rRes.Value;
1570 0 : sal_uInt32 crCharUnderLine = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>( anyCharUnderLine.pReserved));
1571 0 : if (COL_AUTO == crCharUnderLine )
1572 : {
1573 0 : uno::Reference< ::com::sun::star::accessibility::XAccessibleComponent > xComponent;
1574 0 : if (mxParent.is())
1575 : {
1576 0 : xComponent.set(mxParent,uno::UNO_QUERY);
1577 : }
1578 : else
1579 : {
1580 0 : xComponent.set(m_xAccInfo,uno::UNO_QUERY);
1581 : }
1582 0 : if (xComponent.is())
1583 : {
1584 0 : uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY);
1585 0 : if (xContext->getAccessibleRole() == AccessibleRole::SHAPE
1586 0 : || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL)
1587 : {
1588 0 : anyCharUnderLine <<= COL_BLACK;
1589 : }
1590 : else
1591 : {
1592 0 : Color cr(xComponent->getBackground());
1593 0 : crCharUnderLine = cr.IsDark() ? COL_WHITE : COL_BLACK;
1594 0 : anyCharUnderLine <<= crCharUnderLine;
1595 0 : }
1596 0 : }
1597 : }
1598 0 : continue;
1599 : }
1600 : // NumberingLevel
1601 0 : if (rRes.Name == "NumberingLevel")
1602 : {
1603 0 : const SvxNumBulletItem& rNumBullet = static_cast<const SvxNumBulletItem&>(rCacheTF.GetParaAttribs(GetParagraphIndex()).Get(EE_PARA_NUMBULLET));
1604 0 : if(rNumBullet.GetNumRule()->GetLevelCount()==0)
1605 : {
1606 0 : rRes.Value <<= (sal_Int16)-1;
1607 0 : rRes.Handle = -1;
1608 0 : rRes.State = PropertyState_DIRECT_VALUE;
1609 : }
1610 : else
1611 : {
1612 : // SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
1613 : // ImplGetSvxCharAndParaPropertiesMap() );
1614 : // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap
1615 0 : SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() );
1616 :
1617 0 : aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) );
1618 0 : rRes.Value = aPropSet._getPropertyValue( rRes.Name, mnParagraphIndex );
1619 0 : rRes.State = aPropSet._getPropertyState( rRes.Name, mnParagraphIndex );
1620 0 : rRes.Handle = -1;
1621 : }
1622 0 : continue;
1623 : }
1624 : // NumberingRules
1625 0 : if (rRes.Name == "NumberingRules")
1626 : {
1627 0 : SfxItemSet aAttribs = rCacheTF.GetParaAttribs(GetParagraphIndex());
1628 0 : bool bVis = static_cast<const SfxUInt16Item&>(aAttribs.Get( EE_PARA_BULLETSTATE )).GetValue() != 0;
1629 0 : if(bVis)
1630 : {
1631 0 : rRes.Value <<= (sal_Int16)-1;
1632 0 : rRes.Handle = -1;
1633 0 : rRes.State = PropertyState_DIRECT_VALUE;
1634 : }
1635 : else
1636 : {
1637 : // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap
1638 0 : SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() );
1639 0 : aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) );
1640 0 : rRes.Value = aPropSet._getPropertyValue( rRes.Name, mnParagraphIndex );
1641 0 : rRes.State = aPropSet._getPropertyState( rRes.Name, mnParagraphIndex );
1642 0 : rRes.Handle = -1;
1643 : }
1644 0 : continue;
1645 : }
1646 : }
1647 0 : }
1648 5 : sal_Int32 AccessibleEditableTextPara::SkipField(sal_Int32 nIndex, bool bForward)
1649 : {
1650 5 : sal_Int32 nParaIndex = GetParagraphIndex();
1651 5 : SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();
1652 5 : sal_Int32 nAllFieldLen = 0;
1653 5 : sal_Int32 nField = rCacheTF.GetFieldCount(nParaIndex), nFoundFieldIndex = -1;
1654 5 : EFieldInfo ree;
1655 5 : sal_Int32 reeBegin=0, reeEnd=0;
1656 5 : for (sal_Int32 j = 0; j < nField; j++)
1657 : {
1658 0 : ree = rCacheTF.GetFieldInfo(nParaIndex, j);
1659 0 : reeBegin = ree.aPosition.nIndex + nAllFieldLen;
1660 0 : reeEnd = reeBegin + ree.aCurrentText.getLength();
1661 0 : nAllFieldLen += (ree.aCurrentText.getLength() - 1);
1662 0 : if( reeBegin > nIndex )
1663 : {
1664 0 : break;
1665 : }
1666 0 : if (!ree.pFieldItem)
1667 0 : continue;
1668 0 : if (nIndex >= reeBegin && nIndex < reeEnd)
1669 : {
1670 0 : if (ree.pFieldItem->GetField()->GetClassId() != text::textfield::Type::URL)
1671 : {
1672 0 : nFoundFieldIndex = j;
1673 0 : break;
1674 : }
1675 : }
1676 : }
1677 5 : if( nFoundFieldIndex >= 0 )
1678 : {
1679 0 : if( bForward )
1680 0 : return reeEnd - 1;
1681 : else
1682 0 : return reeBegin;
1683 : }
1684 5 : return nIndex;
1685 : }
1686 11 : bool AccessibleEditableTextPara::ExtendByField( ::com::sun::star::accessibility::TextSegment& Segment )
1687 : {
1688 11 : sal_Int32 nParaIndex = GetParagraphIndex();
1689 11 : SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();
1690 11 : sal_Int32 nAllFieldLen = 0;
1691 11 : sal_Int32 nField = rCacheTF.GetFieldCount(nParaIndex), nFoundFieldIndex = -1;
1692 11 : EFieldInfo ree;
1693 11 : sal_Int32 reeBegin=0, reeEnd=0;
1694 11 : for (sal_Int32 j = 0; j < nField; j++)
1695 : {
1696 0 : ree = rCacheTF.GetFieldInfo(nParaIndex, j);
1697 0 : reeBegin = ree.aPosition.nIndex + nAllFieldLen;
1698 0 : reeEnd = reeBegin + ree.aCurrentText.getLength();
1699 0 : nAllFieldLen += (ree.aCurrentText.getLength() - 1);
1700 0 : if( reeBegin > Segment.SegmentEnd )
1701 : {
1702 0 : break;
1703 : }
1704 0 : if (!ree.pFieldItem)
1705 0 : continue;
1706 0 : if( (Segment.SegmentEnd > reeBegin && Segment.SegmentEnd <= reeEnd) ||
1707 0 : (Segment.SegmentStart >= reeBegin && Segment.SegmentStart < reeEnd) )
1708 : {
1709 0 : if(ree.pFieldItem->GetField()->GetClassId() != text::textfield::Type::URL)
1710 : {
1711 0 : nFoundFieldIndex = j;
1712 0 : break;
1713 : }
1714 : }
1715 : }
1716 11 : bool bExtend = false;
1717 11 : if( nFoundFieldIndex >= 0 )
1718 : {
1719 0 : if( Segment.SegmentEnd < reeEnd )
1720 : {
1721 0 : Segment.SegmentEnd = reeEnd;
1722 0 : bExtend = true;
1723 : }
1724 0 : if( Segment.SegmentStart > reeBegin )
1725 : {
1726 0 : Segment.SegmentStart = reeBegin;
1727 0 : bExtend = true;
1728 : }
1729 0 : if( bExtend )
1730 : {
1731 : //If there is a bullet before the field, should add the bullet length into the segment.
1732 0 : EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(nParaIndex);
1733 0 : sal_Int32 nBulletLen = aBulletInfo.aText.getLength();
1734 0 : if (nBulletLen > 0)
1735 : {
1736 0 : Segment.SegmentEnd += nBulletLen;
1737 0 : if (nFoundFieldIndex > 0)
1738 0 : Segment.SegmentStart += nBulletLen;
1739 0 : Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd);
1740 : //After get the correct field name, should restore the offset value which don't contain the bullet.
1741 0 : Segment.SegmentEnd -= nBulletLen;
1742 0 : if (nFoundFieldIndex > 0)
1743 0 : Segment.SegmentStart -= nBulletLen;
1744 : }
1745 : else
1746 0 : Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd);
1747 : }
1748 : }
1749 11 : return bExtend;
1750 : }
1751 :
1752 17 : ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
1753 : {
1754 17 : SolarMutexGuard aGuard;
1755 :
1756 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1757 : "AccessibleEditableTextPara::getTextAtIndex: paragraph index value overflow");
1758 :
1759 17 : ::com::sun::star::accessibility::TextSegment aResult;
1760 17 : aResult.SegmentStart = -1;
1761 17 : aResult.SegmentEnd = -1;
1762 :
1763 17 : switch( aTextType )
1764 : {
1765 : case AccessibleTextType::CHARACTER:
1766 : case AccessibleTextType::WORD:
1767 : {
1768 6 : aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
1769 6 : ExtendByField( aResult );
1770 6 : break;
1771 : }
1772 : // Not yet handled by OCommonAccessibleText. Missing
1773 : // implGetAttributeRunBoundary() method there
1774 : case AccessibleTextType::ATTRIBUTE_RUN:
1775 : {
1776 0 : const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( GetParagraphIndex() );
1777 :
1778 0 : if( nIndex == nTextLen )
1779 : {
1780 : // #i17014# Special-casing one-behind-the-end character
1781 0 : aResult.SegmentStart = aResult.SegmentEnd = nTextLen;
1782 : }
1783 : else
1784 : {
1785 : sal_Int32 nStartIndex, nEndIndex;
1786 : //For the bullet paragraph, the bullet string is ingnored for IAText::attributes() function.
1787 0 : SvxTextForwarder& rCacheTF = GetTextForwarder();
1788 : // MT IA2: Not used? sal_Int32 nBulletLen = 0;
1789 0 : EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(GetParagraphIndex());
1790 0 : if (aBulletInfo.bVisible)
1791 0 : nIndex += aBulletInfo.aText.getLength();
1792 0 : if (nIndex != 0 && nIndex >= getCharacterCount())
1793 0 : nIndex = getCharacterCount()-1;
1794 0 : CheckPosition(nIndex);
1795 0 : if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
1796 : {
1797 0 : aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1798 0 : if (aBulletInfo.bVisible)
1799 : {
1800 0 : nStartIndex -= aBulletInfo.aText.getLength();
1801 0 : nEndIndex -= aBulletInfo.aText.getLength();
1802 : }
1803 0 : aResult.SegmentStart = nStartIndex;
1804 0 : aResult.SegmentEnd = nEndIndex;
1805 0 : }
1806 : }
1807 0 : break;
1808 : }
1809 : case AccessibleTextType::LINE:
1810 : {
1811 8 : SvxTextForwarder& rCacheTF = GetTextForwarder();
1812 8 : sal_Int32 nParaIndex = GetParagraphIndex();
1813 8 : CheckPosition(nIndex);
1814 8 : if (nIndex != 0 && nIndex == getCharacterCount())
1815 0 : --nIndex;
1816 8 : sal_Int32 nLine, nLineCount=rCacheTF.GetLineCount( nParaIndex );
1817 : sal_Int32 nCurIndex;
1818 : //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
1819 : //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
1820 : //by the IAText::attributes(). So here must do special support for bullet line.
1821 8 : sal_Int32 nBulletLen = 0;
1822 8 : for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
1823 : {
1824 8 : if (nLine == 0)
1825 : {
1826 8 : EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( nParaIndex );
1827 8 : if (aBulletInfo.bVisible)
1828 : {
1829 : //in bullet or numbering;
1830 0 : nBulletLen = aBulletInfo.aText.getLength();
1831 8 : }
1832 : }
1833 8 : sal_Int32 nLineLen = rCacheTF.GetLineLen(nParaIndex, nLine);
1834 8 : if (nLine == 0)
1835 8 : nCurIndex += nLineLen - nBulletLen;
1836 : else
1837 0 : nCurIndex += nLineLen;
1838 8 : if( nCurIndex > nIndex )
1839 : {
1840 8 : if (nLine ==0)
1841 : {
1842 8 : aResult.SegmentStart = 0;
1843 8 : aResult.SegmentEnd = nCurIndex;
1844 8 : aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen);
1845 8 : break;
1846 : }
1847 : else
1848 : {
1849 0 : aResult.SegmentStart = nCurIndex - nLineLen;
1850 0 : aResult.SegmentEnd = nCurIndex;
1851 : //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd );
1852 0 : aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen);
1853 0 : break;
1854 : }
1855 : }
1856 : }
1857 8 : break;
1858 : }
1859 : default:
1860 3 : aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
1861 1 : break;
1862 : } /* end of switch( aTextType ) */
1863 :
1864 17 : return aResult;
1865 : }
1866 :
1867 6 : ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
1868 : {
1869 6 : SolarMutexGuard aGuard;
1870 :
1871 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1872 : "AccessibleEditableTextPara::getTextBeforeIndex: paragraph index value overflow");
1873 :
1874 6 : ::com::sun::star::accessibility::TextSegment aResult;
1875 6 : aResult.SegmentStart = -1;
1876 6 : aResult.SegmentEnd = -1;
1877 6 : i18n::Boundary aBoundary;
1878 6 : switch( aTextType )
1879 : {
1880 : // Not yet handled by OCommonAccessibleText. Missing
1881 : // implGetAttributeRunBoundary() method there
1882 : case AccessibleTextType::ATTRIBUTE_RUN:
1883 : {
1884 0 : const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( GetParagraphIndex() );
1885 : sal_Int32 nStartIndex, nEndIndex;
1886 :
1887 0 : if( nIndex == nTextLen )
1888 : {
1889 : // #i17014# Special-casing one-behind-the-end character
1890 0 : if( nIndex > 0 &&
1891 0 : GetAttributeRun(nStartIndex, nEndIndex, nIndex-1) )
1892 : {
1893 0 : aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1894 0 : aResult.SegmentStart = nStartIndex;
1895 0 : aResult.SegmentEnd = nEndIndex;
1896 : }
1897 : }
1898 : else
1899 : {
1900 0 : if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
1901 : {
1902 : // already at the left border? If not, query
1903 : // one index further left
1904 0 : if( nStartIndex > 0 &&
1905 0 : GetAttributeRun(nStartIndex, nEndIndex, nStartIndex-1) )
1906 : {
1907 0 : aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1908 0 : aResult.SegmentStart = nStartIndex;
1909 0 : aResult.SegmentEnd = nEndIndex;
1910 : }
1911 : }
1912 : }
1913 0 : break;
1914 : }
1915 : case AccessibleTextType::LINE:
1916 : {
1917 0 : SvxTextForwarder& rCacheTF = GetTextForwarder();
1918 0 : sal_Int32 nParaIndex = GetParagraphIndex();
1919 :
1920 0 : CheckPosition(nIndex);
1921 :
1922 0 : sal_Int32 nLine, nLineCount=rCacheTF.GetLineCount( nParaIndex );
1923 : //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
1924 : //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
1925 : //by the IAText::attributes(). So here must do special support for bullet line.
1926 0 : sal_Int32 nCurIndex=0, nLastIndex=0, nCurLineLen=0;
1927 0 : sal_Int32 nLastLineLen = 0, nBulletLen = 0;;
1928 : // get the line before the line the index points into
1929 0 : for( nLine=0, nCurIndex=0, nLastIndex=0; nLine<nLineCount; ++nLine )
1930 : {
1931 0 : nLastIndex = nCurIndex;
1932 0 : if (nLine == 0)
1933 : {
1934 0 : EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(nParaIndex);
1935 0 : if (aBulletInfo.bVisible)
1936 : {
1937 : //in bullet or numbering;
1938 0 : nBulletLen = aBulletInfo.aText.getLength();
1939 0 : }
1940 : }
1941 0 : if (nLine == 1)
1942 0 : nLastLineLen = nCurLineLen - nBulletLen;
1943 : else
1944 0 : nLastLineLen = nCurLineLen;
1945 0 : nCurLineLen = rCacheTF.GetLineLen( nParaIndex, nLine);
1946 : //nCurIndex += nCurLineLen;
1947 0 : if (nLine == 0)
1948 0 : nCurIndex += nCurLineLen - nBulletLen;
1949 : else
1950 0 : nCurIndex += nCurLineLen;
1951 :
1952 : //if( nCurIndex > nIndex &&
1953 : //nLastIndex > nCurLineLen )
1954 0 : if (nCurIndex > nIndex)
1955 : {
1956 0 : if (nLine == 0)
1957 : {
1958 0 : break;
1959 : }
1960 0 : else if (nLine == 1)
1961 : {
1962 0 : aResult.SegmentStart = 0;
1963 0 : aResult.SegmentEnd = nLastIndex;
1964 0 : aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen);
1965 0 : break;
1966 : }
1967 : else
1968 : {
1969 : //aResult.SegmentStart = nLastIndex - nCurLineLen;
1970 0 : aResult.SegmentStart = nLastIndex - nLastLineLen;
1971 0 : aResult.SegmentEnd = nLastIndex;
1972 0 : aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen);
1973 0 : break;
1974 : }
1975 : }
1976 : }
1977 :
1978 0 : break;
1979 : }
1980 : case AccessibleTextType::WORD:
1981 : {
1982 1 : nIndex = SkipField( nIndex, false);
1983 1 : OUString sText( implGetText() );
1984 1 : sal_Int32 nLength = sText.getLength();
1985 :
1986 : // get word at index
1987 1 : implGetWordBoundary( aBoundary, nIndex );
1988 :
1989 :
1990 : //sal_Int32 curWordStart = aBoundary.startPos;
1991 : //sal_Int32 preWordStart = curWordStart;
1992 : sal_Int32 curWordStart , preWordStart;
1993 1 : if( aBoundary.startPos == -1 || aBoundary.startPos > nIndex)
1994 0 : curWordStart = preWordStart = nIndex;
1995 : else
1996 1 : curWordStart = preWordStart = aBoundary.startPos;
1997 :
1998 : // get previous word
1999 :
2000 1 : bool bWord = false;
2001 :
2002 : //while ( preWordStart > 0 && aBoundary.startPos == curWordStart)
2003 3 : while ( (preWordStart >= 0 && !bWord ) || ( aBoundary.endPos > curWordStart ) )
2004 : {
2005 1 : preWordStart--;
2006 1 : bWord = implGetWordBoundary( aBoundary, preWordStart );
2007 : }
2008 1 : if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
2009 : {
2010 1 : aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
2011 1 : aResult.SegmentStart = aBoundary.startPos;
2012 1 : aResult.SegmentEnd = aBoundary.endPos;
2013 1 : ExtendByField( aResult );
2014 1 : }
2015 : }
2016 1 : break;
2017 : case AccessibleTextType::CHARACTER:
2018 : {
2019 2 : nIndex = SkipField( nIndex, false);
2020 2 : aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
2021 2 : ExtendByField( aResult );
2022 2 : break;
2023 : }
2024 : default:
2025 3 : aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
2026 1 : break;
2027 : } /* end of switch( aTextType ) */
2028 :
2029 6 : return aResult;
2030 : }
2031 :
2032 6 : ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
2033 : {
2034 6 : SolarMutexGuard aGuard;
2035 :
2036 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2037 : "AccessibleEditableTextPara::getTextBehindIndex: paragraph index value overflow");
2038 :
2039 6 : ::com::sun::star::accessibility::TextSegment aResult;
2040 6 : aResult.SegmentStart = -1;
2041 6 : aResult.SegmentEnd = -1;
2042 6 : i18n::Boundary aBoundary;
2043 6 : switch( aTextType )
2044 : {
2045 : case AccessibleTextType::ATTRIBUTE_RUN:
2046 : {
2047 : sal_Int32 nStartIndex, nEndIndex;
2048 :
2049 0 : if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
2050 : {
2051 : // already at the right border?
2052 0 : if( nEndIndex < GetTextLen() )
2053 : {
2054 0 : if( GetAttributeRun(nStartIndex, nEndIndex, nEndIndex) )
2055 : {
2056 0 : aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
2057 0 : aResult.SegmentStart = nStartIndex;
2058 0 : aResult.SegmentEnd = nEndIndex;
2059 : }
2060 : }
2061 : }
2062 0 : break;
2063 : }
2064 :
2065 : case AccessibleTextType::LINE:
2066 : {
2067 0 : SvxTextForwarder& rCacheTF = GetTextForwarder();
2068 0 : sal_Int32 nParaIndex = GetParagraphIndex();
2069 :
2070 0 : CheckPosition(nIndex);
2071 :
2072 0 : sal_Int32 nLine, nLineCount = rCacheTF.GetLineCount( nParaIndex );
2073 : sal_Int32 nCurIndex;
2074 : //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
2075 : //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
2076 : //by the IAText::attributes(). So here must do special support for bullet line.
2077 0 : sal_Int32 nBulletLen = 0;
2078 : // get the line after the line the index points into
2079 0 : for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
2080 : {
2081 0 : if (nLine == 0)
2082 : {
2083 0 : EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(nParaIndex);
2084 0 : if (aBulletInfo.bVisible)
2085 : {
2086 : //in bullet or numbering;
2087 0 : nBulletLen = aBulletInfo.aText.getLength();
2088 0 : }
2089 : }
2090 0 : sal_Int32 nLineLen = rCacheTF.GetLineLen( nParaIndex, nLine);
2091 :
2092 0 : if (nLine == 0)
2093 0 : nCurIndex += nLineLen - nBulletLen;
2094 : else
2095 0 : nCurIndex += nLineLen;
2096 :
2097 0 : if( nCurIndex > nIndex &&
2098 0 : nLine < nLineCount-1 )
2099 : {
2100 0 : aResult.SegmentStart = nCurIndex;
2101 0 : aResult.SegmentEnd = nCurIndex + rCacheTF.GetLineLen( nParaIndex, nLine+1);
2102 0 : aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen);
2103 0 : break;
2104 : }
2105 : }
2106 :
2107 0 : break;
2108 : }
2109 : case AccessibleTextType::WORD:
2110 : {
2111 0 : nIndex = SkipField( nIndex, true);
2112 0 : OUString sText( implGetText() );
2113 0 : sal_Int32 nLength = sText.getLength();
2114 :
2115 : // get word at index
2116 0 : bool bWord = implGetWordBoundary( aBoundary, nIndex );
2117 :
2118 : // real current world
2119 0 : sal_Int32 nextWord = nIndex;
2120 : //if( nIndex >= aBoundary.startPos && nIndex <= aBoundary.endPos )
2121 0 : if( nIndex <= aBoundary.endPos )
2122 : {
2123 0 : nextWord = aBoundary.endPos;
2124 0 : if( sText.getStr()[nextWord] == sal_Unicode(' ') ) nextWord++;
2125 0 : bWord = implGetWordBoundary( aBoundary, nextWord );
2126 : }
2127 :
2128 0 : if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
2129 : {
2130 0 : aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
2131 0 : aResult.SegmentStart = aBoundary.startPos;
2132 0 : aResult.SegmentEnd = aBoundary.endPos;
2133 :
2134 : // If the end position of aBoundary is inside a field, extend the result to the end of the field
2135 :
2136 0 : ExtendByField( aResult );
2137 0 : }
2138 : }
2139 0 : break;
2140 :
2141 : case AccessibleTextType::CHARACTER:
2142 : {
2143 2 : nIndex = SkipField( nIndex, true);
2144 2 : aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
2145 2 : ExtendByField( aResult );
2146 2 : break;
2147 : }
2148 : default:
2149 4 : aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
2150 2 : break;
2151 : } /* end of switch( aTextType ) */
2152 :
2153 6 : return aResult;
2154 : }
2155 :
2156 0 : sal_Bool SAL_CALL AccessibleEditableTextPara::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
2157 : {
2158 0 : SolarMutexGuard aGuard;
2159 :
2160 : try
2161 : {
2162 0 : SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( true );
2163 : #if OSL_DEBUG_LEVEL > 0
2164 : SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2165 : (void)rCacheTF;
2166 : #else
2167 0 : GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2168 : #endif
2169 :
2170 : bool aRetVal;
2171 :
2172 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2173 : "AccessibleEditableTextPara::copyText: index value overflow");
2174 :
2175 0 : CheckRange(nStartIndex, nEndIndex);
2176 :
2177 : //Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2178 0 : sal_Int32 nBulletLen = 0;
2179 0 : EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2180 0 : if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2181 0 : nBulletLen = aBulletInfo.aText.getLength();
2182 : // save current selection
2183 0 : ESelection aOldSelection;
2184 :
2185 0 : rCacheVF.GetSelection( aOldSelection );
2186 : //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2187 0 : rCacheVF.SetSelection( MakeSelection(nStartIndex + nBulletLen, nEndIndex + nBulletLen) );
2188 0 : aRetVal = rCacheVF.Copy();
2189 0 : rCacheVF.SetSelection( aOldSelection ); // restore
2190 :
2191 0 : return aRetVal;
2192 : }
2193 0 : catch (const uno::RuntimeException&)
2194 : {
2195 0 : return sal_False;
2196 0 : }
2197 : }
2198 :
2199 : // XAccessibleEditableText
2200 0 : sal_Bool SAL_CALL AccessibleEditableTextPara::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
2201 : {
2202 :
2203 0 : SolarMutexGuard aGuard;
2204 :
2205 : try
2206 : {
2207 0 : SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( true );
2208 0 : SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2209 :
2210 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2211 : "AccessibleEditableTextPara::cutText: index value overflow");
2212 :
2213 0 : CheckRange(nStartIndex, nEndIndex);
2214 :
2215 : // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2216 0 : sal_Int32 nBulletLen = 0;
2217 0 : EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2218 0 : if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2219 0 : nBulletLen = aBulletInfo.aText.getLength();
2220 0 : ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen);
2221 : //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2222 0 : if( !rCacheTF.IsEditable( aSelection ) )
2223 0 : return sal_False; // non-editable area selected
2224 :
2225 : // don't save selection, might become invalid after cut!
2226 : //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2227 0 : rCacheVF.SetSelection( aSelection );
2228 :
2229 0 : return rCacheVF.Cut();
2230 : }
2231 0 : catch (const uno::RuntimeException&)
2232 : {
2233 0 : return sal_False;
2234 0 : }
2235 : }
2236 :
2237 0 : sal_Bool SAL_CALL AccessibleEditableTextPara::pasteText( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
2238 : {
2239 :
2240 0 : SolarMutexGuard aGuard;
2241 :
2242 : try
2243 : {
2244 0 : SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( true );
2245 0 : SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2246 :
2247 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2248 : "AccessibleEditableTextPara::pasteText: index value overflow");
2249 :
2250 0 : CheckPosition(nIndex);
2251 :
2252 : // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2253 0 : sal_Int32 nBulletLen = 0;
2254 0 : EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2255 0 : if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2256 0 : nBulletLen = aBulletInfo.aText.getLength();
2257 0 : if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) )
2258 0 : return sal_False; // non-editable area selected
2259 :
2260 : // #104400# set empty selection (=> cursor) to given index
2261 : //rCacheVF.SetSelection( MakeCursor(nIndex) );
2262 0 : rCacheVF.SetSelection( MakeCursor(nIndex + nBulletLen) );
2263 :
2264 0 : return rCacheVF.Paste();
2265 : }
2266 0 : catch (const uno::RuntimeException&)
2267 : {
2268 0 : return sal_False;
2269 0 : }
2270 : }
2271 :
2272 0 : sal_Bool SAL_CALL AccessibleEditableTextPara::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
2273 : {
2274 :
2275 0 : SolarMutexGuard aGuard;
2276 :
2277 : try
2278 : {
2279 : // #102710# Request edit view when doing changes
2280 : // AccessibleEmptyEditSource relies on this behaviour
2281 0 : GetEditViewForwarder( true );
2282 0 : SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2283 :
2284 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2285 : "AccessibleEditableTextPara::deleteText: index value overflow");
2286 :
2287 0 : CheckRange(nStartIndex, nEndIndex);
2288 :
2289 : // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2290 0 : sal_Int32 nBulletLen = 0;
2291 0 : EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2292 0 : if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2293 0 : nBulletLen = aBulletInfo.aText.getLength();
2294 0 : ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen);
2295 :
2296 : //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2297 0 : if( !rCacheTF.IsEditable( aSelection ) )
2298 0 : return sal_False; // non-editable area selected
2299 :
2300 : //sal_Bool bRet = rCacheTF.Delete( MakeSelection(nStartIndex, nEndIndex) );
2301 0 : bool bRet = rCacheTF.Delete( aSelection );
2302 :
2303 0 : GetEditSource().UpdateData();
2304 :
2305 0 : return bRet;
2306 : }
2307 0 : catch (const uno::RuntimeException&)
2308 : {
2309 0 : return sal_False;
2310 0 : }
2311 : }
2312 :
2313 0 : sal_Bool SAL_CALL AccessibleEditableTextPara::insertText( const OUString& sText, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
2314 : {
2315 :
2316 0 : SolarMutexGuard aGuard;
2317 :
2318 : try
2319 : {
2320 : // #102710# Request edit view when doing changes
2321 : // AccessibleEmptyEditSource relies on this behaviour
2322 0 : GetEditViewForwarder( true );
2323 0 : SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2324 :
2325 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2326 : "AccessibleEditableTextPara::insertText: index value overflow");
2327 :
2328 0 : CheckPosition(nIndex);
2329 :
2330 : // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2331 0 : sal_Int32 nBulletLen = 0;
2332 0 : EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2333 0 : if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2334 0 : nBulletLen = aBulletInfo.aText.getLength();
2335 :
2336 0 : if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) )
2337 0 : return sal_False; // non-editable area selected
2338 :
2339 : // #104400# insert given text at empty selection (=> cursor)
2340 0 : bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex + nBulletLen) );
2341 :
2342 0 : rCacheTF.QuickFormatDoc();
2343 0 : GetEditSource().UpdateData();
2344 :
2345 0 : return bRet;
2346 : }
2347 0 : catch (const uno::RuntimeException&)
2348 : {
2349 0 : return sal_False;
2350 0 : }
2351 : }
2352 :
2353 0 : sal_Bool SAL_CALL AccessibleEditableTextPara::replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const OUString& sReplacement ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
2354 : {
2355 :
2356 0 : SolarMutexGuard aGuard;
2357 :
2358 : try
2359 : {
2360 : // #102710# Request edit view when doing changes
2361 : // AccessibleEmptyEditSource relies on this behaviour
2362 0 : GetEditViewForwarder( true );
2363 0 : SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2364 :
2365 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2366 : "AccessibleEditableTextPara::replaceText: index value overflow");
2367 :
2368 0 : CheckRange(nStartIndex, nEndIndex);
2369 :
2370 : // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2371 0 : sal_Int32 nBulletLen = 0;
2372 0 : EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2373 0 : if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2374 0 : nBulletLen = aBulletInfo.aText.getLength();
2375 0 : ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen);
2376 :
2377 : //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2378 0 : if( !rCacheTF.IsEditable( aSelection ) )
2379 0 : return sal_False; // non-editable area selected
2380 :
2381 : // insert given text into given range => replace
2382 : //sal_Bool bRet = rCacheTF.InsertText( sReplacement, MakeSelection(nStartIndex, nEndIndex) );
2383 0 : bool bRet = rCacheTF.InsertText( sReplacement, aSelection );
2384 :
2385 0 : rCacheTF.QuickFormatDoc();
2386 0 : GetEditSource().UpdateData();
2387 :
2388 0 : return bRet;
2389 : }
2390 0 : catch (const uno::RuntimeException&)
2391 : {
2392 0 : return sal_False;
2393 0 : }
2394 : }
2395 :
2396 0 : sal_Bool SAL_CALL AccessibleEditableTextPara::setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const uno::Sequence< beans::PropertyValue >& aAttributeSet ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
2397 : {
2398 :
2399 0 : SolarMutexGuard aGuard;
2400 :
2401 : try
2402 : {
2403 : // #102710# Request edit view when doing changes
2404 : // AccessibleEmptyEditSource relies on this behaviour
2405 0 : GetEditViewForwarder( true );
2406 0 : SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2407 0 : sal_Int32 nPara = GetParagraphIndex();
2408 :
2409 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2410 : "AccessibleEditableTextPara::setAttributes: index value overflow");
2411 :
2412 0 : CheckRange(nStartIndex, nEndIndex);
2413 :
2414 0 : if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2415 0 : return sal_False; // non-editable area selected
2416 :
2417 : // do the indices span the whole paragraph? Then use the outliner map
2418 : // TODO: hold it as a member?
2419 0 : SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
2420 0 : 0 == nStartIndex &&
2421 0 : rCacheTF.GetTextLen(nPara) == nEndIndex ?
2422 : ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() :
2423 0 : ImplGetSvxTextPortionSvxPropertySet() );
2424 :
2425 0 : aPropSet.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2426 :
2427 : // convert from PropertyValue to Any
2428 0 : sal_Int32 i, nLength( aAttributeSet.getLength() );
2429 0 : const beans::PropertyValue* pPropArray = aAttributeSet.getConstArray();
2430 0 : for(i=0; i<nLength; ++i)
2431 : {
2432 : try
2433 : {
2434 0 : aPropSet.setPropertyValue(pPropArray->Name, pPropArray->Value);
2435 : }
2436 0 : catch (const uno::Exception&)
2437 : {
2438 : OSL_FAIL("AccessibleEditableTextPara::setAttributes exception in setPropertyValue");
2439 : }
2440 :
2441 0 : ++pPropArray;
2442 : }
2443 :
2444 0 : rCacheTF.QuickFormatDoc();
2445 0 : GetEditSource().UpdateData();
2446 :
2447 0 : return sal_True;
2448 : }
2449 0 : catch (const uno::RuntimeException&)
2450 : {
2451 0 : return sal_False;
2452 0 : }
2453 : }
2454 :
2455 0 : sal_Bool SAL_CALL AccessibleEditableTextPara::setText( const OUString& sText ) throw (uno::RuntimeException, std::exception)
2456 : {
2457 :
2458 0 : SolarMutexGuard aGuard;
2459 :
2460 0 : return replaceText(0, getCharacterCount(), sText);
2461 : }
2462 :
2463 : // XAccessibleTextAttributes
2464 1 : uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getDefaultAttributes(
2465 : const uno::Sequence< OUString >& rRequestedAttributes )
2466 : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
2467 : {
2468 1 : SolarMutexGuard aGuard;
2469 :
2470 : #if OSL_DEBUG_LEVEL > 0
2471 : SvxAccessibleTextAdapter& rCacheTF =
2472 : #endif
2473 1 : GetTextForwarder();
2474 :
2475 : #if OSL_DEBUG_LEVEL > 0
2476 : (void)rCacheTF;
2477 : #endif
2478 :
2479 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2480 : "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
2481 :
2482 : // get XPropertySetInfo for paragraph attributes and
2483 : // character attributes that span all the paragraphs text.
2484 1 : SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
2485 3 : ImplGetSvxCharAndParaPropertiesSet() );
2486 1 : aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) );
2487 2 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo();
2488 1 : if (!xPropSetInfo.is())
2489 : throw uno::RuntimeException("Cannot query XPropertySetInfo",
2490 : uno::Reference< uno::XInterface >
2491 0 : ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
2492 :
2493 : // build sequence of available properties to check
2494 1 : sal_Int32 nLenReqAttr = rRequestedAttributes.getLength();
2495 2 : uno::Sequence< beans::Property > aProperties;
2496 1 : if (nLenReqAttr)
2497 : {
2498 1 : const OUString *pRequestedAttributes = rRequestedAttributes.getConstArray();
2499 :
2500 1 : aProperties.realloc( nLenReqAttr );
2501 1 : beans::Property *pProperties = aProperties.getArray();
2502 1 : sal_Int32 nCurLen = 0;
2503 2 : for (sal_Int32 i = 0; i < nLenReqAttr; ++i)
2504 : {
2505 1 : beans::Property aProp;
2506 : try
2507 : {
2508 1 : aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] );
2509 : }
2510 2 : catch (const beans::UnknownPropertyException&)
2511 : {
2512 1 : continue;
2513 : }
2514 0 : pProperties[ nCurLen++ ] = aProp;
2515 0 : }
2516 1 : aProperties.realloc( nCurLen );
2517 : }
2518 : else
2519 0 : aProperties = xPropSetInfo->getProperties();
2520 :
2521 1 : sal_Int32 nLength = aProperties.getLength();
2522 1 : const beans::Property *pProperties = aProperties.getConstArray();
2523 :
2524 : // build resulting sequence
2525 1 : uno::Sequence< beans::PropertyValue > aOutSequence( nLength );
2526 1 : beans::PropertyValue* pOutSequence = aOutSequence.getArray();
2527 1 : sal_Int32 nOutLen = 0;
2528 1 : for (sal_Int32 i = 0; i < nLength; ++i)
2529 : {
2530 : // calling implementation functions:
2531 : // _getPropertyState and _getPropertyValue (see below) to provide
2532 : // the proper paragraph number when retrieving paragraph attributes
2533 0 : PropertyState eState = aPropSet._getPropertyState( pProperties->Name, mnParagraphIndex );
2534 : if ( eState == PropertyState_AMBIGUOUS_VALUE )
2535 : {
2536 : OSL_FAIL( "ambiguous property value encountered" );
2537 : }
2538 :
2539 : //if (eState == PropertyState_DIRECT_VALUE)
2540 : // per definition all paragraph properties and all character
2541 : // properties spanning the whole paragraph should be returned
2542 : // and declared as default value
2543 : {
2544 0 : pOutSequence->Name = pProperties->Name;
2545 0 : pOutSequence->Handle = pProperties->Handle;
2546 0 : pOutSequence->Value = aPropSet._getPropertyValue( pProperties->Name, mnParagraphIndex );
2547 0 : pOutSequence->State = PropertyState_DEFAULT_VALUE;
2548 :
2549 0 : ++pOutSequence;
2550 0 : ++nOutLen;
2551 : }
2552 0 : ++pProperties;
2553 : }
2554 1 : aOutSequence.realloc( nOutLen );
2555 :
2556 2 : return aOutSequence;
2557 : }
2558 :
2559 :
2560 1 : uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getRunAttributes(
2561 : sal_Int32 nIndex,
2562 : const uno::Sequence< OUString >& rRequestedAttributes )
2563 : throw (beans::UnknownPropertyException, lang::IndexOutOfBoundsException,
2564 : uno::RuntimeException, std::exception)
2565 : {
2566 :
2567 1 : SolarMutexGuard aGuard;
2568 :
2569 : #if OSL_DEBUG_LEVEL > 0
2570 : SvxAccessibleTextAdapter& rCacheTF =
2571 : #endif
2572 1 : GetTextForwarder();
2573 :
2574 : #if OSL_DEBUG_LEVEL > 0
2575 : (void)rCacheTF;
2576 : #endif
2577 :
2578 : DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2579 : "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
2580 :
2581 1 : if( getCharacterCount() > 0 )
2582 1 : CheckIndex(nIndex);
2583 : else
2584 0 : CheckPosition(nIndex);
2585 :
2586 1 : SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
2587 3 : ImplGetSvxCharAndParaPropertiesSet() );
2588 1 : aPropSet.SetSelection( MakeSelection( nIndex ) );
2589 2 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo();
2590 1 : if (!xPropSetInfo.is())
2591 : throw uno::RuntimeException("Cannot query XPropertySetInfo",
2592 : uno::Reference< uno::XInterface >
2593 0 : ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
2594 :
2595 : // build sequence of available properties to check
2596 1 : sal_Int32 nLenReqAttr = rRequestedAttributes.getLength();
2597 2 : uno::Sequence< beans::Property > aProperties;
2598 1 : if (nLenReqAttr)
2599 : {
2600 1 : const OUString *pRequestedAttributes = rRequestedAttributes.getConstArray();
2601 :
2602 1 : aProperties.realloc( nLenReqAttr );
2603 1 : beans::Property *pProperties = aProperties.getArray();
2604 1 : sal_Int32 nCurLen = 0;
2605 2 : for (sal_Int32 i = 0; i < nLenReqAttr; ++i)
2606 : {
2607 1 : beans::Property aProp;
2608 : try
2609 : {
2610 1 : aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] );
2611 : }
2612 2 : catch (const beans::UnknownPropertyException&)
2613 : {
2614 1 : continue;
2615 : }
2616 0 : pProperties[ nCurLen++ ] = aProp;
2617 0 : }
2618 1 : aProperties.realloc( nCurLen );
2619 : }
2620 : else
2621 0 : aProperties = xPropSetInfo->getProperties();
2622 :
2623 1 : sal_Int32 nLength = aProperties.getLength();
2624 1 : const beans::Property *pProperties = aProperties.getConstArray();
2625 :
2626 : // build resulting sequence
2627 1 : uno::Sequence< beans::PropertyValue > aOutSequence( nLength );
2628 1 : beans::PropertyValue* pOutSequence = aOutSequence.getArray();
2629 1 : sal_Int32 nOutLen = 0;
2630 1 : for (sal_Int32 i = 0; i < nLength; ++i)
2631 : {
2632 : // calling 'regular' functions that will operate on the selection
2633 0 : PropertyState eState = aPropSet.getPropertyState( pProperties->Name );
2634 0 : if (eState == PropertyState_DIRECT_VALUE)
2635 : {
2636 0 : pOutSequence->Name = pProperties->Name;
2637 0 : pOutSequence->Handle = pProperties->Handle;
2638 0 : pOutSequence->Value = aPropSet.getPropertyValue( pProperties->Name );
2639 0 : pOutSequence->State = eState;
2640 :
2641 0 : ++pOutSequence;
2642 0 : ++nOutLen;
2643 : }
2644 0 : ++pProperties;
2645 : }
2646 1 : aOutSequence.realloc( nOutLen );
2647 :
2648 2 : return aOutSequence;
2649 : }
2650 :
2651 : // XAccessibleHypertext
2652 0 : ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkCount( ) throw (::com::sun::star::uno::RuntimeException, std::exception)
2653 : {
2654 0 : SvxAccessibleTextAdapter& rT = GetTextForwarder();
2655 0 : const sal_Int32 nPara = GetParagraphIndex();
2656 :
2657 0 : sal_Int32 nHyperLinks = 0;
2658 0 : sal_Int32 nFields = rT.GetFieldCount( nPara );
2659 0 : for (sal_Int32 n = 0; n < nFields; ++n)
2660 : {
2661 0 : EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2662 0 : if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2663 0 : nHyperLinks++;
2664 0 : }
2665 0 : return nHyperLinks;
2666 : }
2667 :
2668 0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleHyperlink > SAL_CALL AccessibleEditableTextPara::getHyperLink( ::sal_Int32 nLinkIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
2669 : {
2670 0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleHyperlink > xRef;
2671 :
2672 0 : SvxAccessibleTextAdapter& rT = GetTextForwarder();
2673 0 : const sal_Int32 nPara = GetParagraphIndex();
2674 :
2675 0 : sal_Int32 nHyperLink = 0;
2676 0 : sal_Int32 nFields = rT.GetFieldCount( nPara );
2677 0 : for (sal_Int32 n = 0; n < nFields; ++n)
2678 : {
2679 0 : EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2680 0 : if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2681 : {
2682 0 : if ( nHyperLink == nLinkIndex )
2683 : {
2684 0 : sal_Int32 nEEStart = aField.aPosition.nIndex;
2685 :
2686 : // Translate EE Index to accessible index
2687 0 : sal_Int32 nStart = rT.CalcEditEngineIndex( nPara, nEEStart );
2688 0 : sal_Int32 nEnd = nStart + aField.aCurrentText.getLength();
2689 0 : xRef = new AccessibleHyperlink( rT, new SvxFieldItem( *aField.pFieldItem ), nPara, nEEStart, nStart, nEnd, aField.aCurrentText );
2690 0 : break;
2691 : }
2692 0 : nHyperLink++;
2693 : }
2694 0 : }
2695 :
2696 0 : return xRef;
2697 : }
2698 :
2699 0 : ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkIndex( ::sal_Int32 nCharIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
2700 : {
2701 0 : const sal_Int32 nPara = GetParagraphIndex();
2702 0 : SvxAccessibleTextAdapter& rT = GetTextForwarder();
2703 :
2704 0 : const sal_Int32 nEEIndex = rT.CalcEditEngineIndex( nPara, nCharIndex );
2705 0 : sal_Int32 nHLIndex = -1; //i123620
2706 0 : sal_Int32 nHyperLink = 0;
2707 0 : sal_Int32 nFields = rT.GetFieldCount( nPara );
2708 0 : for (sal_Int32 n = 0; n < nFields; ++n)
2709 : {
2710 0 : EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2711 0 : if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2712 : {
2713 0 : if ( aField.aPosition.nIndex == nEEIndex )
2714 : {
2715 0 : nHLIndex = nHyperLink;
2716 0 : break;
2717 : }
2718 0 : nHyperLink++;
2719 : }
2720 0 : }
2721 :
2722 0 : return nHLIndex;
2723 : }
2724 :
2725 : // XAccessibleMultiLineText
2726 0 : sal_Int32 SAL_CALL AccessibleEditableTextPara::getLineNumberAtIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
2727 : {
2728 :
2729 0 : sal_Int32 nRes = -1;
2730 0 : sal_Int32 nPara = GetParagraphIndex();
2731 :
2732 0 : SvxTextForwarder &rCacheTF = GetTextForwarder();
2733 0 : const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
2734 : DBG_ASSERT( bValidPara, "getLineNumberAtIndex: current paragraph index out of range" );
2735 0 : if (bValidPara)
2736 : {
2737 : // we explicitly allow for the index to point at the character right behind the text
2738 0 : if (0 <= nIndex && nIndex <= rCacheTF.GetTextLen( nPara ))
2739 0 : nRes = rCacheTF.GetLineNumberAtIndex( nPara, nIndex );
2740 : else
2741 0 : throw lang::IndexOutOfBoundsException();
2742 : }
2743 0 : return nRes;
2744 : }
2745 :
2746 : // XAccessibleMultiLineText
2747 0 : ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineNumber( sal_Int32 nLineNo ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
2748 : {
2749 :
2750 0 : ::com::sun::star::accessibility::TextSegment aResult;
2751 0 : sal_Int32 nPara = GetParagraphIndex();
2752 0 : SvxTextForwarder &rCacheTF = GetTextForwarder();
2753 0 : const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
2754 : DBG_ASSERT( bValidPara, "getTextAtLineNumber: current paragraph index out of range" );
2755 0 : if (bValidPara)
2756 : {
2757 0 : if (0 <= nLineNo && nLineNo < rCacheTF.GetLineCount( nPara ))
2758 : {
2759 0 : sal_Int32 nStart = 0, nEnd = 0;
2760 0 : rCacheTF.GetLineBoundaries( nStart, nEnd, nPara, nLineNo );
2761 0 : if (nStart >= 0 && nEnd >= 0)
2762 : {
2763 : try
2764 : {
2765 0 : aResult.SegmentText = getTextRange( nStart, nEnd );
2766 0 : aResult.SegmentStart = nStart;
2767 0 : aResult.SegmentEnd = nEnd;
2768 : }
2769 0 : catch (const lang::IndexOutOfBoundsException&)
2770 : {
2771 : // this is not the exception that should be raised in this function ...
2772 : DBG_ASSERT( false, "unexpected exception" );
2773 : }
2774 : }
2775 : }
2776 : else
2777 0 : throw lang::IndexOutOfBoundsException();
2778 : }
2779 0 : return aResult;
2780 : }
2781 :
2782 : // XAccessibleMultiLineText
2783 0 : ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineWithCaret( ) throw (uno::RuntimeException, std::exception)
2784 : {
2785 :
2786 0 : ::com::sun::star::accessibility::TextSegment aResult;
2787 : try
2788 : {
2789 0 : aResult = getTextAtLineNumber( getNumberOfLineWithCaret() );
2790 : }
2791 0 : catch (const lang::IndexOutOfBoundsException&)
2792 : {
2793 : // this one needs to be catched since this interface does not allow for it.
2794 : }
2795 0 : return aResult;
2796 : }
2797 :
2798 : // XAccessibleMultiLineText
2799 0 : sal_Int32 SAL_CALL AccessibleEditableTextPara::getNumberOfLineWithCaret( ) throw (uno::RuntimeException, std::exception)
2800 : {
2801 :
2802 0 : sal_Int32 nRes = -1;
2803 : try
2804 : {
2805 0 : nRes = getLineNumberAtIndex( getCaretPosition() );
2806 : }
2807 0 : catch (const lang::IndexOutOfBoundsException&)
2808 : {
2809 : // this one needs to be catched since this interface does not allow for it.
2810 : }
2811 0 : return nRes;
2812 : }
2813 :
2814 :
2815 : // XServiceInfo
2816 6 : OUString SAL_CALL AccessibleEditableTextPara::getImplementationName() throw (uno::RuntimeException, std::exception)
2817 : {
2818 :
2819 6 : return OUString("AccessibleEditableTextPara");
2820 : }
2821 :
2822 0 : sal_Bool SAL_CALL AccessibleEditableTextPara::supportsService (const OUString& sServiceName) throw (uno::RuntimeException, std::exception)
2823 : {
2824 :
2825 0 : return cppu::supportsService(this, sServiceName);
2826 : }
2827 :
2828 0 : uno::Sequence< OUString> SAL_CALL AccessibleEditableTextPara::getSupportedServiceNames() throw (uno::RuntimeException, std::exception)
2829 : {
2830 :
2831 0 : const OUString sServiceName( getServiceName() );
2832 0 : return uno::Sequence< OUString > (&sServiceName, 1);
2833 : }
2834 :
2835 : // XServiceName
2836 0 : OUString SAL_CALL AccessibleEditableTextPara::getServiceName() throw (uno::RuntimeException)
2837 : {
2838 :
2839 : // #105185# Using correct service now
2840 0 : return OUString("com.sun.star.text.AccessibleParagraphView");
2841 : }
2842 :
2843 : } // end of namespace accessibility
2844 :
2845 :
2846 :
2847 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|