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