Bump for 3.6-28
[LibreOffice.git] / editeng / source / accessibility / AccessibleEditableTextPara.cxx
blob8586dbe28837eafab9157c021cbc51a719c3a111
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 //------------------------------------------------------------------------
32 // Global header
34 //------------------------------------------------------------------------
36 #include <limits.h>
37 #include <vector>
38 #include <algorithm>
39 #include <osl/mutex.hxx>
40 #include <vcl/window.hxx>
41 #include <vcl/svapp.hxx>
42 #include <editeng/flditem.hxx>
43 #include <com/sun/star/uno/Any.hxx>
44 #include <com/sun/star/uno/Reference.hxx>
45 #include <com/sun/star/awt/Point.hpp>
46 #include <com/sun/star/awt/Rectangle.hpp>
47 #include <com/sun/star/lang/DisposedException.hpp>
48 #include <com/sun/star/accessibility/AccessibleRole.hpp>
49 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
50 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
51 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
52 #include <comphelper/accessibleeventnotifier.hxx>
53 #include <comphelper/sequenceashashmap.hxx>
54 #include <unotools/accessiblestatesethelper.hxx>
55 #include <unotools/accessiblerelationsethelper.hxx>
56 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
57 #include <vcl/unohelp.hxx>
58 #include <editeng/editeng.hxx>
59 #include <editeng/unoprnms.hxx>
60 #include <editeng/unoipset.hxx>
61 #include <editeng/outliner.hxx>
63 //------------------------------------------------------------------------
65 // Project-local header
67 //------------------------------------------------------------------------
69 #include <com/sun/star/beans/PropertyState.hpp>
71 //!!!#include <svx/unoshape.hxx>
72 //!!!#include <svx/dialmgr.hxx>
73 //!!!#include "accessibility.hrc"
75 #include <editeng/unolingu.hxx>
76 #include <editeng/unopracc.hxx>
77 #include "editeng/AccessibleEditableTextPara.hxx"
78 #include "AccessibleHyperlink.hxx"
80 #include <svtools/colorcfg.hxx>
83 using namespace ::com::sun::star;
84 using namespace ::com::sun::star::beans;
85 using namespace ::com::sun::star::accessibility;
88 //------------------------------------------------------------------------
90 // AccessibleEditableTextPara implementation
92 //------------------------------------------------------------------------
94 namespace accessibility
97 const SvxItemPropertySet* ImplGetSvxCharAndParaPropertiesSet()
99 // PropertyMap for character and paragraph properties
100 static const SfxItemPropertyMapEntry aPropMap[] =
102 SVX_UNOEDIT_CHAR_PROPERTIES,
103 SVX_UNOEDIT_PARA_PROPERTIES,
104 SVX_UNOEDIT_NUMBERING_PROPERTIE,
105 {MAP_CHAR_LEN("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0},
106 {MAP_CHAR_LEN("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0},
107 {0,0,0,0,0,0}
109 static SvxItemPropertySet aPropSet( aPropMap, EditEngine::GetGlobalItemPool() );
110 return &aPropSet;
114 DBG_NAME( AccessibleEditableTextPara )
116 // #i27138# - add parameter <_pParaManager>
117 AccessibleEditableTextPara::AccessibleEditableTextPara(
118 const uno::Reference< XAccessible >& rParent,
119 const AccessibleParaManager* _pParaManager )
120 : AccessibleTextParaInterfaceBase( m_aMutex ),
121 mnParagraphIndex( 0 ),
122 mnIndexInParent( 0 ),
123 mpEditSource( NULL ),
124 maEEOffset( 0, 0 ),
125 mxParent( rParent ),
126 // well, that's strictly (UNO) exception safe, though not
127 // really robust. We rely on the fact that this member is
128 // constructed last, and that the constructor body catches
129 // exceptions, thus no chance for exceptions once the Id is
130 // fetched. Nevertheless, normally should employ RAII here...
131 mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient()),
132 // #i27138#
133 mpParaManager( _pParaManager )
135 #ifdef DBG_UTIL
136 DBG_CTOR( AccessibleEditableTextPara, NULL );
137 OSL_TRACE( "AccessibleEditableTextPara received ID: %d", mnNotifierClientId );
138 #endif
142 // Create the state set.
143 ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper ();
144 mxStateSet = pStateSet;
146 // these are always on
147 pStateSet->AddState( AccessibleStateType::MULTI_LINE );
148 pStateSet->AddState( AccessibleStateType::FOCUSABLE );
149 pStateSet->AddState( AccessibleStateType::VISIBLE );
150 pStateSet->AddState( AccessibleStateType::SHOWING );
151 pStateSet->AddState( AccessibleStateType::ENABLED );
152 pStateSet->AddState( AccessibleStateType::SENSITIVE );
154 catch (const uno::Exception&)
159 AccessibleEditableTextPara::~AccessibleEditableTextPara()
161 DBG_DTOR( AccessibleEditableTextPara, NULL );
163 // sign off from event notifier
164 if( getNotifierClientId() != -1 )
168 ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() );
169 #ifdef DBG_UTIL
170 OSL_TRACE( "AccessibleEditableTextPara revoked ID: %d", mnNotifierClientId );
171 #endif
173 catch (const uno::Exception&)
179 ::rtl::OUString AccessibleEditableTextPara::implGetText()
181 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
183 return GetTextRange( 0, GetTextLen() );
186 ::com::sun::star::lang::Locale AccessibleEditableTextPara::implGetLocale()
188 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
190 lang::Locale aLocale;
192 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
193 "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
195 // return locale of first character in the paragraph
196 return SvxLanguageToLocale(aLocale, GetTextForwarder().GetLanguage( static_cast< sal_uInt16 >( GetParagraphIndex() ), 0 ));
199 void AccessibleEditableTextPara::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
201 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
203 sal_uInt16 nStart, nEnd;
205 if( GetSelection( nStart, nEnd ) )
207 nStartIndex = nStart;
208 nEndIndex = nEnd;
210 else
212 // #102234# No exception, just set to 'invalid'
213 nStartIndex = -1;
214 nEndIndex = -1;
218 void AccessibleEditableTextPara::implGetParagraphBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 /*nIndex*/ )
220 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
221 DBG_WARNING( "AccessibleEditableTextPara::implGetParagraphBoundary: only a base implementation, ignoring the index" );
223 rBoundary.startPos = 0;
224 rBoundary.endPos = GetTextLen();
227 void AccessibleEditableTextPara::implGetLineBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex )
229 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
231 SvxTextForwarder& rCacheTF = GetTextForwarder();
232 const sal_Int32 nParaIndex = GetParagraphIndex();
234 DBG_ASSERT(nParaIndex >= 0 && nParaIndex <= USHRT_MAX,
235 "AccessibleEditableTextPara::implGetLineBoundary: paragraph index value overflow");
237 const sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< sal_uInt16 >( nParaIndex ) );
239 CheckPosition(nIndex);
241 rBoundary.startPos = rBoundary.endPos = -1;
243 const sal_uInt16 nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) );
245 if( nIndex == nTextLen )
247 // #i17014# Special-casing one-behind-the-end character
248 if( nLineCount <= 1 )
249 rBoundary.startPos = 0;
250 else
251 rBoundary.startPos = nTextLen - rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ),
252 nLineCount-1 );
254 rBoundary.endPos = nTextLen;
256 else
258 // normal line search
259 sal_uInt16 nLine;
260 sal_Int32 nCurIndex;
261 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
263 nCurIndex += rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine);
265 if( nCurIndex > nIndex )
267 rBoundary.startPos = nCurIndex - rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine);
268 rBoundary.endPos = nCurIndex;
269 break;
275 int AccessibleEditableTextPara::getNotifierClientId() const
277 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
279 return mnNotifierClientId;
282 void AccessibleEditableTextPara::SetIndexInParent( sal_Int32 nIndex )
284 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
286 mnIndexInParent = nIndex;
289 sal_Int32 AccessibleEditableTextPara::GetIndexInParent() const
291 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
293 return mnIndexInParent;
296 void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex )
298 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
300 sal_Int32 nOldIndex = mnParagraphIndex;
302 mnParagraphIndex = nIndex;
304 WeakBullet::HardRefType aChild( maImageBullet.get() );
305 if( aChild.is() )
306 aChild->SetParagraphIndex(mnParagraphIndex);
310 if( nOldIndex != nIndex )
312 uno::Any aOldDesc;
313 uno::Any aOldName;
317 aOldDesc <<= getAccessibleDescription();
318 aOldName <<= getAccessibleName();
320 catch (const uno::Exception&) // optional behaviour
323 // index and therefore description changed
324 FireEvent( AccessibleEventId::DESCRIPTION_CHANGED, uno::makeAny( getAccessibleDescription() ), aOldDesc );
325 FireEvent( AccessibleEventId::NAME_CHANGED, uno::makeAny( getAccessibleName() ), aOldName );
328 catch (const uno::Exception&) // optional behaviour
333 sal_Int32 AccessibleEditableTextPara::GetParagraphIndex() const SAL_THROW((uno::RuntimeException))
335 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
337 return mnParagraphIndex;
340 void AccessibleEditableTextPara::Dispose()
342 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
344 int nClientId( getNotifierClientId() );
346 // #108212# drop all references before notifying dispose
347 mxParent = NULL;
348 mnNotifierClientId = -1;
349 mpEditSource = NULL;
351 // notify listeners
352 if( nClientId != -1 )
356 uno::Reference < XAccessibleContext > xThis = getAccessibleContext();
358 // #106234# Delegate to EventNotifier
359 ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, xThis );
360 #ifdef DBG_UTIL
361 OSL_TRACE( "Disposed ID: %d", nClientId );
362 #endif
364 catch (const uno::Exception&)
370 void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter* pEditSource )
372 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
374 mpEditSource = pEditSource;
376 WeakBullet::HardRefType aChild( maImageBullet.get() );
377 if( aChild.is() )
378 aChild->SetEditSource(pEditSource);
380 if( !mpEditSource )
382 // going defunc
383 UnSetState( AccessibleStateType::SHOWING );
384 UnSetState( AccessibleStateType::VISIBLE );
385 SetState( AccessibleStateType::INVALID );
386 SetState( AccessibleStateType::DEFUNC );
388 Dispose();
391 // #108900# Init last text content
394 TextChanged();
396 catch (const uno::RuntimeException&)
401 ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex )
403 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
405 // check overflow
406 DBG_ASSERT(nStartEEIndex >= 0 && nStartEEIndex <= USHRT_MAX &&
407 nEndEEIndex >= 0 && nEndEEIndex <= USHRT_MAX &&
408 GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
409 "AccessibleEditableTextPara::MakeSelection: index value overflow");
411 sal_uInt16 nParaIndex = static_cast< sal_uInt16 >( GetParagraphIndex() );
412 return ESelection( nParaIndex, static_cast< sal_uInt16 >( nStartEEIndex ),
413 nParaIndex, static_cast< sal_uInt16 >( nEndEEIndex ) );
416 ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nEEIndex )
418 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
420 return MakeSelection( nEEIndex, nEEIndex+1 );
423 ESelection AccessibleEditableTextPara::MakeCursor( sal_Int32 nEEIndex )
425 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
427 return MakeSelection( nEEIndex, nEEIndex );
430 void AccessibleEditableTextPara::CheckIndex( sal_Int32 nIndex ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
432 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
434 if( nIndex < 0 || nIndex >= getCharacterCount() )
435 throw lang::IndexOutOfBoundsException(::rtl::OUString("AccessibleEditableTextPara: character index out of bounds"),
436 uno::Reference< uno::XInterface >
437 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy
440 void AccessibleEditableTextPara::CheckPosition( sal_Int32 nIndex ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
442 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
444 if( nIndex < 0 || nIndex > getCharacterCount() )
445 throw lang::IndexOutOfBoundsException(::rtl::OUString("AccessibleEditableTextPara: character position out of bounds"),
446 uno::Reference< uno::XInterface >
447 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy
450 void AccessibleEditableTextPara::CheckRange( sal_Int32 nStart, sal_Int32 nEnd ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
452 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
454 CheckPosition( nStart );
455 CheckPosition( nEnd );
458 sal_Bool AccessibleEditableTextPara::GetSelection( sal_uInt16& nStartPos, sal_uInt16& nEndPos ) SAL_THROW((uno::RuntimeException))
460 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
462 ESelection aSelection;
463 sal_uInt16 nPara = static_cast< sal_uInt16 > ( GetParagraphIndex() );
464 if( !GetEditViewForwarder().GetSelection( aSelection ) )
465 return sal_False;
467 if( aSelection.nStartPara < aSelection.nEndPara )
469 if( aSelection.nStartPara > nPara ||
470 aSelection.nEndPara < nPara )
471 return sal_False;
473 if( nPara == aSelection.nStartPara )
474 nStartPos = aSelection.nStartPos;
475 else
476 nStartPos = 0;
478 if( nPara == aSelection.nEndPara )
479 nEndPos = aSelection.nEndPos;
480 else
481 nEndPos = GetTextLen();
483 else
485 if( aSelection.nStartPara < nPara ||
486 aSelection.nEndPara > nPara )
487 return sal_False;
489 if( nPara == aSelection.nStartPara )
490 nStartPos = aSelection.nStartPos;
491 else
492 nStartPos = GetTextLen();
494 if( nPara == aSelection.nEndPara )
495 nEndPos = aSelection.nEndPos;
496 else
497 nEndPos = 0;
500 return sal_True;
503 String AccessibleEditableTextPara::GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) SAL_THROW((uno::RuntimeException))
505 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
507 return GetTextForwarder().GetText( MakeSelection(nStartIndex, nEndIndex) );
510 sal_uInt16 AccessibleEditableTextPara::GetTextLen() const SAL_THROW((uno::RuntimeException))
512 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
514 return GetTextForwarder().GetTextLen( static_cast< sal_uInt16 >( GetParagraphIndex() ) );
517 SvxEditSourceAdapter& AccessibleEditableTextPara::GetEditSource() const SAL_THROW((uno::RuntimeException))
519 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
521 if( mpEditSource )
522 return *mpEditSource;
523 else
524 throw uno::RuntimeException(::rtl::OUString("No edit source, object is defunct"),
525 uno::Reference< uno::XInterface >
526 ( static_cast< ::cppu::OWeakObject* >
527 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
530 SvxAccessibleTextAdapter& AccessibleEditableTextPara::GetTextForwarder() const SAL_THROW((uno::RuntimeException))
532 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
534 SvxEditSourceAdapter& rEditSource = GetEditSource();
535 SvxAccessibleTextAdapter* pTextForwarder = rEditSource.GetTextForwarderAdapter();
537 if( !pTextForwarder )
538 throw uno::RuntimeException(::rtl::OUString("Unable to fetch text forwarder, object is defunct"),
539 uno::Reference< uno::XInterface >
540 ( static_cast< ::cppu::OWeakObject* >
541 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
543 if( pTextForwarder->IsValid() )
544 return *pTextForwarder;
545 else
546 throw uno::RuntimeException(::rtl::OUString("Text forwarder is invalid, object is defunct"),
547 uno::Reference< uno::XInterface >
548 ( static_cast< ::cppu::OWeakObject* >
549 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
552 SvxViewForwarder& AccessibleEditableTextPara::GetViewForwarder() const SAL_THROW((uno::RuntimeException))
554 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
556 SvxEditSource& rEditSource = GetEditSource();
557 SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder();
559 if( !pViewForwarder )
561 throw uno::RuntimeException(::rtl::OUString("Unable to fetch view forwarder, object is defunct"),
562 uno::Reference< uno::XInterface >
563 ( static_cast< ::cppu::OWeakObject* >
564 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
567 if( pViewForwarder->IsValid() )
568 return *pViewForwarder;
569 else
570 throw uno::RuntimeException(::rtl::OUString("View forwarder is invalid, object is defunct"),
571 uno::Reference< uno::XInterface >
572 ( static_cast< ::cppu::OWeakObject* >
573 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
576 SvxAccessibleTextEditViewAdapter& AccessibleEditableTextPara::GetEditViewForwarder( sal_Bool bCreate ) const SAL_THROW((uno::RuntimeException))
578 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
580 SvxEditSourceAdapter& rEditSource = GetEditSource();
581 SvxAccessibleTextEditViewAdapter* pTextEditViewForwarder = rEditSource.GetEditViewForwarderAdapter( bCreate );
583 if( !pTextEditViewForwarder )
585 if( bCreate )
586 throw uno::RuntimeException(::rtl::OUString("Unable to fetch view forwarder, object is defunct"),
587 uno::Reference< uno::XInterface >
588 ( static_cast< ::cppu::OWeakObject* >
589 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
590 else
591 throw uno::RuntimeException(::rtl::OUString("No view forwarder, object not in edit mode"),
592 uno::Reference< uno::XInterface >
593 ( static_cast< ::cppu::OWeakObject* >
594 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
597 if( pTextEditViewForwarder->IsValid() )
598 return *pTextEditViewForwarder;
599 else
601 if( bCreate )
602 throw uno::RuntimeException(::rtl::OUString("View forwarder is invalid, object is defunct"),
603 uno::Reference< uno::XInterface >
604 ( static_cast< ::cppu::OWeakObject* >
605 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
606 else
607 throw uno::RuntimeException(::rtl::OUString("View forwarder is invalid, object not in edit mode"),
608 uno::Reference< uno::XInterface >
609 ( static_cast< ::cppu::OWeakObject* >
610 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy
614 sal_Bool AccessibleEditableTextPara::HaveEditView() const
616 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
618 SvxEditSource& rEditSource = GetEditSource();
619 SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder();
621 if( !pViewForwarder )
622 return sal_False;
624 if( !pViewForwarder->IsValid() )
625 return sal_False;
627 return sal_True;
630 sal_Bool AccessibleEditableTextPara::HaveChildren()
632 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
634 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
635 "AccessibleEditableTextPara::HaveChildren: paragraph index value overflow");
637 return GetTextForwarder().HaveImageBullet( static_cast< sal_uInt16 >(GetParagraphIndex()) );
640 Rectangle AccessibleEditableTextPara::LogicToPixel( const Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder& rForwarder )
642 // convert to screen coordinates
643 return Rectangle( rForwarder.LogicToPixel( rRect.TopLeft(), rMapMode ),
644 rForwarder.LogicToPixel( rRect.BottomRight(), rMapMode ) );
647 const Point& AccessibleEditableTextPara::GetEEOffset() const
649 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
651 return maEEOffset;
654 void AccessibleEditableTextPara::SetEEOffset( const Point& rOffset )
656 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
658 WeakBullet::HardRefType aChild( maImageBullet.get() );
659 if( aChild.is() )
660 aChild->SetEEOffset(rOffset);
662 maEEOffset = rOffset;
665 void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue) const
667 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
669 uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleEditableTextPara* > (this)->getAccessibleContext() );
671 AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue);
673 // #102261# Call global queue for focus events
674 if( nEventId == AccessibleEventId::STATE_CHANGED )
675 vcl::unohelper::NotifyAccessibleStateEventGlobally( aEvent );
677 // #106234# Delegate to EventNotifier
678 if( getNotifierClientId() != -1 )
679 ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(),
680 aEvent );
683 void AccessibleEditableTextPara::GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const
685 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
687 FireEvent( nEventId, rNewValue );
690 void AccessibleEditableTextPara::LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const
692 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
694 FireEvent( nEventId, uno::Any(), rOldValue );
697 void AccessibleEditableTextPara::SetState( const sal_Int16 nStateId )
699 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
701 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
702 if( pStateSet != NULL &&
703 !pStateSet->contains(nStateId) )
705 pStateSet->AddState( nStateId );
706 GotPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED );
710 void AccessibleEditableTextPara::UnSetState( const sal_Int16 nStateId )
712 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
714 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
715 if( pStateSet != NULL &&
716 pStateSet->contains(nStateId) )
718 pStateSet->RemoveState( nStateId );
719 LostPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED );
723 void AccessibleEditableTextPara::TextChanged()
725 ::rtl::OUString aCurrentString( OCommonAccessibleText::getText() );
726 uno::Any aDeleted;
727 uno::Any aInserted;
728 if( OCommonAccessibleText::implInitTextChangedEvent( maLastTextString, aCurrentString,
729 aDeleted, aInserted) )
731 FireEvent( AccessibleEventId::TEXT_CHANGED, aInserted, aDeleted );
732 maLastTextString = aCurrentString;
736 sal_Bool AccessibleEditableTextPara::GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, sal_Int32 nIndex )
738 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
740 DBG_ASSERT(nIndex >= 0 && nIndex <= USHRT_MAX,
741 "AccessibleEditableTextPara::GetAttributeRun: index value overflow");
743 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
744 "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
746 return GetTextForwarder().GetAttributeRun( nStartIndex,
747 nEndIndex,
748 static_cast< sal_uInt16 >(GetParagraphIndex()),
749 static_cast< sal_uInt16 >(nIndex) );
752 uno::Any SAL_CALL AccessibleEditableTextPara::queryInterface (const uno::Type & rType) throw (uno::RuntimeException)
754 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
756 uno::Any aRet;
758 // must provide XAccesibleText by hand, since it comes publicly inherited by XAccessibleEditableText
759 if ( rType == ::getCppuType((uno::Reference< XAccessibleText > *)0) )
761 uno::Reference< XAccessibleText > aAccText = static_cast< XAccessibleEditableText * >(this);
762 aRet <<= aAccText;
764 else if ( rType == ::getCppuType((uno::Reference< XAccessibleEditableText > *)0) )
766 uno::Reference< XAccessibleEditableText > aAccEditText = this;
767 aRet <<= aAccEditText;
769 else if ( rType == ::getCppuType((uno::Reference< XAccessibleHypertext > *)0) )
771 uno::Reference< XAccessibleHypertext > aAccHyperText = this;
772 aRet <<= aAccHyperText;
774 else
776 aRet = AccessibleTextParaInterfaceBase::queryInterface(rType);
779 return aRet;
782 // XAccessible
783 uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext() throw (uno::RuntimeException)
785 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
787 // We implement the XAccessibleContext interface in the same object
788 return uno::Reference< XAccessibleContext > ( this );
791 // XAccessibleContext
792 sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleChildCount() throw (uno::RuntimeException)
794 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
796 SolarMutexGuard aGuard;
798 return HaveChildren() ? 1 : 0;
801 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
803 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
805 SolarMutexGuard aGuard;
807 if( !HaveChildren() )
808 throw lang::IndexOutOfBoundsException(::rtl::OUString("No children available"),
809 uno::Reference< uno::XInterface >
810 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy
812 if( i != 0 )
813 throw lang::IndexOutOfBoundsException(::rtl::OUString("Invalid child index"),
814 uno::Reference< uno::XInterface >
815 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy
817 WeakBullet::HardRefType aChild( maImageBullet.get() );
819 if( !aChild.is() )
821 // there is no hard reference available, create object then
822 AccessibleImageBullet* pChild = new AccessibleImageBullet( uno::Reference< XAccessible >( this ) );
823 uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY );
825 if( !xChild.is() )
826 throw uno::RuntimeException(::rtl::OUString("Child creation failed"),
827 uno::Reference< uno::XInterface >
828 ( static_cast< ::cppu::OWeakObject* > (this) ) );
830 aChild = WeakBullet::HardRefType( xChild, pChild );
832 aChild->SetEditSource( &GetEditSource() );
833 aChild->SetParagraphIndex( GetParagraphIndex() );
834 aChild->SetIndexInParent( i );
836 maImageBullet = aChild;
839 return aChild.getRef();
842 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleParent() throw (uno::RuntimeException)
844 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
846 #ifdef DBG_UTIL
847 if( !mxParent.is() )
848 OSL_TRACE( "AccessibleEditableTextPara::getAccessibleParent: no frontend set, did somebody forgot to call AccessibleTextHelper::SetEventSource()?");
849 #endif
851 return mxParent;
854 sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleIndexInParent() throw (uno::RuntimeException)
856 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
858 return mnIndexInParent;
861 sal_Int16 SAL_CALL AccessibleEditableTextPara::getAccessibleRole() throw (uno::RuntimeException)
863 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
865 return AccessibleRole::PARAGRAPH;
868 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleDescription() throw (uno::RuntimeException)
870 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
872 // SolarMutexGuard aGuard;
874 return ::rtl::OUString();
877 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleName() throw (uno::RuntimeException)
879 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
881 // SolarMutexGuard aGuard;
883 return ::rtl::OUString();
886 uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleEditableTextPara::getAccessibleRelationSet() throw (uno::RuntimeException)
888 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
890 // #i27138# - provide relations CONTENT_FLOWS_FROM
891 // and CONTENT_FLOWS_TO
892 if ( mpParaManager )
894 utl::AccessibleRelationSetHelper* pAccRelSetHelper =
895 new utl::AccessibleRelationSetHelper();
896 sal_Int32 nMyParaIndex( GetParagraphIndex() );
897 // relation CONTENT_FLOWS_FROM
898 if ( nMyParaIndex > 0 &&
899 mpParaManager->IsReferencable( nMyParaIndex - 1 ) )
901 uno::Sequence<uno::Reference<XInterface> > aSequence(1);
902 aSequence[0] =
903 mpParaManager->GetChild( nMyParaIndex - 1 ).first.get().getRef();
904 AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM,
905 aSequence );
906 pAccRelSetHelper->AddRelation( aAccRel );
909 // relation CONTENT_FLOWS_TO
910 if ( (nMyParaIndex + 1) < (sal_Int32)mpParaManager->GetNum() &&
911 mpParaManager->IsReferencable( nMyParaIndex + 1 ) )
913 uno::Sequence<uno::Reference<XInterface> > aSequence(1);
914 aSequence[0] =
915 mpParaManager->GetChild( nMyParaIndex + 1 ).first.get().getRef();
916 AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO,
917 aSequence );
918 pAccRelSetHelper->AddRelation( aAccRel );
921 return pAccRelSetHelper;
923 else
925 // no relations, therefore empty
926 return uno::Reference< XAccessibleRelationSet >();
930 uno::Reference< XAccessibleStateSet > SAL_CALL AccessibleEditableTextPara::getAccessibleStateSet() throw (uno::RuntimeException)
932 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
934 SolarMutexGuard aGuard;
936 // Create a copy of the state set and return it.
937 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
939 if( !pStateSet )
940 return uno::Reference<XAccessibleStateSet>();
942 return uno::Reference<XAccessibleStateSet>( new ::utl::AccessibleStateSetHelper (*pStateSet) );
945 lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale() throw (IllegalAccessibleComponentStateException, uno::RuntimeException)
947 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
949 SolarMutexGuard aGuard;
951 return implGetLocale();
954 void SAL_CALL AccessibleEditableTextPara::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException)
956 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
958 if( getNotifierClientId() != -1 )
959 ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener );
962 void SAL_CALL AccessibleEditableTextPara::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException)
964 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
966 if( getNotifierClientId() != -1 )
967 ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener );
970 // XAccessibleComponent
971 sal_Bool SAL_CALL AccessibleEditableTextPara::containsPoint( const awt::Point& aTmpPoint ) throw (uno::RuntimeException)
973 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
975 SolarMutexGuard aGuard;
977 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
978 "AccessibleEditableTextPara::contains: index value overflow");
980 awt::Rectangle aTmpRect = getBounds();
981 Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) );
982 Point aPoint( aTmpPoint.X, aTmpPoint.Y );
984 return aRect.IsInside( aPoint );
987 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point& _aPoint ) throw (uno::RuntimeException)
989 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
991 SolarMutexGuard aGuard;
993 if( HaveChildren() )
995 // #103862# No longer need to make given position relative
996 Point aPoint( _aPoint.X, _aPoint.Y );
998 // respect EditEngine offset to surrounding shape/cell
999 aPoint -= GetEEOffset();
1001 // convert to EditEngine coordinate system
1002 SvxTextForwarder& rCacheTF = GetTextForwarder();
1003 Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
1005 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 > (GetParagraphIndex()) );
1007 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
1008 aBulletInfo.bVisible &&
1009 aBulletInfo.nType == SVX_NUM_BITMAP )
1011 Rectangle aRect = aBulletInfo.aBounds;
1013 if( aRect.IsInside( aLogPoint ) )
1014 return getAccessibleChild(0);
1018 // no children at all, or none at given position
1019 return uno::Reference< XAccessible >();
1022 awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds() throw (uno::RuntimeException)
1024 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1026 SolarMutexGuard aGuard;
1028 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1029 "AccessibleEditableTextPara::getBounds: index value overflow");
1031 SvxTextForwarder& rCacheTF = GetTextForwarder();
1032 Rectangle aRect = rCacheTF.GetParaBounds( static_cast< sal_uInt16 >( GetParagraphIndex() ) );
1034 // convert to screen coordinates
1035 Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
1036 rCacheTF.GetMapMode(),
1037 GetViewForwarder() );
1039 // offset from shape/cell
1040 Point aOffset = GetEEOffset();
1042 return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
1043 aScreenRect.Top() + aOffset.Y(),
1044 aScreenRect.GetSize().Width(),
1045 aScreenRect.GetSize().Height() );
1048 awt::Point SAL_CALL AccessibleEditableTextPara::getLocation( ) throw (uno::RuntimeException)
1050 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1052 SolarMutexGuard aGuard;
1054 awt::Rectangle aRect = getBounds();
1056 return awt::Point( aRect.X, aRect.Y );
1059 awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen( ) throw (uno::RuntimeException)
1061 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1063 SolarMutexGuard aGuard;
1065 // relate us to parent
1066 uno::Reference< XAccessible > xParent = getAccessibleParent();
1067 if( xParent.is() )
1069 uno::Reference< XAccessibleComponent > xParentComponent( xParent, uno::UNO_QUERY );
1070 if( xParentComponent.is() )
1072 awt::Point aRefPoint = xParentComponent->getLocationOnScreen();
1073 awt::Point aPoint = getLocation();
1074 aPoint.X += aRefPoint.X;
1075 aPoint.Y += aRefPoint.Y;
1077 return aPoint;
1079 // #i88070#
1080 // fallback to parent's <XAccessibleContext> instance
1081 else
1083 uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext();
1084 if ( xParentContext.is() )
1086 uno::Reference< XAccessibleComponent > xParentContextComponent( xParentContext, uno::UNO_QUERY );
1087 if( xParentContextComponent.is() )
1089 awt::Point aRefPoint = xParentContextComponent->getLocationOnScreen();
1090 awt::Point aPoint = getLocation();
1091 aPoint.X += aRefPoint.X;
1092 aPoint.Y += aRefPoint.Y;
1094 return aPoint;
1100 throw uno::RuntimeException(::rtl::OUString("Cannot access parent"),
1101 uno::Reference< uno::XInterface >
1102 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
1105 awt::Size SAL_CALL AccessibleEditableTextPara::getSize( ) throw (uno::RuntimeException)
1107 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1109 SolarMutexGuard aGuard;
1111 awt::Rectangle aRect = getBounds();
1113 return awt::Size( aRect.Width, aRect.Height );
1116 void SAL_CALL AccessibleEditableTextPara::grabFocus( ) throw (uno::RuntimeException)
1118 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1120 // set cursor to this paragraph
1121 setSelection(0,0);
1124 sal_Int32 SAL_CALL AccessibleEditableTextPara::getForeground( ) throw (::com::sun::star::uno::RuntimeException)
1126 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1128 // #104444# Added to XAccessibleComponent interface
1129 svtools::ColorConfig aColorConfig;
1130 sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
1131 return static_cast<sal_Int32>(nColor);
1134 sal_Int32 SAL_CALL AccessibleEditableTextPara::getBackground( ) throw (::com::sun::star::uno::RuntimeException)
1136 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1138 // #104444# Added to XAccessibleComponent interface
1139 Color aColor( Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor() );
1141 // the background is transparent
1142 aColor.SetTransparency( 0xFF);
1144 return static_cast<sal_Int32>( aColor.GetColor() );
1147 // XAccessibleText
1148 sal_Int32 SAL_CALL AccessibleEditableTextPara::getCaretPosition() throw (uno::RuntimeException)
1150 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1152 SolarMutexGuard aGuard;
1154 if( !HaveEditView() )
1155 return -1;
1157 ESelection aSelection;
1158 if( GetEditViewForwarder().GetSelection( aSelection ) &&
1159 GetParagraphIndex() == aSelection.nEndPara )
1161 // caret is always nEndPara,nEndPos
1162 return aSelection.nEndPos;
1165 // not within this paragraph
1166 return -1;
1169 sal_Bool SAL_CALL AccessibleEditableTextPara::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1171 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1173 return setSelection(nIndex, nIndex);
1176 sal_Unicode SAL_CALL AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1178 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1180 SolarMutexGuard aGuard;
1182 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1183 "AccessibleEditableTextPara::getCharacter: index value overflow");
1185 return OCommonAccessibleText::getCharacter( nIndex );
1188 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rRequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1190 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1191 SolarMutexGuard aGuard;
1193 CheckIndex(nIndex); // may throw IndexOutOfBoundsException
1195 // get default attribues...
1196 ::comphelper::SequenceAsHashMap aPropHashMap( getDefaultAttributes( rRequestedAttributes ) );
1198 // ... and override them with the direct attributes from the specific position
1199 uno::Sequence< beans::PropertyValue > aRunAttribs( getRunAttributes( nIndex, rRequestedAttributes ) );
1200 sal_Int32 nRunAttribs = aRunAttribs.getLength();
1201 const beans::PropertyValue *pRunAttrib = aRunAttribs.getConstArray();
1202 for (sal_Int32 k = 0; k < nRunAttribs; ++k)
1204 const beans::PropertyValue &rRunAttrib = pRunAttrib[k];
1205 aPropHashMap[ rRunAttrib.Name ] = rRunAttrib.Value; //!! should not only be the value !!
1208 // get resulting sequence
1209 uno::Sequence< beans::PropertyValue > aRes;
1210 aPropHashMap >> aRes;
1212 // since SequenceAsHashMap ignores property handles and property state
1213 // we have to restore the property state here (property handles are
1214 // of no use to the accessibility API).
1215 sal_Int32 nRes = aRes.getLength();
1216 beans::PropertyValue *pRes = aRes.getArray();
1217 for (sal_Int32 i = 0; i < nRes; ++i)
1219 beans::PropertyValue &rRes = pRes[i];
1220 sal_Bool bIsDirectVal = sal_False;
1221 for (sal_Int32 k = 0; k < nRunAttribs && !bIsDirectVal; ++k)
1223 if (rRes.Name == pRunAttrib[k].Name)
1224 bIsDirectVal = sal_True;
1226 rRes.Handle = -1;
1227 rRes.State = bIsDirectVal ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
1230 return aRes;
1233 awt::Rectangle SAL_CALL AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1235 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1237 SolarMutexGuard aGuard;
1239 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1240 "AccessibleEditableTextPara::getCharacterBounds: index value overflow");
1242 // #108900# Have position semantics now for nIndex, as
1243 // one-past-the-end values are legal, too.
1244 CheckPosition( nIndex );
1246 SvxTextForwarder& rCacheTF = GetTextForwarder();
1247 Rectangle aRect = rCacheTF.GetCharBounds( static_cast< sal_uInt16 >( GetParagraphIndex() ), static_cast< sal_uInt16 >( nIndex ) );
1249 // convert to screen
1250 Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
1251 rCacheTF.GetMapMode(),
1252 GetViewForwarder() );
1253 // #109864# offset from parent (paragraph), but in screen
1254 // coordinates. This makes sure the internal text offset in
1255 // the outline view forwarder gets cancelled out here
1256 awt::Rectangle aParaRect( getBounds() );
1257 aScreenRect.Move( -aParaRect.X, -aParaRect.Y );
1259 // offset from shape/cell
1260 Point aOffset = GetEEOffset();
1262 return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
1263 aScreenRect.Top() + aOffset.Y(),
1264 aScreenRect.GetSize().Width(),
1265 aScreenRect.GetSize().Height() );
1268 sal_Int32 SAL_CALL AccessibleEditableTextPara::getCharacterCount() throw (uno::RuntimeException)
1270 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1272 SolarMutexGuard aGuard;
1274 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1275 "AccessibleEditableTextPara::getCharacterCount: index value overflow");
1277 return OCommonAccessibleText::getCharacterCount();
1280 sal_Int32 SAL_CALL AccessibleEditableTextPara::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException)
1282 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1284 SolarMutexGuard aGuard;
1286 sal_uInt16 nPara, nIndex;
1288 // offset from surrounding cell/shape
1289 Point aOffset( GetEEOffset() );
1290 Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() );
1292 // convert to logical coordinates
1293 SvxTextForwarder& rCacheTF = GetTextForwarder();
1294 Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
1296 // re-offset to parent (paragraph)
1297 Rectangle aParaRect = rCacheTF.GetParaBounds( static_cast< sal_uInt16 >( GetParagraphIndex() ) );
1298 aLogPoint.Move( aParaRect.Left(), aParaRect.Top() );
1300 if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) &&
1301 GetParagraphIndex() == nPara )
1303 // #102259# Double-check if we're _really_ on the given character
1306 awt::Rectangle aRect1( getCharacterBounds(nIndex) );
1307 Rectangle aRect2( aRect1.X, aRect1.Y,
1308 aRect1.Width + aRect1.X, aRect1.Height + aRect1.Y );
1309 if( aRect2.IsInside( Point( rPoint.X, rPoint.Y ) ) )
1310 return nIndex;
1311 else
1312 return -1;
1314 catch (const lang::IndexOutOfBoundsException&)
1316 // #103927# Don't throw for invalid nIndex values
1317 return -1;
1320 else
1322 // not within our paragraph
1323 return -1;
1327 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getSelectedText() throw (uno::RuntimeException)
1329 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1331 SolarMutexGuard aGuard;
1333 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1334 "AccessibleEditableTextPara::getSelectedText: index value overflow");
1336 if( !HaveEditView() )
1337 return ::rtl::OUString();
1339 return OCommonAccessibleText::getSelectedText();
1342 sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart() throw (uno::RuntimeException)
1344 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1346 SolarMutexGuard aGuard;
1348 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1349 "AccessibleEditableTextPara::getSelectionStart: index value overflow");
1351 if( !HaveEditView() )
1352 return -1;
1354 return OCommonAccessibleText::getSelectionStart();
1357 sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd() throw (uno::RuntimeException)
1359 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1361 SolarMutexGuard aGuard;
1363 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1364 "AccessibleEditableTextPara::getSelectionEnd: index value overflow");
1366 if( !HaveEditView() )
1367 return -1;
1369 return OCommonAccessibleText::getSelectionEnd();
1372 sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1374 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1376 SolarMutexGuard aGuard;
1378 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1379 "AccessibleEditableTextPara::setSelection: paragraph index value overflow");
1381 CheckRange(nStartIndex, nEndIndex);
1385 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
1386 return rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
1388 catch (const uno::RuntimeException&)
1390 return sal_False;
1394 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getText() throw (uno::RuntimeException)
1396 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1398 SolarMutexGuard aGuard;
1400 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1401 "AccessibleEditableTextPara::getText: paragraph index value overflow");
1403 return OCommonAccessibleText::getText();
1406 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1408 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1410 SolarMutexGuard aGuard;
1412 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1413 "AccessibleEditableTextPara::getTextRange: paragraph index value overflow");
1415 return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex);
1418 ::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)
1420 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1422 SolarMutexGuard aGuard;
1424 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1425 "AccessibleEditableTextPara::getTextAtIndex: paragraph index value overflow");
1427 ::com::sun::star::accessibility::TextSegment aResult;
1428 aResult.SegmentStart = -1;
1429 aResult.SegmentEnd = -1;
1431 switch( aTextType )
1433 // Not yet handled by OCommonAccessibleText. Missing
1434 // implGetAttributeRunBoundary() method there
1435 case AccessibleTextType::ATTRIBUTE_RUN:
1437 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( static_cast< sal_uInt16 >( GetParagraphIndex() ) );
1439 if( nIndex == nTextLen )
1441 // #i17014# Special-casing one-behind-the-end character
1442 aResult.SegmentStart = aResult.SegmentEnd = nTextLen;
1444 else
1446 sal_uInt16 nStartIndex, nEndIndex;
1448 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
1450 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1451 aResult.SegmentStart = nStartIndex;
1452 aResult.SegmentEnd = nEndIndex;
1455 break;
1458 default:
1459 aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
1460 break;
1461 } /* end of switch( aTextType ) */
1463 return aResult;
1466 ::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)
1468 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1470 SolarMutexGuard aGuard;
1472 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1473 "AccessibleEditableTextPara::getTextBeforeIndex: paragraph index value overflow");
1475 ::com::sun::star::accessibility::TextSegment aResult;
1476 aResult.SegmentStart = -1;
1477 aResult.SegmentEnd = -1;
1479 switch( aTextType )
1481 // Not yet handled by OCommonAccessibleText. Missing
1482 // implGetAttributeRunBoundary() method there
1483 case AccessibleTextType::ATTRIBUTE_RUN:
1485 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( static_cast< sal_uInt16 >( GetParagraphIndex() ) );
1486 sal_uInt16 nStartIndex, nEndIndex;
1488 if( nIndex == nTextLen )
1490 // #i17014# Special-casing one-behind-the-end character
1491 if( nIndex > 0 &&
1492 GetAttributeRun(nStartIndex, nEndIndex, nIndex-1) )
1494 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1495 aResult.SegmentStart = nStartIndex;
1496 aResult.SegmentEnd = nEndIndex;
1499 else
1501 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
1503 // already at the left border? If not, query
1504 // one index further left
1505 if( nStartIndex > 0 &&
1506 GetAttributeRun(nStartIndex, nEndIndex, nStartIndex-1) )
1508 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1509 aResult.SegmentStart = nStartIndex;
1510 aResult.SegmentEnd = nEndIndex;
1514 break;
1517 default:
1518 aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
1519 break;
1520 } /* end of switch( aTextType ) */
1522 return aResult;
1525 ::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)
1527 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1529 SolarMutexGuard aGuard;
1531 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1532 "AccessibleEditableTextPara::getTextBehindIndex: paragraph index value overflow");
1534 ::com::sun::star::accessibility::TextSegment aResult;
1535 aResult.SegmentStart = -1;
1536 aResult.SegmentEnd = -1;
1538 switch( aTextType )
1540 case AccessibleTextType::ATTRIBUTE_RUN:
1542 sal_uInt16 nStartIndex, nEndIndex;
1544 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
1546 // already at the right border?
1547 if( nEndIndex < GetTextLen() )
1549 if( GetAttributeRun(nStartIndex, nEndIndex, nEndIndex) )
1551 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1552 aResult.SegmentStart = nStartIndex;
1553 aResult.SegmentEnd = nEndIndex;
1557 break;
1560 default:
1561 aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
1562 break;
1563 } /* end of switch( aTextType ) */
1565 return aResult;
1568 sal_Bool SAL_CALL AccessibleEditableTextPara::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1570 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1572 SolarMutexGuard aGuard;
1576 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
1577 #if OSL_DEBUG_LEVEL > 0
1578 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1579 (void)rCacheTF;
1580 #else
1581 GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1582 #endif
1584 sal_Bool aRetVal;
1586 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1587 "AccessibleEditableTextPara::copyText: index value overflow");
1589 CheckRange(nStartIndex, nEndIndex);
1591 // save current selection
1592 ESelection aOldSelection;
1594 rCacheVF.GetSelection( aOldSelection );
1595 rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
1596 aRetVal = rCacheVF.Copy();
1597 rCacheVF.SetSelection( aOldSelection ); // restore
1599 return aRetVal;
1601 catch (const uno::RuntimeException&)
1603 return sal_False;
1607 // XAccessibleEditableText
1608 sal_Bool SAL_CALL AccessibleEditableTextPara::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1610 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1612 SolarMutexGuard aGuard;
1616 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
1617 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1619 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1620 "AccessibleEditableTextPara::cutText: index value overflow");
1622 CheckRange(nStartIndex, nEndIndex);
1624 if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
1625 return sal_False; // non-editable area selected
1627 // don't save selection, might become invalid after cut!
1628 rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
1630 return rCacheVF.Cut();
1632 catch (const uno::RuntimeException&)
1634 return sal_False;
1638 sal_Bool SAL_CALL AccessibleEditableTextPara::pasteText( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1640 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1642 SolarMutexGuard aGuard;
1646 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
1647 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1649 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1650 "AccessibleEditableTextPara::pasteText: index value overflow");
1652 CheckPosition(nIndex);
1654 if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) )
1655 return sal_False; // non-editable area selected
1657 // #104400# set empty selection (=> cursor) to given index
1658 rCacheVF.SetSelection( MakeCursor(nIndex) );
1660 return rCacheVF.Paste();
1662 catch (const uno::RuntimeException&)
1664 return sal_False;
1668 sal_Bool SAL_CALL AccessibleEditableTextPara::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1670 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1672 SolarMutexGuard aGuard;
1676 // #102710# Request edit view when doing changes
1677 // AccessibleEmptyEditSource relies on this behaviour
1678 GetEditViewForwarder( sal_True );
1679 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1681 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1682 "AccessibleEditableTextPara::deleteText: index value overflow");
1684 CheckRange(nStartIndex, nEndIndex);
1686 if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
1687 return sal_False; // non-editable area selected
1689 sal_Bool bRet = rCacheTF.Delete( MakeSelection(nStartIndex, nEndIndex) );
1691 GetEditSource().UpdateData();
1693 return bRet;
1695 catch (const uno::RuntimeException&)
1697 return sal_False;
1701 sal_Bool SAL_CALL AccessibleEditableTextPara::insertText( const ::rtl::OUString& sText, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1703 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1705 SolarMutexGuard aGuard;
1709 // #102710# Request edit view when doing changes
1710 // AccessibleEmptyEditSource relies on this behaviour
1711 GetEditViewForwarder( sal_True );
1712 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1714 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1715 "AccessibleEditableTextPara::insertText: index value overflow");
1717 CheckPosition(nIndex);
1719 if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) )
1720 return sal_False; // non-editable area selected
1722 // #104400# insert given text at empty selection (=> cursor)
1723 sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex) );
1725 rCacheTF.QuickFormatDoc();
1726 GetEditSource().UpdateData();
1728 return bRet;
1730 catch (const uno::RuntimeException&)
1732 return sal_False;
1736 sal_Bool SAL_CALL AccessibleEditableTextPara::replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const ::rtl::OUString& sReplacement ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1738 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1740 SolarMutexGuard aGuard;
1744 // #102710# Request edit view when doing changes
1745 // AccessibleEmptyEditSource relies on this behaviour
1746 GetEditViewForwarder( sal_True );
1747 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1749 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1750 "AccessibleEditableTextPara::replaceText: index value overflow");
1752 CheckRange(nStartIndex, nEndIndex);
1754 if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
1755 return sal_False; // non-editable area selected
1757 // insert given text into given range => replace
1758 sal_Bool bRet = rCacheTF.InsertText( sReplacement, MakeSelection(nStartIndex, nEndIndex) );
1760 rCacheTF.QuickFormatDoc();
1761 GetEditSource().UpdateData();
1763 return bRet;
1765 catch (const uno::RuntimeException&)
1767 return sal_False;
1771 sal_Bool SAL_CALL AccessibleEditableTextPara::setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const uno::Sequence< beans::PropertyValue >& aAttributeSet ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1773 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1775 SolarMutexGuard aGuard;
1779 // #102710# Request edit view when doing changes
1780 // AccessibleEmptyEditSource relies on this behaviour
1781 GetEditViewForwarder( sal_True );
1782 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
1783 sal_uInt16 nPara = static_cast< sal_uInt16 >( GetParagraphIndex() );
1785 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1786 "AccessibleEditableTextPara::setAttributes: index value overflow");
1788 CheckRange(nStartIndex, nEndIndex);
1790 if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
1791 return sal_False; // non-editable area selected
1793 // do the indices span the whole paragraph? Then use the outliner map
1794 // TODO: hold it as a member?
1795 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
1796 0 == nStartIndex &&
1797 rCacheTF.GetTextLen(nPara) == nEndIndex ?
1798 ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() :
1799 ImplGetSvxTextPortionSvxPropertySet() );
1801 aPropSet.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
1803 // convert from PropertyValue to Any
1804 sal_Int32 i, nLength( aAttributeSet.getLength() );
1805 const beans::PropertyValue* pPropArray = aAttributeSet.getConstArray();
1806 for(i=0; i<nLength; ++i)
1810 aPropSet.setPropertyValue(pPropArray->Name, pPropArray->Value);
1812 catch (const uno::Exception&)
1814 OSL_FAIL("AccessibleEditableTextPara::setAttributes exception in setPropertyValue");
1817 ++pPropArray;
1820 rCacheTF.QuickFormatDoc();
1821 GetEditSource().UpdateData();
1823 return sal_True;
1825 catch (const uno::RuntimeException&)
1827 return sal_False;
1831 sal_Bool SAL_CALL AccessibleEditableTextPara::setText( const ::rtl::OUString& sText ) throw (uno::RuntimeException)
1833 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1835 SolarMutexGuard aGuard;
1837 return replaceText(0, getCharacterCount(), sText);
1840 // XAccessibleTextAttributes
1841 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getDefaultAttributes(
1842 const uno::Sequence< ::rtl::OUString >& rRequestedAttributes )
1843 throw (uno::RuntimeException)
1845 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1846 SolarMutexGuard aGuard;
1848 #if OSL_DEBUG_LEVEL > 0
1849 SvxAccessibleTextAdapter& rCacheTF =
1850 #endif
1851 GetTextForwarder();
1853 #if OSL_DEBUG_LEVEL > 0
1854 (void)rCacheTF;
1855 #endif
1857 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1858 "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
1860 // get XPropertySetInfo for paragraph attributes and
1861 // character attributes that span all the paragraphs text.
1862 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
1863 ImplGetSvxCharAndParaPropertiesSet() );
1864 aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) );
1865 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo();
1866 if (!xPropSetInfo.is())
1867 throw uno::RuntimeException(::rtl::OUString("Cannot query XPropertySetInfo"),
1868 uno::Reference< uno::XInterface >
1869 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
1871 // build sequence of available properties to check
1872 sal_Int32 nLenReqAttr = rRequestedAttributes.getLength();
1873 uno::Sequence< beans::Property > aProperties;
1874 if (nLenReqAttr)
1876 const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray();
1878 aProperties.realloc( nLenReqAttr );
1879 beans::Property *pProperties = aProperties.getArray();
1880 sal_Int32 nCurLen = 0;
1881 for (sal_Int32 i = 0; i < nLenReqAttr; ++i)
1883 beans::Property aProp;
1886 aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] );
1888 catch (const beans::UnknownPropertyException&)
1890 continue;
1892 pProperties[ nCurLen++ ] = aProp;
1894 aProperties.realloc( nCurLen );
1896 else
1897 aProperties = xPropSetInfo->getProperties();
1899 sal_Int32 nLength = aProperties.getLength();
1900 const beans::Property *pProperties = aProperties.getConstArray();
1902 // build resulting sequence
1903 uno::Sequence< beans::PropertyValue > aOutSequence( nLength );
1904 beans::PropertyValue* pOutSequence = aOutSequence.getArray();
1905 sal_Int32 nOutLen = 0;
1906 for (sal_Int32 i = 0; i < nLength; ++i)
1908 // calling implementation functions:
1909 // _getPropertyState and _getPropertyValue (see below) to provide
1910 // the proper paragraph number when retrieving paragraph attributes
1911 PropertyState eState = aPropSet._getPropertyState( pProperties->Name, mnParagraphIndex );
1912 if ( eState == PropertyState_AMBIGUOUS_VALUE )
1914 OSL_FAIL( "ambiguous property value encountered" );
1917 //if (eState == PropertyState_DIRECT_VALUE)
1918 // per definition all paragraph properties and all character
1919 // properties spanning the whole paragraph should be returned
1920 // and declared as default value
1922 pOutSequence->Name = pProperties->Name;
1923 pOutSequence->Handle = pProperties->Handle;
1924 pOutSequence->Value = aPropSet._getPropertyValue( pProperties->Name, mnParagraphIndex );
1925 pOutSequence->State = PropertyState_DEFAULT_VALUE;
1927 ++pOutSequence;
1928 ++nOutLen;
1930 ++pProperties;
1932 aOutSequence.realloc( nOutLen );
1934 return aOutSequence;
1938 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getRunAttributes(
1939 sal_Int32 nIndex,
1940 const uno::Sequence< ::rtl::OUString >& rRequestedAttributes )
1941 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1943 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1945 SolarMutexGuard aGuard;
1947 #if OSL_DEBUG_LEVEL > 0
1948 SvxAccessibleTextAdapter& rCacheTF =
1949 #endif
1950 GetTextForwarder();
1952 #if OSL_DEBUG_LEVEL > 0
1953 (void)rCacheTF;
1954 #endif
1956 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1957 "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
1959 CheckIndex(nIndex);
1961 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
1962 ImplGetSvxCharAndParaPropertiesSet() );
1963 aPropSet.SetSelection( MakeSelection( nIndex ) );
1964 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo();
1965 if (!xPropSetInfo.is())
1966 throw uno::RuntimeException(::rtl::OUString("Cannot query XPropertySetInfo"),
1967 uno::Reference< uno::XInterface >
1968 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
1970 // build sequence of available properties to check
1971 sal_Int32 nLenReqAttr = rRequestedAttributes.getLength();
1972 uno::Sequence< beans::Property > aProperties;
1973 if (nLenReqAttr)
1975 const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray();
1977 aProperties.realloc( nLenReqAttr );
1978 beans::Property *pProperties = aProperties.getArray();
1979 sal_Int32 nCurLen = 0;
1980 for (sal_Int32 i = 0; i < nLenReqAttr; ++i)
1982 beans::Property aProp;
1985 aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] );
1987 catch (const beans::UnknownPropertyException&)
1989 continue;
1991 pProperties[ nCurLen++ ] = aProp;
1993 aProperties.realloc( nCurLen );
1995 else
1996 aProperties = xPropSetInfo->getProperties();
1998 sal_Int32 nLength = aProperties.getLength();
1999 const beans::Property *pProperties = aProperties.getConstArray();
2001 // build resulting sequence
2002 uno::Sequence< beans::PropertyValue > aOutSequence( nLength );
2003 beans::PropertyValue* pOutSequence = aOutSequence.getArray();
2004 sal_Int32 nOutLen = 0;
2005 for (sal_Int32 i = 0; i < nLength; ++i)
2007 // calling 'regular' functions that will operate on the selection
2008 PropertyState eState = aPropSet.getPropertyState( pProperties->Name );
2009 if (eState == PropertyState_DIRECT_VALUE)
2011 pOutSequence->Name = pProperties->Name;
2012 pOutSequence->Handle = pProperties->Handle;
2013 pOutSequence->Value = aPropSet.getPropertyValue( pProperties->Name );
2014 pOutSequence->State = eState;
2016 ++pOutSequence;
2017 ++nOutLen;
2019 ++pProperties;
2021 aOutSequence.realloc( nOutLen );
2023 return aOutSequence;
2026 // XAccessibleHypertext
2027 ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkCount( ) throw (::com::sun::star::uno::RuntimeException)
2029 SvxAccessibleTextAdapter& rT = GetTextForwarder();
2030 const sal_Int32 nPara = GetParagraphIndex();
2032 sal_uInt16 nHyperLinks = 0;
2033 sal_uInt16 nFields = rT.GetFieldCount( nPara );
2034 for ( sal_uInt16 n = 0; n < nFields; n++ )
2036 EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2037 if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2038 nHyperLinks++;
2040 return nHyperLinks;
2043 ::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)
2045 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleHyperlink > xRef;
2047 SvxAccessibleTextAdapter& rT = GetTextForwarder();
2048 const sal_Int32 nPara = GetParagraphIndex();
2050 sal_uInt16 nHyperLink = 0;
2051 sal_uInt16 nFields = rT.GetFieldCount( nPara );
2052 for ( sal_uInt16 n = 0; n < nFields; n++ )
2054 EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2055 if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2057 if ( nHyperLink == nLinkIndex )
2059 sal_uInt16 nEEStart = aField.aPosition.nIndex;
2061 // Translate EE Index to accessible index
2062 sal_uInt16 nStart = rT.CalcEditEngineIndex( nPara, nEEStart );
2063 sal_uInt16 nEnd = nStart + aField.aCurrentText.Len();
2064 xRef = new AccessibleHyperlink( rT, new SvxFieldItem( *aField.pFieldItem ), nPara, nEEStart, nStart, nEnd, aField.aCurrentText );
2065 break;
2067 nHyperLink++;
2071 return xRef;
2074 ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkIndex( ::sal_Int32 nCharIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
2076 const sal_Int32 nPara = GetParagraphIndex();
2077 SvxAccessibleTextAdapter& rT = GetTextForwarder();
2079 // SvxAccessibleTextIndex aIndex;
2080 // aIndex.SetIndex(nPara, nCharIndex, rT);
2081 // const sal_uInt16 nEEIndex = aIndex.GetEEIndex();
2083 const sal_uInt16 nEEIndex = rT.CalcEditEngineIndex( nPara, nCharIndex );
2084 sal_Int32 nHLIndex = 0;
2085 sal_uInt16 nHyperLink = 0;
2086 sal_uInt16 nFields = rT.GetFieldCount( nPara );
2087 for ( sal_uInt16 n = 0; n < nFields; n++ )
2089 EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2090 if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2092 if ( aField.aPosition.nIndex == nEEIndex )
2094 nHLIndex = nHyperLink;
2095 break;
2097 nHyperLink++;
2101 return nHLIndex;
2104 // XAccessibleMultiLineText
2105 sal_Int32 SAL_CALL AccessibleEditableTextPara::getLineNumberAtIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2107 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2109 sal_Int32 nRes = -1;
2110 sal_Int32 nPara = GetParagraphIndex();
2112 SvxTextForwarder &rCacheTF = GetTextForwarder();
2113 const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
2114 DBG_ASSERT( bValidPara, "getLineNumberAtIndex: current paragraph index out of range" );
2115 if (bValidPara)
2117 // we explicitly allow for the index to point at the character right behind the text
2118 if (0 <= nIndex && nIndex <= rCacheTF.GetTextLen( static_cast< sal_uInt16 >(nPara) ))
2119 nRes = rCacheTF.GetLineNumberAtIndex( static_cast< sal_uInt16 >(nPara), static_cast< sal_uInt16 >(nIndex) );
2120 else
2121 throw lang::IndexOutOfBoundsException();
2123 return nRes;
2126 // XAccessibleMultiLineText
2127 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineNumber( sal_Int32 nLineNo ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2129 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2131 ::com::sun::star::accessibility::TextSegment aResult;
2132 sal_Int32 nPara = GetParagraphIndex();
2133 SvxTextForwarder &rCacheTF = GetTextForwarder();
2134 const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
2135 DBG_ASSERT( bValidPara, "getTextAtLineNumber: current paragraph index out of range" );
2136 if (bValidPara)
2138 if (0 <= nLineNo && nLineNo < rCacheTF.GetLineCount( static_cast< sal_uInt16 >(nPara) ))
2140 sal_uInt16 nStart = 0, nEnd = 0;
2141 rCacheTF.GetLineBoundaries( nStart, nEnd, static_cast< sal_uInt16 >(nPara), static_cast< sal_uInt16 >(nLineNo) );
2142 if (nStart != 0xFFFF && nEnd != 0xFFFF)
2146 aResult.SegmentText = getTextRange( nStart, nEnd );
2147 aResult.SegmentStart = nStart;
2148 aResult.SegmentEnd = nEnd;
2150 catch (const lang::IndexOutOfBoundsException&)
2152 // this is not the exception that should be raised in this function ...
2153 DBG_ASSERT( 0, "unexpected exception" );
2157 else
2158 throw lang::IndexOutOfBoundsException();
2160 return aResult;
2163 // XAccessibleMultiLineText
2164 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineWithCaret( ) throw (uno::RuntimeException)
2166 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2168 ::com::sun::star::accessibility::TextSegment aResult;
2171 aResult = getTextAtLineNumber( getNumberOfLineWithCaret() );
2173 catch (const lang::IndexOutOfBoundsException&)
2175 // this one needs to be catched since this interface does not allow for it.
2177 return aResult;
2180 // XAccessibleMultiLineText
2181 sal_Int32 SAL_CALL AccessibleEditableTextPara::getNumberOfLineWithCaret( ) throw (uno::RuntimeException)
2183 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2185 sal_Int32 nRes = -1;
2188 nRes = getLineNumberAtIndex( getCaretPosition() );
2190 catch (const lang::IndexOutOfBoundsException&)
2192 // this one needs to be catched since this interface does not allow for it.
2194 return nRes;
2198 // XServiceInfo
2199 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getImplementationName (void) throw (uno::RuntimeException)
2201 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2203 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("AccessibleEditableTextPara"));
2206 sal_Bool SAL_CALL AccessibleEditableTextPara::supportsService (const ::rtl::OUString& sServiceName) throw (uno::RuntimeException)
2208 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2210 // Iterate over all supported service names and return true if on of them
2211 // matches the given name.
2212 uno::Sequence< ::rtl::OUString> aSupportedServices (
2213 getSupportedServiceNames ());
2214 for (int i=0; i<aSupportedServices.getLength(); i++)
2215 if (sServiceName == aSupportedServices[i])
2216 return sal_True;
2217 return sal_False;
2220 uno::Sequence< ::rtl::OUString> SAL_CALL AccessibleEditableTextPara::getSupportedServiceNames (void) throw (uno::RuntimeException)
2222 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2224 const ::rtl::OUString sServiceName( getServiceName() );
2225 return uno::Sequence< ::rtl::OUString > (&sServiceName, 1);
2228 // XServiceName
2229 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getServiceName (void) throw (uno::RuntimeException)
2231 DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2233 // #105185# Using correct service now
2234 return ::rtl::OUString("com.sun.star.text.AccessibleParagraphView");
2237 } // end of namespace accessibility
2239 //------------------------------------------------------------------------
2241 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */