Bump version to 4.1-6
[LibreOffice.git] / editeng / source / accessibility / AccessibleEditableTextPara.cxx
blob9702c440e10b20ca2191edbf36b714c8ad2925c2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 //------------------------------------------------------------------------
23 // Global header
25 //------------------------------------------------------------------------
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 <unotools/accessiblestatesethelper.hxx>
46 #include <unotools/accessiblerelationsethelper.hxx>
47 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
48 #include <vcl/unohelp.hxx>
49 #include <editeng/editeng.hxx>
50 #include <editeng/unoprnms.hxx>
51 #include <editeng/unoipset.hxx>
52 #include <editeng/outliner.hxx>
54 //------------------------------------------------------------------------
56 // Project-local header
58 //------------------------------------------------------------------------
60 #include <com/sun/star/beans/PropertyState.hpp>
62 //!!!#include <svx/unoshape.hxx>
63 //!!!#include <svx/dialmgr.hxx>
64 //!!!#include "accessibility.hrc"
66 #include <editeng/unolingu.hxx>
67 #include <editeng/unopracc.hxx>
68 #include "editeng/AccessibleEditableTextPara.hxx"
69 #include "AccessibleHyperlink.hxx"
71 #include <svtools/colorcfg.hxx>
74 using namespace ::com::sun::star;
75 using namespace ::com::sun::star::beans;
76 using namespace ::com::sun::star::accessibility;
79 //------------------------------------------------------------------------
81 // AccessibleEditableTextPara implementation
83 //------------------------------------------------------------------------
85 namespace accessibility
88 const SvxItemPropertySet* ImplGetSvxCharAndParaPropertiesSet()
90 // PropertyMap for character and paragraph properties
91 static const SfxItemPropertyMapEntry aPropMap[] =
93 SVX_UNOEDIT_CHAR_PROPERTIES,
94 SVX_UNOEDIT_PARA_PROPERTIES,
95 SVX_UNOEDIT_NUMBERING_PROPERTIE,
96 {MAP_CHAR_LEN("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0},
97 {MAP_CHAR_LEN("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0},
98 {0,0,0,0,0,0}
100 static SvxItemPropertySet aPropSet( aPropMap, EditEngine::GetGlobalItemPool() );
101 return &aPropSet;
105 DBG_NAME( AccessibleEditableTextPara )
107 // #i27138# - add parameter <_pParaManager>
108 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 mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient()),
123 // #i27138#
124 mpParaManager( _pParaManager )
126 #ifdef DBG_UTIL
127 DBG_CTOR( AccessibleEditableTextPara, NULL );
128 OSL_TRACE( "AccessibleEditableTextPara received ID: %d", mnNotifierClientId );
129 #endif
133 // Create the state set.
134 ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper ();
135 mxStateSet = pStateSet;
137 // these are always on
138 pStateSet->AddState( AccessibleStateType::MULTI_LINE );
139 pStateSet->AddState( AccessibleStateType::FOCUSABLE );
140 pStateSet->AddState( AccessibleStateType::VISIBLE );
141 pStateSet->AddState( AccessibleStateType::SHOWING );
142 pStateSet->AddState( AccessibleStateType::ENABLED );
143 pStateSet->AddState( AccessibleStateType::SENSITIVE );
145 catch (const uno::Exception&)
150 AccessibleEditableTextPara::~AccessibleEditableTextPara()
152 DBG_DTOR( AccessibleEditableTextPara, NULL );
154 // sign off from event notifier
155 if( getNotifierClientId() != -1 )
159 ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() );
160 #ifdef DBG_UTIL
161 OSL_TRACE( "AccessibleEditableTextPara revoked ID: %d", mnNotifierClientId );
162 #endif
164 catch (const uno::Exception&)
170 OUString AccessibleEditableTextPara::implGetText()
172 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
174 return GetTextRange( 0, GetTextLen() );
177 ::com::sun::star::lang::Locale AccessibleEditableTextPara::implGetLocale()
179 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
181 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_INT32,
182 "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
184 // return locale of first character in the paragraph
185 return LanguageTag(GetTextForwarder().GetLanguage( GetParagraphIndex(), 0 )).getLocale();
188 void AccessibleEditableTextPara::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
190 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
192 sal_uInt16 nStart, nEnd;
194 if( GetSelection( nStart, nEnd ) )
196 nStartIndex = nStart;
197 nEndIndex = nEnd;
199 else
201 // #102234# No exception, just set to 'invalid'
202 nStartIndex = -1;
203 nEndIndex = -1;
207 void AccessibleEditableTextPara::implGetParagraphBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 /*nIndex*/ )
209 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
210 DBG_WARNING( "AccessibleEditableTextPara::implGetParagraphBoundary: only a base implementation, ignoring the index" );
212 rBoundary.startPos = 0;
213 rBoundary.endPos = GetTextLen();
216 void AccessibleEditableTextPara::implGetLineBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex )
218 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
220 SvxTextForwarder& rCacheTF = GetTextForwarder();
221 const sal_Int32 nParaIndex = GetParagraphIndex();
223 DBG_ASSERT(nParaIndex >= 0 && nParaIndex <= SAL_MAX_INT32,
224 "AccessibleEditableTextPara::implGetLineBoundary: paragraph index value overflow");
226 const sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex );
228 CheckPosition(nIndex);
230 rBoundary.startPos = rBoundary.endPos = -1;
232 const sal_uInt16 nLineCount=rCacheTF.GetLineCount( nParaIndex );
234 if( nIndex == nTextLen )
236 // #i17014# Special-casing one-behind-the-end character
237 if( nLineCount <= 1 )
238 rBoundary.startPos = 0;
239 else
240 rBoundary.startPos = nTextLen - rCacheTF.GetLineLen( nParaIndex,
241 nLineCount-1 );
243 rBoundary.endPos = nTextLen;
245 else
247 // normal line search
248 sal_uInt16 nLine;
249 sal_Int32 nCurIndex;
250 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
252 nCurIndex += rCacheTF.GetLineLen( nParaIndex, nLine);
254 if( nCurIndex > nIndex )
256 rBoundary.startPos = nCurIndex - rCacheTF.GetLineLen( nParaIndex, nLine);
257 rBoundary.endPos = nCurIndex;
258 break;
264 int AccessibleEditableTextPara::getNotifierClientId() const
266 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
268 return mnNotifierClientId;
271 void AccessibleEditableTextPara::SetIndexInParent( sal_Int32 nIndex )
273 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
275 mnIndexInParent = nIndex;
278 sal_Int32 AccessibleEditableTextPara::GetIndexInParent() const
280 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
282 return mnIndexInParent;
285 void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex )
287 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
289 sal_Int32 nOldIndex = mnParagraphIndex;
291 mnParagraphIndex = nIndex;
293 WeakBullet::HardRefType aChild( maImageBullet.get() );
294 if( aChild.is() )
295 aChild->SetParagraphIndex(mnParagraphIndex);
299 if( nOldIndex != nIndex )
301 uno::Any aOldDesc;
302 uno::Any aOldName;
306 aOldDesc <<= getAccessibleDescription();
307 aOldName <<= getAccessibleName();
309 catch (const uno::Exception&) // optional behaviour
312 // index and therefore description changed
313 FireEvent( AccessibleEventId::DESCRIPTION_CHANGED, uno::makeAny( getAccessibleDescription() ), aOldDesc );
314 FireEvent( AccessibleEventId::NAME_CHANGED, uno::makeAny( getAccessibleName() ), aOldName );
317 catch (const uno::Exception&) // optional behaviour
322 sal_Int32 AccessibleEditableTextPara::GetParagraphIndex() const SAL_THROW((uno::RuntimeException))
324 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
326 return mnParagraphIndex;
329 void AccessibleEditableTextPara::Dispose()
331 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
333 int nClientId( getNotifierClientId() );
335 // #108212# drop all references before notifying dispose
336 mxParent = NULL;
337 mnNotifierClientId = -1;
338 mpEditSource = NULL;
340 // notify listeners
341 if( nClientId != -1 )
345 uno::Reference < XAccessibleContext > xThis = getAccessibleContext();
347 // #106234# Delegate to EventNotifier
348 ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, xThis );
349 #ifdef DBG_UTIL
350 OSL_TRACE( "Disposed ID: %d", nClientId );
351 #endif
353 catch (const uno::Exception&)
359 void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter* pEditSource )
361 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
363 mpEditSource = pEditSource;
365 WeakBullet::HardRefType aChild( maImageBullet.get() );
366 if( aChild.is() )
367 aChild->SetEditSource(pEditSource);
369 if( !mpEditSource )
371 // going defunc
372 UnSetState( AccessibleStateType::SHOWING );
373 UnSetState( AccessibleStateType::VISIBLE );
374 SetState( AccessibleStateType::INVALID );
375 SetState( AccessibleStateType::DEFUNC );
377 Dispose();
380 // #108900# Init last text content
383 TextChanged();
385 catch (const uno::RuntimeException&)
390 ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex )
392 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
394 // check overflow
395 DBG_ASSERT(nStartEEIndex >= 0 && nStartEEIndex <= USHRT_MAX &&
396 nEndEEIndex >= 0 && nEndEEIndex <= USHRT_MAX &&
397 GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_INT32,
398 "AccessibleEditableTextPara::MakeSelection: index value overflow");
400 sal_Int32 nParaIndex = GetParagraphIndex();
401 return ESelection( nParaIndex, static_cast< sal_uInt16 >( nStartEEIndex ),
402 nParaIndex, static_cast< sal_uInt16 >( nEndEEIndex ) );
405 ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nEEIndex )
407 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
409 return MakeSelection( nEEIndex, nEEIndex+1 );
412 ESelection AccessibleEditableTextPara::MakeCursor( sal_Int32 nEEIndex )
414 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
416 return MakeSelection( nEEIndex, nEEIndex );
419 void AccessibleEditableTextPara::CheckIndex( sal_Int32 nIndex ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
421 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
423 if( nIndex < 0 || nIndex >= getCharacterCount() )
424 throw lang::IndexOutOfBoundsException("AccessibleEditableTextPara: character index out of bounds",
425 uno::Reference< uno::XInterface >
426 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy
429 void AccessibleEditableTextPara::CheckPosition( sal_Int32 nIndex ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
431 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
433 if( nIndex < 0 || nIndex > getCharacterCount() )
434 throw lang::IndexOutOfBoundsException("AccessibleEditableTextPara: character position out of bounds",
435 uno::Reference< uno::XInterface >
436 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy
439 void AccessibleEditableTextPara::CheckRange( sal_Int32 nStart, sal_Int32 nEnd ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
441 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
443 CheckPosition( nStart );
444 CheckPosition( nEnd );
447 sal_Bool AccessibleEditableTextPara::GetSelection( sal_uInt16& nStartPos, sal_uInt16& nEndPos ) SAL_THROW((uno::RuntimeException))
449 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
451 ESelection aSelection;
452 sal_Int32 nPara = GetParagraphIndex();
453 if( !GetEditViewForwarder().GetSelection( aSelection ) )
454 return sal_False;
456 if( aSelection.nStartPara < aSelection.nEndPara )
458 if( aSelection.nStartPara > nPara ||
459 aSelection.nEndPara < nPara )
460 return sal_False;
462 if( nPara == aSelection.nStartPara )
463 nStartPos = aSelection.nStartPos;
464 else
465 nStartPos = 0;
467 if( nPara == aSelection.nEndPara )
468 nEndPos = aSelection.nEndPos;
469 else
470 nEndPos = GetTextLen();
472 else
474 if( aSelection.nStartPara < nPara ||
475 aSelection.nEndPara > nPara )
476 return sal_False;
478 if( nPara == aSelection.nStartPara )
479 nStartPos = aSelection.nStartPos;
480 else
481 nStartPos = GetTextLen();
483 if( nPara == aSelection.nEndPara )
484 nEndPos = aSelection.nEndPos;
485 else
486 nEndPos = 0;
489 return sal_True;
492 String AccessibleEditableTextPara::GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) SAL_THROW((uno::RuntimeException))
494 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
496 return GetTextForwarder().GetText( MakeSelection(nStartIndex, nEndIndex) );
499 sal_uInt16 AccessibleEditableTextPara::GetTextLen() const SAL_THROW((uno::RuntimeException))
501 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
503 return GetTextForwarder().GetTextLen( static_cast< sal_uInt16 >( GetParagraphIndex() ) );
506 SvxEditSourceAdapter& AccessibleEditableTextPara::GetEditSource() const SAL_THROW((uno::RuntimeException))
508 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
510 if( mpEditSource )
511 return *mpEditSource;
512 else
513 throw uno::RuntimeException("No edit source, object is defunct",
514 uno::Reference< uno::XInterface >
515 ( static_cast< ::cppu::OWeakObject* >
516 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
519 SvxAccessibleTextAdapter& AccessibleEditableTextPara::GetTextForwarder() const SAL_THROW((uno::RuntimeException))
521 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
523 SvxEditSourceAdapter& rEditSource = GetEditSource();
524 SvxAccessibleTextAdapter* pTextForwarder = rEditSource.GetTextForwarderAdapter();
526 if( !pTextForwarder )
527 throw uno::RuntimeException("Unable to fetch text forwarder, object is defunct",
528 uno::Reference< uno::XInterface >
529 ( static_cast< ::cppu::OWeakObject* >
530 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
532 if( pTextForwarder->IsValid() )
533 return *pTextForwarder;
534 else
535 throw uno::RuntimeException("Text forwarder is invalid, object is defunct",
536 uno::Reference< uno::XInterface >
537 ( static_cast< ::cppu::OWeakObject* >
538 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
541 SvxViewForwarder& AccessibleEditableTextPara::GetViewForwarder() const SAL_THROW((uno::RuntimeException))
543 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
545 SvxEditSource& rEditSource = GetEditSource();
546 SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder();
548 if( !pViewForwarder )
550 throw uno::RuntimeException("Unable to fetch view forwarder, object is defunct",
551 uno::Reference< uno::XInterface >
552 ( static_cast< ::cppu::OWeakObject* >
553 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
556 if( pViewForwarder->IsValid() )
557 return *pViewForwarder;
558 else
559 throw uno::RuntimeException("View forwarder is invalid, object is defunct",
560 uno::Reference< uno::XInterface >
561 ( static_cast< ::cppu::OWeakObject* >
562 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
565 SvxAccessibleTextEditViewAdapter& AccessibleEditableTextPara::GetEditViewForwarder( sal_Bool bCreate ) const SAL_THROW((uno::RuntimeException))
567 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
569 SvxEditSourceAdapter& rEditSource = GetEditSource();
570 SvxAccessibleTextEditViewAdapter* pTextEditViewForwarder = rEditSource.GetEditViewForwarderAdapter( bCreate );
572 if( !pTextEditViewForwarder )
574 if( bCreate )
575 throw uno::RuntimeException("Unable to fetch view forwarder, object is defunct",
576 uno::Reference< uno::XInterface >
577 ( static_cast< ::cppu::OWeakObject* >
578 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
579 else
580 throw uno::RuntimeException("No view forwarder, object not in edit mode",
581 uno::Reference< uno::XInterface >
582 ( static_cast< ::cppu::OWeakObject* >
583 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
586 if( pTextEditViewForwarder->IsValid() )
587 return *pTextEditViewForwarder;
588 else
590 if( bCreate )
591 throw uno::RuntimeException("View forwarder is invalid, object is defunct",
592 uno::Reference< uno::XInterface >
593 ( static_cast< ::cppu::OWeakObject* >
594 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
595 else
596 throw uno::RuntimeException("View forwarder is invalid, object not in edit mode",
597 uno::Reference< uno::XInterface >
598 ( static_cast< ::cppu::OWeakObject* >
599 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
603 sal_Bool AccessibleEditableTextPara::HaveEditView() const
605 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
607 SvxEditSource& rEditSource = GetEditSource();
608 SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder();
610 if( !pViewForwarder )
611 return sal_False;
613 if( !pViewForwarder->IsValid() )
614 return sal_False;
616 return sal_True;
619 sal_Bool AccessibleEditableTextPara::HaveChildren()
621 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
623 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_INT32,
624 "AccessibleEditableTextPara::HaveChildren: paragraph index value overflow");
626 return GetTextForwarder().HaveImageBullet( GetParagraphIndex() );
629 Rectangle AccessibleEditableTextPara::LogicToPixel( const Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder& rForwarder )
631 // convert to screen coordinates
632 return Rectangle( rForwarder.LogicToPixel( rRect.TopLeft(), rMapMode ),
633 rForwarder.LogicToPixel( rRect.BottomRight(), rMapMode ) );
636 const Point& AccessibleEditableTextPara::GetEEOffset() const
638 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
640 return maEEOffset;
643 void AccessibleEditableTextPara::SetEEOffset( const Point& rOffset )
645 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
647 WeakBullet::HardRefType aChild( maImageBullet.get() );
648 if( aChild.is() )
649 aChild->SetEEOffset(rOffset);
651 maEEOffset = rOffset;
654 void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue) const
656 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
658 uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleEditableTextPara* > (this)->getAccessibleContext() );
660 AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue);
662 // #102261# Call global queue for focus events
663 if( nEventId == AccessibleEventId::STATE_CHANGED )
664 vcl::unohelper::NotifyAccessibleStateEventGlobally( aEvent );
666 // #106234# Delegate to EventNotifier
667 if( getNotifierClientId() != -1 )
668 ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(),
669 aEvent );
672 void AccessibleEditableTextPara::GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const
674 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
676 FireEvent( nEventId, rNewValue );
679 void AccessibleEditableTextPara::LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const
681 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
683 FireEvent( nEventId, uno::Any(), rOldValue );
686 void AccessibleEditableTextPara::SetState( const sal_Int16 nStateId )
688 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
690 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
691 if( pStateSet != NULL &&
692 !pStateSet->contains(nStateId) )
694 pStateSet->AddState( nStateId );
695 GotPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED );
699 void AccessibleEditableTextPara::UnSetState( const sal_Int16 nStateId )
701 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
703 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
704 if( pStateSet != NULL &&
705 pStateSet->contains(nStateId) )
707 pStateSet->RemoveState( nStateId );
708 LostPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED );
712 void AccessibleEditableTextPara::TextChanged()
714 OUString aCurrentString( OCommonAccessibleText::getText() );
715 uno::Any aDeleted;
716 uno::Any aInserted;
717 if( OCommonAccessibleText::implInitTextChangedEvent( maLastTextString, aCurrentString,
718 aDeleted, aInserted) )
720 FireEvent( AccessibleEventId::TEXT_CHANGED, aInserted, aDeleted );
721 maLastTextString = aCurrentString;
725 sal_Bool AccessibleEditableTextPara::GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, sal_Int32 nIndex )
727 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
729 DBG_ASSERT(nIndex >= 0 && nIndex <= USHRT_MAX,
730 "AccessibleEditableTextPara::GetAttributeRun: index value overflow");
732 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_INT32,
733 "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
735 return GetTextForwarder().GetAttributeRun( nStartIndex,
736 nEndIndex,
737 GetParagraphIndex(),
738 static_cast< sal_uInt16 >(nIndex) );
741 uno::Any SAL_CALL AccessibleEditableTextPara::queryInterface (const uno::Type & rType) throw (uno::RuntimeException)
743 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
745 uno::Any aRet;
747 // must provide XAccesibleText by hand, since it comes publicly inherited by XAccessibleEditableText
748 if ( rType == ::getCppuType((uno::Reference< XAccessibleText > *)0) )
750 uno::Reference< XAccessibleText > aAccText = static_cast< XAccessibleEditableText * >(this);
751 aRet <<= aAccText;
753 else if ( rType == ::getCppuType((uno::Reference< XAccessibleEditableText > *)0) )
755 uno::Reference< XAccessibleEditableText > aAccEditText = this;
756 aRet <<= aAccEditText;
758 else if ( rType == ::getCppuType((uno::Reference< XAccessibleHypertext > *)0) )
760 uno::Reference< XAccessibleHypertext > aAccHyperText = this;
761 aRet <<= aAccHyperText;
763 else
765 aRet = AccessibleTextParaInterfaceBase::queryInterface(rType);
768 return aRet;
771 // XAccessible
772 uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext() throw (uno::RuntimeException)
774 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
776 // We implement the XAccessibleContext interface in the same object
777 return uno::Reference< XAccessibleContext > ( this );
780 // XAccessibleContext
781 sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleChildCount() throw (uno::RuntimeException)
783 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
785 SolarMutexGuard aGuard;
787 return HaveChildren() ? 1 : 0;
790 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
792 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
794 SolarMutexGuard aGuard;
796 if( !HaveChildren() )
797 throw lang::IndexOutOfBoundsException("No children available",
798 uno::Reference< uno::XInterface >
799 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy
801 if( i != 0 )
802 throw lang::IndexOutOfBoundsException("Invalid child index",
803 uno::Reference< uno::XInterface >
804 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy
806 WeakBullet::HardRefType aChild( maImageBullet.get() );
808 if( !aChild.is() )
810 // there is no hard reference available, create object then
811 AccessibleImageBullet* pChild = new AccessibleImageBullet( uno::Reference< XAccessible >( this ) );
812 uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY );
814 if( !xChild.is() )
815 throw uno::RuntimeException("Child creation failed",
816 uno::Reference< uno::XInterface >
817 ( static_cast< ::cppu::OWeakObject* > (this) ) );
819 aChild = WeakBullet::HardRefType( xChild, pChild );
821 aChild->SetEditSource( &GetEditSource() );
822 aChild->SetParagraphIndex( GetParagraphIndex() );
823 aChild->SetIndexInParent( i );
825 maImageBullet = aChild;
828 return aChild.getRef();
831 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleParent() throw (uno::RuntimeException)
833 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
835 #ifdef DBG_UTIL
836 if( !mxParent.is() )
837 OSL_TRACE( "AccessibleEditableTextPara::getAccessibleParent: no frontend set, did somebody forgot to call AccessibleTextHelper::SetEventSource()?");
838 #endif
840 return mxParent;
843 sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleIndexInParent() throw (uno::RuntimeException)
845 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
847 return mnIndexInParent;
850 sal_Int16 SAL_CALL AccessibleEditableTextPara::getAccessibleRole() throw (uno::RuntimeException)
852 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
854 return AccessibleRole::PARAGRAPH;
857 OUString SAL_CALL AccessibleEditableTextPara::getAccessibleDescription() throw (uno::RuntimeException)
859 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
861 // SolarMutexGuard aGuard;
863 return OUString();
866 OUString SAL_CALL AccessibleEditableTextPara::getAccessibleName() throw (uno::RuntimeException)
868 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
870 // SolarMutexGuard aGuard;
872 return OUString();
875 uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleEditableTextPara::getAccessibleRelationSet() throw (uno::RuntimeException)
877 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
879 // #i27138# - provide relations CONTENT_FLOWS_FROM
880 // and CONTENT_FLOWS_TO
881 if ( mpParaManager )
883 utl::AccessibleRelationSetHelper* pAccRelSetHelper =
884 new utl::AccessibleRelationSetHelper();
885 sal_Int32 nMyParaIndex( GetParagraphIndex() );
886 // relation CONTENT_FLOWS_FROM
887 if ( nMyParaIndex > 0 &&
888 mpParaManager->IsReferencable( nMyParaIndex - 1 ) )
890 uno::Sequence<uno::Reference<XInterface> > aSequence(1);
891 aSequence[0] =
892 mpParaManager->GetChild( nMyParaIndex - 1 ).first.get().getRef();
893 AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM,
894 aSequence );
895 pAccRelSetHelper->AddRelation( aAccRel );
898 // relation CONTENT_FLOWS_TO
899 if ( (nMyParaIndex + 1) < (sal_Int32)mpParaManager->GetNum() &&
900 mpParaManager->IsReferencable( nMyParaIndex + 1 ) )
902 uno::Sequence<uno::Reference<XInterface> > aSequence(1);
903 aSequence[0] =
904 mpParaManager->GetChild( nMyParaIndex + 1 ).first.get().getRef();
905 AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO,
906 aSequence );
907 pAccRelSetHelper->AddRelation( aAccRel );
910 return pAccRelSetHelper;
912 else
914 // no relations, therefore empty
915 return uno::Reference< XAccessibleRelationSet >();
919 uno::Reference< XAccessibleStateSet > SAL_CALL AccessibleEditableTextPara::getAccessibleStateSet() throw (uno::RuntimeException)
921 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
923 SolarMutexGuard aGuard;
925 // Create a copy of the state set and return it.
926 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
928 if( !pStateSet )
929 return uno::Reference<XAccessibleStateSet>();
931 return uno::Reference<XAccessibleStateSet>( new ::utl::AccessibleStateSetHelper (*pStateSet) );
934 lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale() throw (IllegalAccessibleComponentStateException, uno::RuntimeException)
936 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
938 SolarMutexGuard aGuard;
940 return implGetLocale();
943 void SAL_CALL AccessibleEditableTextPara::addAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException)
945 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
947 if( getNotifierClientId() != -1 )
948 ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener );
951 void SAL_CALL AccessibleEditableTextPara::removeAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException)
953 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
955 if( getNotifierClientId() != -1 )
956 ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener );
959 // XAccessibleComponent
960 sal_Bool SAL_CALL AccessibleEditableTextPara::containsPoint( const awt::Point& aTmpPoint ) throw (uno::RuntimeException)
962 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
964 SolarMutexGuard aGuard;
966 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_INT32,
967 "AccessibleEditableTextPara::contains: index value overflow");
969 awt::Rectangle aTmpRect = getBounds();
970 Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) );
971 Point aPoint( aTmpPoint.X, aTmpPoint.Y );
973 return aRect.IsInside( aPoint );
976 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point& _aPoint ) throw (uno::RuntimeException)
978 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
980 SolarMutexGuard aGuard;
982 if( HaveChildren() )
984 // #103862# No longer need to make given position relative
985 Point aPoint( _aPoint.X, _aPoint.Y );
987 // respect EditEngine offset to surrounding shape/cell
988 aPoint -= GetEEOffset();
990 // convert to EditEngine coordinate system
991 SvxTextForwarder& rCacheTF = GetTextForwarder();
992 Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
994 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 > (GetParagraphIndex()) );
996 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
997 aBulletInfo.bVisible &&
998 aBulletInfo.nType == SVX_NUM_BITMAP )
1000 Rectangle aRect = aBulletInfo.aBounds;
1002 if( aRect.IsInside( aLogPoint ) )
1003 return getAccessibleChild(0);
1007 // no children at all, or none at given position
1008 return uno::Reference< XAccessible >();
1011 awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds() throw (uno::RuntimeException)
1013 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1015 SolarMutexGuard aGuard;
1017 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_INT32,
1018 "AccessibleEditableTextPara::getBounds: index value overflow");
1020 SvxTextForwarder& rCacheTF = GetTextForwarder();
1021 Rectangle aRect = rCacheTF.GetParaBounds( GetParagraphIndex() );
1023 // convert to screen coordinates
1024 Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
1025 rCacheTF.GetMapMode(),
1026 GetViewForwarder() );
1028 // offset from shape/cell
1029 Point aOffset = GetEEOffset();
1031 return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
1032 aScreenRect.Top() + aOffset.Y(),
1033 aScreenRect.GetSize().Width(),
1034 aScreenRect.GetSize().Height() );
1037 awt::Point SAL_CALL AccessibleEditableTextPara::getLocation( ) throw (uno::RuntimeException)
1039 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1041 SolarMutexGuard aGuard;
1043 awt::Rectangle aRect = getBounds();
1045 return awt::Point( aRect.X, aRect.Y );
1048 awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen( ) throw (uno::RuntimeException)
1050 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1052 SolarMutexGuard aGuard;
1054 // relate us to parent
1055 uno::Reference< XAccessible > xParent = getAccessibleParent();
1056 if( xParent.is() )
1058 uno::Reference< XAccessibleComponent > xParentComponent( xParent, uno::UNO_QUERY );
1059 if( xParentComponent.is() )
1061 awt::Point aRefPoint = xParentComponent->getLocationOnScreen();
1062 awt::Point aPoint = getLocation();
1063 aPoint.X += aRefPoint.X;
1064 aPoint.Y += aRefPoint.Y;
1066 return aPoint;
1068 // #i88070#
1069 // fallback to parent's <XAccessibleContext> instance
1070 else
1072 uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext();
1073 if ( xParentContext.is() )
1075 uno::Reference< XAccessibleComponent > xParentContextComponent( xParentContext, uno::UNO_QUERY );
1076 if( xParentContextComponent.is() )
1078 awt::Point aRefPoint = xParentContextComponent->getLocationOnScreen();
1079 awt::Point aPoint = getLocation();
1080 aPoint.X += aRefPoint.X;
1081 aPoint.Y += aRefPoint.Y;
1083 return aPoint;
1089 throw uno::RuntimeException("Cannot access parent",
1090 uno::Reference< uno::XInterface >
1091 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
1094 awt::Size SAL_CALL AccessibleEditableTextPara::getSize( ) throw (uno::RuntimeException)
1096 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1098 SolarMutexGuard aGuard;
1100 awt::Rectangle aRect = getBounds();
1102 return awt::Size( aRect.Width, aRect.Height );
1105 void SAL_CALL AccessibleEditableTextPara::grabFocus( ) throw (uno::RuntimeException)
1107 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1109 // set cursor to this paragraph
1110 setSelection(0,0);
1113 sal_Int32 SAL_CALL AccessibleEditableTextPara::getForeground( ) throw (::com::sun::star::uno::RuntimeException)
1115 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1117 // #104444# Added to XAccessibleComponent interface
1118 svtools::ColorConfig aColorConfig;
1119 sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
1120 return static_cast<sal_Int32>(nColor);
1123 sal_Int32 SAL_CALL AccessibleEditableTextPara::getBackground( ) throw (::com::sun::star::uno::RuntimeException)
1125 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1127 // #104444# Added to XAccessibleComponent interface
1128 Color aColor( Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor() );
1130 // the background is transparent
1131 aColor.SetTransparency( 0xFF);
1133 return static_cast<sal_Int32>( aColor.GetColor() );
1136 // XAccessibleText
1137 sal_Int32 SAL_CALL AccessibleEditableTextPara::getCaretPosition() throw (uno::RuntimeException)
1139 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1141 SolarMutexGuard aGuard;
1143 if( !HaveEditView() )
1144 return -1;
1146 ESelection aSelection;
1147 if( GetEditViewForwarder().GetSelection( aSelection ) &&
1148 GetParagraphIndex() == aSelection.nEndPara )
1150 // caret is always nEndPara,nEndPos
1151 return aSelection.nEndPos;
1154 // not within this paragraph
1155 return -1;
1158 sal_Bool SAL_CALL AccessibleEditableTextPara::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1160 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1162 return setSelection(nIndex, nIndex);
1165 sal_Unicode SAL_CALL AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1167 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1169 SolarMutexGuard aGuard;
1171 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1172 "AccessibleEditableTextPara::getCharacter: index value overflow");
1174 return OCommonAccessibleText::getCharacter( nIndex );
1177 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< OUString >& rRequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1179 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1180 SolarMutexGuard aGuard;
1182 CheckIndex(nIndex); // may throw IndexOutOfBoundsException
1184 // get default attribues...
1185 ::comphelper::SequenceAsHashMap aPropHashMap( getDefaultAttributes( rRequestedAttributes ) );
1187 // ... and override them with the direct attributes from the specific position
1188 uno::Sequence< beans::PropertyValue > aRunAttribs( getRunAttributes( nIndex, rRequestedAttributes ) );
1189 sal_Int32 nRunAttribs = aRunAttribs.getLength();
1190 const beans::PropertyValue *pRunAttrib = aRunAttribs.getConstArray();
1191 for (sal_Int32 k = 0; k < nRunAttribs; ++k)
1193 const beans::PropertyValue &rRunAttrib = pRunAttrib[k];
1194 aPropHashMap[ rRunAttrib.Name ] = rRunAttrib.Value; //!! should not only be the value !!
1197 // get resulting sequence
1198 uno::Sequence< beans::PropertyValue > aRes;
1199 aPropHashMap >> aRes;
1201 // since SequenceAsHashMap ignores property handles and property state
1202 // we have to restore the property state here (property handles are
1203 // of no use to the accessibility API).
1204 sal_Int32 nRes = aRes.getLength();
1205 beans::PropertyValue *pRes = aRes.getArray();
1206 for (sal_Int32 i = 0; i < nRes; ++i)
1208 beans::PropertyValue &rRes = pRes[i];
1209 sal_Bool bIsDirectVal = sal_False;
1210 for (sal_Int32 k = 0; k < nRunAttribs && !bIsDirectVal; ++k)
1212 if (rRes.Name == pRunAttrib[k].Name)
1213 bIsDirectVal = sal_True;
1215 rRes.Handle = -1;
1216 rRes.State = bIsDirectVal ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
1219 return aRes;
1222 awt::Rectangle SAL_CALL AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1224 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1226 SolarMutexGuard aGuard;
1228 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1229 "AccessibleEditableTextPara::getCharacterBounds: index value overflow");
1231 // #108900# Have position semantics now for nIndex, as
1232 // one-past-the-end values are legal, too.
1233 CheckPosition( nIndex );
1235 SvxTextForwarder& rCacheTF = GetTextForwarder();
1236 Rectangle aRect = rCacheTF.GetCharBounds( static_cast< sal_uInt16 >( GetParagraphIndex() ), static_cast< sal_uInt16 >( nIndex ) );
1238 // convert to screen
1239 Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
1240 rCacheTF.GetMapMode(),
1241 GetViewForwarder() );
1242 // #109864# offset from parent (paragraph), but in screen
1243 // coordinates. This makes sure the internal text offset in
1244 // the outline view forwarder gets cancelled out here
1245 awt::Rectangle aParaRect( getBounds() );
1246 aScreenRect.Move( -aParaRect.X, -aParaRect.Y );
1248 // offset from shape/cell
1249 Point aOffset = GetEEOffset();
1251 return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
1252 aScreenRect.Top() + aOffset.Y(),
1253 aScreenRect.GetSize().Width(),
1254 aScreenRect.GetSize().Height() );
1257 sal_Int32 SAL_CALL AccessibleEditableTextPara::getCharacterCount() throw (uno::RuntimeException)
1259 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1261 SolarMutexGuard aGuard;
1263 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1264 "AccessibleEditableTextPara::getCharacterCount: index value overflow");
1266 return OCommonAccessibleText::getCharacterCount();
1269 sal_Int32 SAL_CALL AccessibleEditableTextPara::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException)
1271 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1273 SolarMutexGuard aGuard;
1275 sal_Int32 nPara;
1276 sal_uInt16 nIndex;
1278 // offset from surrounding cell/shape
1279 Point aOffset( GetEEOffset() );
1280 Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() );
1282 // convert to logical coordinates
1283 SvxTextForwarder& rCacheTF = GetTextForwarder();
1284 Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
1286 // re-offset to parent (paragraph)
1287 Rectangle aParaRect = rCacheTF.GetParaBounds( GetParagraphIndex() );
1288 aLogPoint.Move( aParaRect.Left(), aParaRect.Top() );
1290 if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) &&
1291 GetParagraphIndex() == nPara )
1293 // #102259# Double-check if we're _really_ on the given character
1296 awt::Rectangle aRect1( getCharacterBounds(nIndex) );
1297 Rectangle aRect2( aRect1.X, aRect1.Y,
1298 aRect1.Width + aRect1.X, aRect1.Height + aRect1.Y );
1299 if( aRect2.IsInside( Point( rPoint.X, rPoint.Y ) ) )
1300 return nIndex;
1301 else
1302 return -1;
1304 catch (const lang::IndexOutOfBoundsException&)
1306 // #103927# Don't throw for invalid nIndex values
1307 return -1;
1310 else
1312 // not within our paragraph
1313 return -1;
1317 OUString SAL_CALL AccessibleEditableTextPara::getSelectedText() throw (uno::RuntimeException)
1319 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1321 SolarMutexGuard aGuard;
1323 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1324 "AccessibleEditableTextPara::getSelectedText: index value overflow");
1326 if( !HaveEditView() )
1327 return OUString();
1329 return OCommonAccessibleText::getSelectedText();
1332 sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart() throw (uno::RuntimeException)
1334 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1336 SolarMutexGuard aGuard;
1338 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1339 "AccessibleEditableTextPara::getSelectionStart: index value overflow");
1341 if( !HaveEditView() )
1342 return -1;
1344 return OCommonAccessibleText::getSelectionStart();
1347 sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd() throw (uno::RuntimeException)
1349 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1351 SolarMutexGuard aGuard;
1353 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1354 "AccessibleEditableTextPara::getSelectionEnd: index value overflow");
1356 if( !HaveEditView() )
1357 return -1;
1359 return OCommonAccessibleText::getSelectionEnd();
1362 sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1364 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1366 SolarMutexGuard aGuard;
1368 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1369 "AccessibleEditableTextPara::setSelection: paragraph index value overflow");
1371 CheckRange(nStartIndex, nEndIndex);
1375 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
1376 return rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
1378 catch (const uno::RuntimeException&)
1380 return sal_False;
1384 OUString SAL_CALL AccessibleEditableTextPara::getText() throw (uno::RuntimeException)
1386 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1388 SolarMutexGuard aGuard;
1390 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1391 "AccessibleEditableTextPara::getText: paragraph index value overflow");
1393 return OCommonAccessibleText::getText();
1396 OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1398 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1400 SolarMutexGuard aGuard;
1402 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1403 "AccessibleEditableTextPara::getTextRange: paragraph index value overflow");
1405 return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex);
1408 ::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)
1410 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1412 SolarMutexGuard aGuard;
1414 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1415 "AccessibleEditableTextPara::getTextAtIndex: paragraph index value overflow");
1417 ::com::sun::star::accessibility::TextSegment aResult;
1418 aResult.SegmentStart = -1;
1419 aResult.SegmentEnd = -1;
1421 switch( aTextType )
1423 // Not yet handled by OCommonAccessibleText. Missing
1424 // implGetAttributeRunBoundary() method there
1425 case AccessibleTextType::ATTRIBUTE_RUN:
1427 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( GetParagraphIndex() );
1429 if( nIndex == nTextLen )
1431 // #i17014# Special-casing one-behind-the-end character
1432 aResult.SegmentStart = aResult.SegmentEnd = nTextLen;
1434 else
1436 sal_uInt16 nStartIndex, nEndIndex;
1438 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
1440 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1441 aResult.SegmentStart = nStartIndex;
1442 aResult.SegmentEnd = nEndIndex;
1445 break;
1448 default:
1449 aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
1450 break;
1451 } /* end of switch( aTextType ) */
1453 return aResult;
1456 ::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)
1458 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1460 SolarMutexGuard aGuard;
1462 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1463 "AccessibleEditableTextPara::getTextBeforeIndex: paragraph index value overflow");
1465 ::com::sun::star::accessibility::TextSegment aResult;
1466 aResult.SegmentStart = -1;
1467 aResult.SegmentEnd = -1;
1469 switch( aTextType )
1471 // Not yet handled by OCommonAccessibleText. Missing
1472 // implGetAttributeRunBoundary() method there
1473 case AccessibleTextType::ATTRIBUTE_RUN:
1475 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( GetParagraphIndex() );
1476 sal_uInt16 nStartIndex, nEndIndex;
1478 if( nIndex == nTextLen )
1480 // #i17014# Special-casing one-behind-the-end character
1481 if( nIndex > 0 &&
1482 GetAttributeRun(nStartIndex, nEndIndex, nIndex-1) )
1484 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1485 aResult.SegmentStart = nStartIndex;
1486 aResult.SegmentEnd = nEndIndex;
1489 else
1491 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
1493 // already at the left border? If not, query
1494 // one index further left
1495 if( nStartIndex > 0 &&
1496 GetAttributeRun(nStartIndex, nEndIndex, nStartIndex-1) )
1498 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1499 aResult.SegmentStart = nStartIndex;
1500 aResult.SegmentEnd = nEndIndex;
1504 break;
1507 default:
1508 aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
1509 break;
1510 } /* end of switch( aTextType ) */
1512 return aResult;
1515 ::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)
1517 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1519 SolarMutexGuard aGuard;
1521 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1522 "AccessibleEditableTextPara::getTextBehindIndex: paragraph index value overflow");
1524 ::com::sun::star::accessibility::TextSegment aResult;
1525 aResult.SegmentStart = -1;
1526 aResult.SegmentEnd = -1;
1528 switch( aTextType )
1530 case AccessibleTextType::ATTRIBUTE_RUN:
1532 sal_uInt16 nStartIndex, nEndIndex;
1534 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
1536 // already at the right border?
1537 if( nEndIndex < GetTextLen() )
1539 if( GetAttributeRun(nStartIndex, nEndIndex, nEndIndex) )
1541 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1542 aResult.SegmentStart = nStartIndex;
1543 aResult.SegmentEnd = nEndIndex;
1547 break;
1550 default:
1551 aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
1552 break;
1553 } /* end of switch( aTextType ) */
1555 return aResult;
1558 sal_Bool SAL_CALL AccessibleEditableTextPara::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1560 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1562 SolarMutexGuard aGuard;
1566 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
1567 #if OSL_DEBUG_LEVEL > 0
1568 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1569 (void)rCacheTF;
1570 #else
1571 GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1572 #endif
1574 sal_Bool aRetVal;
1576 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1577 "AccessibleEditableTextPara::copyText: index value overflow");
1579 CheckRange(nStartIndex, nEndIndex);
1581 // save current selection
1582 ESelection aOldSelection;
1584 rCacheVF.GetSelection( aOldSelection );
1585 rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
1586 aRetVal = rCacheVF.Copy();
1587 rCacheVF.SetSelection( aOldSelection ); // restore
1589 return aRetVal;
1591 catch (const uno::RuntimeException&)
1593 return sal_False;
1597 // XAccessibleEditableText
1598 sal_Bool SAL_CALL AccessibleEditableTextPara::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1600 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1602 SolarMutexGuard aGuard;
1606 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
1607 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1609 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1610 "AccessibleEditableTextPara::cutText: index value overflow");
1612 CheckRange(nStartIndex, nEndIndex);
1614 if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
1615 return sal_False; // non-editable area selected
1617 // don't save selection, might become invalid after cut!
1618 rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
1620 return rCacheVF.Cut();
1622 catch (const uno::RuntimeException&)
1624 return sal_False;
1628 sal_Bool SAL_CALL AccessibleEditableTextPara::pasteText( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1630 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1632 SolarMutexGuard aGuard;
1636 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
1637 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1639 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1640 "AccessibleEditableTextPara::pasteText: index value overflow");
1642 CheckPosition(nIndex);
1644 if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) )
1645 return sal_False; // non-editable area selected
1647 // #104400# set empty selection (=> cursor) to given index
1648 rCacheVF.SetSelection( MakeCursor(nIndex) );
1650 return rCacheVF.Paste();
1652 catch (const uno::RuntimeException&)
1654 return sal_False;
1658 sal_Bool SAL_CALL AccessibleEditableTextPara::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1660 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1662 SolarMutexGuard aGuard;
1666 // #102710# Request edit view when doing changes
1667 // AccessibleEmptyEditSource relies on this behaviour
1668 GetEditViewForwarder( sal_True );
1669 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1671 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1672 "AccessibleEditableTextPara::deleteText: index value overflow");
1674 CheckRange(nStartIndex, nEndIndex);
1676 if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
1677 return sal_False; // non-editable area selected
1679 sal_Bool bRet = rCacheTF.Delete( MakeSelection(nStartIndex, nEndIndex) );
1681 GetEditSource().UpdateData();
1683 return bRet;
1685 catch (const uno::RuntimeException&)
1687 return sal_False;
1691 sal_Bool SAL_CALL AccessibleEditableTextPara::insertText( const OUString& sText, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1693 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1695 SolarMutexGuard aGuard;
1699 // #102710# Request edit view when doing changes
1700 // AccessibleEmptyEditSource relies on this behaviour
1701 GetEditViewForwarder( sal_True );
1702 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1704 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1705 "AccessibleEditableTextPara::insertText: index value overflow");
1707 CheckPosition(nIndex);
1709 if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) )
1710 return sal_False; // non-editable area selected
1712 // #104400# insert given text at empty selection (=> cursor)
1713 sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex) );
1715 rCacheTF.QuickFormatDoc();
1716 GetEditSource().UpdateData();
1718 return bRet;
1720 catch (const uno::RuntimeException&)
1722 return sal_False;
1726 sal_Bool SAL_CALL AccessibleEditableTextPara::replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const OUString& sReplacement ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1728 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1730 SolarMutexGuard aGuard;
1734 // #102710# Request edit view when doing changes
1735 // AccessibleEmptyEditSource relies on this behaviour
1736 GetEditViewForwarder( sal_True );
1737 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1739 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1740 "AccessibleEditableTextPara::replaceText: index value overflow");
1742 CheckRange(nStartIndex, nEndIndex);
1744 if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
1745 return sal_False; // non-editable area selected
1747 // insert given text into given range => replace
1748 sal_Bool bRet = rCacheTF.InsertText( sReplacement, MakeSelection(nStartIndex, nEndIndex) );
1750 rCacheTF.QuickFormatDoc();
1751 GetEditSource().UpdateData();
1753 return bRet;
1755 catch (const uno::RuntimeException&)
1757 return sal_False;
1761 sal_Bool SAL_CALL AccessibleEditableTextPara::setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const uno::Sequence< beans::PropertyValue >& aAttributeSet ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1763 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1765 SolarMutexGuard aGuard;
1769 // #102710# Request edit view when doing changes
1770 // AccessibleEmptyEditSource relies on this behaviour
1771 GetEditViewForwarder( sal_True );
1772 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1773 sal_uInt16 nPara = static_cast< sal_uInt16 >( GetParagraphIndex() );
1775 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1776 "AccessibleEditableTextPara::setAttributes: index value overflow");
1778 CheckRange(nStartIndex, nEndIndex);
1780 if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
1781 return sal_False; // non-editable area selected
1783 // do the indices span the whole paragraph? Then use the outliner map
1784 // TODO: hold it as a member?
1785 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
1786 0 == nStartIndex &&
1787 rCacheTF.GetTextLen(nPara) == nEndIndex ?
1788 ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() :
1789 ImplGetSvxTextPortionSvxPropertySet() );
1791 aPropSet.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
1793 // convert from PropertyValue to Any
1794 sal_Int32 i, nLength( aAttributeSet.getLength() );
1795 const beans::PropertyValue* pPropArray = aAttributeSet.getConstArray();
1796 for(i=0; i<nLength; ++i)
1800 aPropSet.setPropertyValue(pPropArray->Name, pPropArray->Value);
1802 catch (const uno::Exception&)
1804 OSL_FAIL("AccessibleEditableTextPara::setAttributes exception in setPropertyValue");
1807 ++pPropArray;
1810 rCacheTF.QuickFormatDoc();
1811 GetEditSource().UpdateData();
1813 return sal_True;
1815 catch (const uno::RuntimeException&)
1817 return sal_False;
1821 sal_Bool SAL_CALL AccessibleEditableTextPara::setText( const OUString& sText ) throw (uno::RuntimeException)
1823 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1825 SolarMutexGuard aGuard;
1827 return replaceText(0, getCharacterCount(), sText);
1830 // XAccessibleTextAttributes
1831 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getDefaultAttributes(
1832 const uno::Sequence< OUString >& rRequestedAttributes )
1833 throw (uno::RuntimeException)
1835 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1836 SolarMutexGuard aGuard;
1838 #if OSL_DEBUG_LEVEL > 0
1839 SvxAccessibleTextAdapter& rCacheTF =
1840 #endif
1841 GetTextForwarder();
1843 #if OSL_DEBUG_LEVEL > 0
1844 (void)rCacheTF;
1845 #endif
1847 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1848 "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
1850 // get XPropertySetInfo for paragraph attributes and
1851 // character attributes that span all the paragraphs text.
1852 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
1853 ImplGetSvxCharAndParaPropertiesSet() );
1854 aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) );
1855 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo();
1856 if (!xPropSetInfo.is())
1857 throw uno::RuntimeException("Cannot query XPropertySetInfo",
1858 uno::Reference< uno::XInterface >
1859 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
1861 // build sequence of available properties to check
1862 sal_Int32 nLenReqAttr = rRequestedAttributes.getLength();
1863 uno::Sequence< beans::Property > aProperties;
1864 if (nLenReqAttr)
1866 const OUString *pRequestedAttributes = rRequestedAttributes.getConstArray();
1868 aProperties.realloc( nLenReqAttr );
1869 beans::Property *pProperties = aProperties.getArray();
1870 sal_Int32 nCurLen = 0;
1871 for (sal_Int32 i = 0; i < nLenReqAttr; ++i)
1873 beans::Property aProp;
1876 aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] );
1878 catch (const beans::UnknownPropertyException&)
1880 continue;
1882 pProperties[ nCurLen++ ] = aProp;
1884 aProperties.realloc( nCurLen );
1886 else
1887 aProperties = xPropSetInfo->getProperties();
1889 sal_Int32 nLength = aProperties.getLength();
1890 const beans::Property *pProperties = aProperties.getConstArray();
1892 // build resulting sequence
1893 uno::Sequence< beans::PropertyValue > aOutSequence( nLength );
1894 beans::PropertyValue* pOutSequence = aOutSequence.getArray();
1895 sal_Int32 nOutLen = 0;
1896 for (sal_Int32 i = 0; i < nLength; ++i)
1898 // calling implementation functions:
1899 // _getPropertyState and _getPropertyValue (see below) to provide
1900 // the proper paragraph number when retrieving paragraph attributes
1901 PropertyState eState = aPropSet._getPropertyState( pProperties->Name, mnParagraphIndex );
1902 if ( eState == PropertyState_AMBIGUOUS_VALUE )
1904 OSL_FAIL( "ambiguous property value encountered" );
1907 //if (eState == PropertyState_DIRECT_VALUE)
1908 // per definition all paragraph properties and all character
1909 // properties spanning the whole paragraph should be returned
1910 // and declared as default value
1912 pOutSequence->Name = pProperties->Name;
1913 pOutSequence->Handle = pProperties->Handle;
1914 pOutSequence->Value = aPropSet._getPropertyValue( pProperties->Name, mnParagraphIndex );
1915 pOutSequence->State = PropertyState_DEFAULT_VALUE;
1917 ++pOutSequence;
1918 ++nOutLen;
1920 ++pProperties;
1922 aOutSequence.realloc( nOutLen );
1924 return aOutSequence;
1928 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getRunAttributes(
1929 sal_Int32 nIndex,
1930 const uno::Sequence< OUString >& rRequestedAttributes )
1931 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1933 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1935 SolarMutexGuard aGuard;
1937 #if OSL_DEBUG_LEVEL > 0
1938 SvxAccessibleTextAdapter& rCacheTF =
1939 #endif
1940 GetTextForwarder();
1942 #if OSL_DEBUG_LEVEL > 0
1943 (void)rCacheTF;
1944 #endif
1946 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1947 "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
1949 CheckIndex(nIndex);
1951 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
1952 ImplGetSvxCharAndParaPropertiesSet() );
1953 aPropSet.SetSelection( MakeSelection( nIndex ) );
1954 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo();
1955 if (!xPropSetInfo.is())
1956 throw uno::RuntimeException("Cannot query XPropertySetInfo",
1957 uno::Reference< uno::XInterface >
1958 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
1960 // build sequence of available properties to check
1961 sal_Int32 nLenReqAttr = rRequestedAttributes.getLength();
1962 uno::Sequence< beans::Property > aProperties;
1963 if (nLenReqAttr)
1965 const OUString *pRequestedAttributes = rRequestedAttributes.getConstArray();
1967 aProperties.realloc( nLenReqAttr );
1968 beans::Property *pProperties = aProperties.getArray();
1969 sal_Int32 nCurLen = 0;
1970 for (sal_Int32 i = 0; i < nLenReqAttr; ++i)
1972 beans::Property aProp;
1975 aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] );
1977 catch (const beans::UnknownPropertyException&)
1979 continue;
1981 pProperties[ nCurLen++ ] = aProp;
1983 aProperties.realloc( nCurLen );
1985 else
1986 aProperties = xPropSetInfo->getProperties();
1988 sal_Int32 nLength = aProperties.getLength();
1989 const beans::Property *pProperties = aProperties.getConstArray();
1991 // build resulting sequence
1992 uno::Sequence< beans::PropertyValue > aOutSequence( nLength );
1993 beans::PropertyValue* pOutSequence = aOutSequence.getArray();
1994 sal_Int32 nOutLen = 0;
1995 for (sal_Int32 i = 0; i < nLength; ++i)
1997 // calling 'regular' functions that will operate on the selection
1998 PropertyState eState = aPropSet.getPropertyState( pProperties->Name );
1999 if (eState == PropertyState_DIRECT_VALUE)
2001 pOutSequence->Name = pProperties->Name;
2002 pOutSequence->Handle = pProperties->Handle;
2003 pOutSequence->Value = aPropSet.getPropertyValue( pProperties->Name );
2004 pOutSequence->State = eState;
2006 ++pOutSequence;
2007 ++nOutLen;
2009 ++pProperties;
2011 aOutSequence.realloc( nOutLen );
2013 return aOutSequence;
2016 // XAccessibleHypertext
2017 ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkCount( ) throw (::com::sun::star::uno::RuntimeException)
2019 SvxAccessibleTextAdapter& rT = GetTextForwarder();
2020 const sal_Int32 nPara = GetParagraphIndex();
2022 sal_uInt16 nHyperLinks = 0;
2023 sal_uInt16 nFields = rT.GetFieldCount( nPara );
2024 for ( sal_uInt16 n = 0; n < nFields; n++ )
2026 EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2027 if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2028 nHyperLinks++;
2030 return nHyperLinks;
2033 ::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)
2035 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleHyperlink > xRef;
2037 SvxAccessibleTextAdapter& rT = GetTextForwarder();
2038 const sal_Int32 nPara = GetParagraphIndex();
2040 sal_uInt16 nHyperLink = 0;
2041 sal_uInt16 nFields = rT.GetFieldCount( nPara );
2042 for ( sal_uInt16 n = 0; n < nFields; n++ )
2044 EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2045 if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2047 if ( nHyperLink == nLinkIndex )
2049 sal_uInt16 nEEStart = aField.aPosition.nIndex;
2051 // Translate EE Index to accessible index
2052 sal_uInt16 nStart = rT.CalcEditEngineIndex( nPara, nEEStart );
2053 sal_uInt16 nEnd = nStart + aField.aCurrentText.Len();
2054 xRef = new AccessibleHyperlink( rT, new SvxFieldItem( *aField.pFieldItem ), nPara, nEEStart, nStart, nEnd, aField.aCurrentText );
2055 break;
2057 nHyperLink++;
2061 return xRef;
2064 ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkIndex( ::sal_Int32 nCharIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
2066 const sal_Int32 nPara = GetParagraphIndex();
2067 SvxAccessibleTextAdapter& rT = GetTextForwarder();
2069 // SvxAccessibleTextIndex aIndex;
2070 // aIndex.SetIndex(nPara, nCharIndex, rT);
2071 // const sal_uInt16 nEEIndex = aIndex.GetEEIndex();
2073 const sal_uInt16 nEEIndex = rT.CalcEditEngineIndex( nPara, nCharIndex );
2074 sal_Int32 nHLIndex = 0;
2075 sal_uInt16 nHyperLink = 0;
2076 sal_uInt16 nFields = rT.GetFieldCount( nPara );
2077 for ( sal_uInt16 n = 0; n < nFields; n++ )
2079 EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2080 if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2082 if ( aField.aPosition.nIndex == nEEIndex )
2084 nHLIndex = nHyperLink;
2085 break;
2087 nHyperLink++;
2091 return nHLIndex;
2094 // XAccessibleMultiLineText
2095 sal_Int32 SAL_CALL AccessibleEditableTextPara::getLineNumberAtIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2097 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2099 sal_Int32 nRes = -1;
2100 sal_Int32 nPara = GetParagraphIndex();
2102 SvxTextForwarder &rCacheTF = GetTextForwarder();
2103 const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
2104 DBG_ASSERT( bValidPara, "getLineNumberAtIndex: current paragraph index out of range" );
2105 if (bValidPara)
2107 // we explicitly allow for the index to point at the character right behind the text
2108 if (0 <= nIndex && nIndex <= rCacheTF.GetTextLen( nPara ))
2109 nRes = rCacheTF.GetLineNumberAtIndex( nPara, static_cast< sal_uInt16 >(nIndex) );
2110 else
2111 throw lang::IndexOutOfBoundsException();
2113 return nRes;
2116 // XAccessibleMultiLineText
2117 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineNumber( sal_Int32 nLineNo ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2119 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2121 ::com::sun::star::accessibility::TextSegment aResult;
2122 sal_Int32 nPara = GetParagraphIndex();
2123 SvxTextForwarder &rCacheTF = GetTextForwarder();
2124 const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
2125 DBG_ASSERT( bValidPara, "getTextAtLineNumber: current paragraph index out of range" );
2126 if (bValidPara)
2128 if (0 <= nLineNo && nLineNo < rCacheTF.GetLineCount( nPara ))
2130 sal_uInt16 nStart = 0, nEnd = 0;
2131 rCacheTF.GetLineBoundaries( nStart, nEnd, nPara, static_cast< sal_uInt16 >(nLineNo) );
2132 if (nStart != 0xFFFF && nEnd != 0xFFFF)
2136 aResult.SegmentText = getTextRange( nStart, nEnd );
2137 aResult.SegmentStart = nStart;
2138 aResult.SegmentEnd = nEnd;
2140 catch (const lang::IndexOutOfBoundsException&)
2142 // this is not the exception that should be raised in this function ...
2143 DBG_ASSERT( 0, "unexpected exception" );
2147 else
2148 throw lang::IndexOutOfBoundsException();
2150 return aResult;
2153 // XAccessibleMultiLineText
2154 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineWithCaret( ) throw (uno::RuntimeException)
2156 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2158 ::com::sun::star::accessibility::TextSegment aResult;
2161 aResult = getTextAtLineNumber( getNumberOfLineWithCaret() );
2163 catch (const lang::IndexOutOfBoundsException&)
2165 // this one needs to be catched since this interface does not allow for it.
2167 return aResult;
2170 // XAccessibleMultiLineText
2171 sal_Int32 SAL_CALL AccessibleEditableTextPara::getNumberOfLineWithCaret( ) throw (uno::RuntimeException)
2173 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2175 sal_Int32 nRes = -1;
2178 nRes = getLineNumberAtIndex( getCaretPosition() );
2180 catch (const lang::IndexOutOfBoundsException&)
2182 // this one needs to be catched since this interface does not allow for it.
2184 return nRes;
2188 // XServiceInfo
2189 OUString SAL_CALL AccessibleEditableTextPara::getImplementationName (void) throw (uno::RuntimeException)
2191 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2193 return OUString("AccessibleEditableTextPara");
2196 sal_Bool SAL_CALL AccessibleEditableTextPara::supportsService (const OUString& sServiceName) throw (uno::RuntimeException)
2198 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2200 // Iterate over all supported service names and return true if on of them
2201 // matches the given name.
2202 uno::Sequence< OUString> aSupportedServices (
2203 getSupportedServiceNames ());
2204 for (int i=0; i<aSupportedServices.getLength(); i++)
2205 if (sServiceName == aSupportedServices[i])
2206 return sal_True;
2207 return sal_False;
2210 uno::Sequence< OUString> SAL_CALL AccessibleEditableTextPara::getSupportedServiceNames (void) throw (uno::RuntimeException)
2212 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2214 const OUString sServiceName( getServiceName() );
2215 return uno::Sequence< OUString > (&sServiceName, 1);
2218 // XServiceName
2219 OUString SAL_CALL AccessibleEditableTextPara::getServiceName (void) throw (uno::RuntimeException)
2221 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2223 // #105185# Using correct service now
2224 return OUString("com.sun.star.text.AccessibleParagraphView");
2227 } // end of namespace accessibility
2229 //------------------------------------------------------------------------
2231 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */