1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
31 #include <osl/mutex.hxx>
32 #include <vcl/window.hxx>
33 #include <vcl/svapp.hxx>
34 #include <com/sun/star/uno/Any.hxx>
35 #include <com/sun/star/uno/Reference.hxx>
39 // Project-local header
42 #include "editeng/unoedprx.hxx"
43 #include <editeng/unotext.hxx>
44 #include <editeng/unoedhlp.hxx>
45 #include <editeng/editdata.hxx>
46 #include <editeng/editeng.hxx>
47 #include <editeng/editview.hxx>
48 #include <editeng/AccessibleStringWrap.hxx>
49 #include <editeng/outliner.hxx>
51 using namespace ::com::sun::star
;
54 class SvxAccessibleTextIndex
57 SvxAccessibleTextIndex() :
67 ~SvxAccessibleTextIndex() {};
69 // Get/Set current paragraph
70 void SetParagraph( sal_Int32 nPara
)
74 sal_Int32
GetParagraph() const { return mnPara
; }
76 /** Set the index in the UAA semantic
79 The index from the UA API (fields and bullets are expanded)
82 The text forwarder to use in the calculations
84 void SetIndex( sal_Int32 nIndex
, const SvxTextForwarder
& rTF
);
85 void SetIndex( sal_Int32 nPara
, sal_Int32 nIndex
, const SvxTextForwarder
& rTF
) { SetParagraph(nPara
); SetIndex(nIndex
, rTF
); }
86 sal_Int32
GetIndex() const { return mnIndex
; }
88 /** Set the index in the edit engine semantic
90 Update the object state to reflect the given index position in
91 EditEngine/Outliner index values
94 The index from the edit engine (fields span exactly one index increment)
97 The text forwarder to use in the calculations
99 void SetEEIndex( sal_uInt16 nEEIndex
, const SvxTextForwarder
& rTF
);
100 void SetEEIndex( sal_Int32 nPara
, sal_uInt16 nEEIndex
, const SvxTextForwarder
& rTF
) { SetParagraph(nPara
); SetEEIndex(nEEIndex
, rTF
); }
101 sal_uInt16
GetEEIndex() const;
103 void SetFieldOffset( sal_Int32 nOffset
, sal_Int32 nLen
) { mnFieldOffset
= nOffset
; mnFieldLen
= nLen
; }
104 sal_Int32
GetFieldOffset() const { return mnFieldOffset
; }
105 sal_Int32
GetFieldLen() const { return mnFieldLen
; }
106 void AreInField( bool bInField
= true ) { mbInField
= bInField
; }
107 bool InField() const { return mbInField
; }
109 void SetBulletOffset( sal_Int32 nOffset
, sal_Int32 nLen
) { mnBulletOffset
= nOffset
; mnBulletLen
= nLen
; }
110 sal_Int32
GetBulletOffset() const { return mnBulletOffset
; }
111 sal_Int32
GetBulletLen() const { return mnBulletLen
; }
112 void AreInBullet( bool bInBullet
= true ) { mbInBullet
= bInBullet
; }
113 bool InBullet() const { return mbInBullet
; }
115 /// returns false if the given range is non-editable (e.g. contains bullets or _parts_ of fields)
116 bool IsEditableRange( const SvxAccessibleTextIndex
& rEnd
) const;
122 sal_Int32 mnFieldOffset
;
123 sal_Int32 mnFieldLen
;
125 sal_Int32 mnBulletOffset
;
126 sal_Int32 mnBulletLen
;
130 ESelection
MakeEESelection( const SvxAccessibleTextIndex
& rStart
, const SvxAccessibleTextIndex
& rEnd
)
132 // deal with field special case: to really get a field contained
133 // within a selection, the start index must be before or on the
134 // field, the end index after it.
136 // The SvxAccessibleTextIndex.GetEEIndex method gives the index on
137 // the field, as long the input index is on the field. Thus,
138 // correction necessary for the end index
140 // Therefore, for _ranges_, if part of the field is touched, all
141 // of the field must be selected
142 if( rStart
.GetParagraph() <= rEnd
.GetParagraph() ||
143 (rStart
.GetParagraph() == rEnd
.GetParagraph() &&
144 rStart
.GetEEIndex() <= rEnd
.GetEEIndex()) )
146 if( rEnd
.InField() && rEnd
.GetFieldOffset() )
147 return ESelection( rStart
.GetParagraph(), rStart
.GetEEIndex(),
148 rEnd
.GetParagraph(), rEnd
.GetEEIndex()+1 );
150 else if( rStart
.GetParagraph() > rEnd
.GetParagraph() ||
151 (rStart
.GetParagraph() == rEnd
.GetParagraph() &&
152 rStart
.GetEEIndex() > rEnd
.GetEEIndex()) )
154 if( rStart
.InField() && rStart
.GetFieldOffset() )
155 return ESelection( rStart
.GetParagraph(), rStart
.GetEEIndex()+1,
156 rEnd
.GetParagraph(), rEnd
.GetEEIndex() );
159 return ESelection( rStart
.GetParagraph(), rStart
.GetEEIndex(),
160 rEnd
.GetParagraph(), rEnd
.GetEEIndex() );
163 ESelection
MakeEESelection( const SvxAccessibleTextIndex
& rIndex
)
165 return ESelection( rIndex
.GetParagraph(), rIndex
.GetEEIndex(),
166 rIndex
.GetParagraph(), rIndex
.GetEEIndex() + 1 );
169 sal_uInt16
SvxAccessibleTextIndex::GetEEIndex() const
171 DBG_ASSERT(mnEEIndex
>= 0 && mnEEIndex
<= USHRT_MAX
,
172 "SvxAccessibleTextIndex::GetEEIndex: index value overflow");
174 return static_cast< sal_uInt16
> (mnEEIndex
);
177 void SvxAccessibleTextIndex::SetEEIndex( sal_uInt16 nEEIndex
, const SvxTextForwarder
& rTF
)
188 mnEEIndex
= nEEIndex
;
190 // calculate unknowns
191 sal_Int32 nCurrField
, nFieldCount
= rTF
.GetFieldCount( GetParagraph() );
195 EBulletInfo aBulletInfo
= rTF
.GetBulletInfo( GetParagraph() );
198 if( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&&
199 aBulletInfo
.bVisible
&&
200 aBulletInfo
.nType
!= SVX_NUM_BITMAP
)
202 mnIndex
+= aBulletInfo
.aText
.getLength();
205 for( nCurrField
=0; nCurrField
< nFieldCount
; ++nCurrField
)
207 EFieldInfo
aFieldInfo( rTF
.GetFieldInfo( GetParagraph(), nCurrField
) );
209 if( aFieldInfo
.aPosition
.nIndex
> nEEIndex
)
212 if( aFieldInfo
.aPosition
.nIndex
== nEEIndex
)
219 mnIndex
+= ::std::max(aFieldInfo
.aCurrentText
.getLength()-1, (sal_Int32
)0);
223 void SvxAccessibleTextIndex::SetIndex( sal_Int32 nIndex
, const SvxTextForwarder
& rTF
)
236 // calculate unknowns
237 sal_Int32 nCurrField
, nFieldCount
= rTF
.GetFieldCount( GetParagraph() );
239 DBG_ASSERT(nIndex
>= 0 && nIndex
<= USHRT_MAX
,
240 "SvxAccessibleTextIndex::SetIndex: index value overflow");
244 EBulletInfo aBulletInfo
= rTF
.GetBulletInfo( GetParagraph() );
247 if( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&&
248 aBulletInfo
.bVisible
&&
249 aBulletInfo
.nType
!= SVX_NUM_BITMAP
)
251 sal_Int32 nBulletLen
= aBulletInfo
.aText
.getLength();
253 if( nIndex
< nBulletLen
)
256 SetBulletOffset( nIndex
, nBulletLen
);
261 mnEEIndex
= mnEEIndex
- nBulletLen
;
264 for( nCurrField
=0; nCurrField
< nFieldCount
; ++nCurrField
)
266 EFieldInfo
aFieldInfo( rTF
.GetFieldInfo( GetParagraph(), nCurrField
) );
268 // we're before a field
269 if( aFieldInfo
.aPosition
.nIndex
> mnEEIndex
)
273 mnEEIndex
-= ::std::max(aFieldInfo
.aCurrentText
.getLength()-1, (sal_Int32
)0);
275 // we're within a field
276 if( aFieldInfo
.aPosition
.nIndex
>= mnEEIndex
)
279 SetFieldOffset( ::std::max(aFieldInfo
.aCurrentText
.getLength()-1, (sal_Int32
)0) - (aFieldInfo
.aPosition
.nIndex
- mnEEIndex
),
280 aFieldInfo
.aCurrentText
.getLength() );
281 mnEEIndex
= aFieldInfo
.aPosition
.nIndex
;
287 bool SvxAccessibleTextIndex::IsEditableRange( const SvxAccessibleTextIndex
& rEnd
) const
289 if( GetIndex() > rEnd
.GetIndex() )
290 return rEnd
.IsEditableRange( *this );
292 if( InBullet() || rEnd
.InBullet() )
295 if( InField() && GetFieldOffset() )
296 return false; // within field
298 if( rEnd
.InField() && rEnd
.GetFieldOffset() >= rEnd
.GetFieldLen() - 1 )
299 return false; // within field
306 SvxEditSourceAdapter::SvxEditSourceAdapter() : mbEditSourceValid( false )
310 SvxEditSourceAdapter::~SvxEditSourceAdapter()
314 SvxEditSource
* SvxEditSourceAdapter::Clone() const
316 if( mbEditSourceValid
&& mpAdaptee
.get() )
318 ::std::unique_ptr
< SvxEditSource
> pClonedAdaptee( mpAdaptee
->Clone() );
320 if( pClonedAdaptee
.get() )
322 SvxEditSourceAdapter
* pClone
= new SvxEditSourceAdapter();
323 pClone
->SetEditSource( std::move(pClonedAdaptee
) );
331 SvxAccessibleTextAdapter
* SvxEditSourceAdapter::GetTextForwarderAdapter()
333 if( mbEditSourceValid
&& mpAdaptee
.get() )
335 SvxTextForwarder
* pTextForwarder
= mpAdaptee
->GetTextForwarder();
339 maTextAdapter
.SetForwarder(*pTextForwarder
);
341 return &maTextAdapter
;
348 SvxTextForwarder
* SvxEditSourceAdapter::GetTextForwarder()
350 return GetTextForwarderAdapter();
353 SvxViewForwarder
* SvxEditSourceAdapter::GetViewForwarder()
355 if( mbEditSourceValid
&& mpAdaptee
.get() )
356 return mpAdaptee
->GetViewForwarder();
361 SvxAccessibleTextEditViewAdapter
* SvxEditSourceAdapter::GetEditViewForwarderAdapter( bool bCreate
)
363 if( mbEditSourceValid
&& mpAdaptee
.get() )
365 SvxEditViewForwarder
* pEditViewForwarder
= mpAdaptee
->GetEditViewForwarder(bCreate
);
367 if( pEditViewForwarder
)
369 SvxAccessibleTextAdapter
* pTextAdapter
= GetTextForwarderAdapter();
373 maEditViewAdapter
.SetForwarder(*pEditViewForwarder
, *pTextAdapter
);
375 return &maEditViewAdapter
;
383 SvxEditViewForwarder
* SvxEditSourceAdapter::GetEditViewForwarder( bool bCreate
)
385 return GetEditViewForwarderAdapter( bCreate
);
388 void SvxEditSourceAdapter::UpdateData()
390 if( mbEditSourceValid
&& mpAdaptee
.get() )
391 mpAdaptee
->UpdateData();
394 SfxBroadcaster
& SvxEditSourceAdapter::GetBroadcaster() const
396 if( mbEditSourceValid
&& mpAdaptee
.get() )
397 return mpAdaptee
->GetBroadcaster();
399 return maDummyBroadcaster
;
402 void SvxEditSourceAdapter::SetEditSource( ::std::unique_ptr
< SvxEditSource
> && pAdaptee
)
406 mpAdaptee
= std::move(pAdaptee
);
407 mbEditSourceValid
= true;
411 // do a lazy delete (prevents us from deleting the broadcaster
412 // from within a broadcast in
413 // AccessibleTextHelper_Impl::Notify)
414 mbEditSourceValid
= false;
418 SvxAccessibleTextAdapter::SvxAccessibleTextAdapter()
419 : mpTextForwarder(NULL
)
423 SvxAccessibleTextAdapter::~SvxAccessibleTextAdapter()
427 sal_Int32
SvxAccessibleTextAdapter::GetParagraphCount() const
429 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
431 return mpTextForwarder
->GetParagraphCount();
434 sal_Int32
SvxAccessibleTextAdapter::GetTextLen( sal_Int32 nParagraph
) const
436 SvxAccessibleTextIndex aIndex
;
437 aIndex
.SetEEIndex( nParagraph
, mpTextForwarder
->GetTextLen( nParagraph
), *this );
439 return aIndex
.GetIndex();
442 OUString
SvxAccessibleTextAdapter::GetText( const ESelection
& rSel
) const
444 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
446 SvxAccessibleTextIndex aStartIndex
;
447 SvxAccessibleTextIndex aEndIndex
;
449 aStartIndex
.SetIndex( rSel
.nStartPara
, rSel
.nStartPos
, *this );
450 aEndIndex
.SetIndex( rSel
.nEndPara
, rSel
.nEndPos
, *this );
452 // normalize selection
453 if( rSel
.nStartPara
> rSel
.nEndPara
||
454 (rSel
.nStartPara
== rSel
.nEndPara
&& rSel
.nStartPos
> rSel
.nEndPos
) )
456 ::std::swap( aStartIndex
, aEndIndex
);
459 OUString sStr
= mpTextForwarder
->GetText( MakeEESelection(aStartIndex
, aEndIndex
) );
461 // trim field text, if necessary
462 if( aStartIndex
.InField() )
464 DBG_ASSERT(aStartIndex
.GetFieldOffset() >= 0 &&
465 aStartIndex
.GetFieldOffset() <= USHRT_MAX
,
466 "SvxAccessibleTextIndex::GetText: index value overflow");
468 sStr
= sStr
.copy( aStartIndex
.GetFieldOffset() );
470 if( aEndIndex
.InField() && aEndIndex
.GetFieldOffset() )
472 DBG_ASSERT(sStr
.getLength() - (aEndIndex
.GetFieldLen() - aEndIndex
.GetFieldOffset()) >= 0 &&
473 sStr
.getLength() - (aEndIndex
.GetFieldLen() - aEndIndex
.GetFieldOffset()) <= USHRT_MAX
,
474 "SvxAccessibleTextIndex::GetText: index value overflow");
476 sStr
= sStr
.copy(0, sStr
.getLength() - (aEndIndex
.GetFieldLen() - aEndIndex
.GetFieldOffset()) );
479 EBulletInfo aBulletInfo1
= GetBulletInfo( aStartIndex
.GetParagraph() );
480 EBulletInfo aBulletInfo2
= GetBulletInfo( aEndIndex
.GetParagraph() );
482 if( aEndIndex
.InBullet() )
484 // append trailing bullet
485 sStr
+= aBulletInfo2
.aText
;
487 DBG_ASSERT(sStr
.getLength() - (aEndIndex
.GetBulletLen() - aEndIndex
.GetBulletOffset()) >= 0 &&
488 sStr
.getLength() - (aEndIndex
.GetBulletLen() - aEndIndex
.GetBulletOffset()) <= USHRT_MAX
,
489 "SvxAccessibleTextIndex::GetText: index value overflow");
491 sStr
= sStr
.copy(0, sStr
.getLength() - (aEndIndex
.GetBulletLen() - aEndIndex
.GetBulletOffset()) );
493 else if( aStartIndex
.GetParagraph() != aEndIndex
.GetParagraph() &&
494 HaveTextBullet( aEndIndex
.GetParagraph() ) )
496 OUString sBullet
= aBulletInfo2
.aText
;
498 DBG_ASSERT(sBullet
.getLength() - (aEndIndex
.GetBulletLen() - aEndIndex
.GetBulletOffset()) >= 0 &&
499 sBullet
.getLength() - (aEndIndex
.GetBulletLen() - aEndIndex
.GetBulletOffset()) <= USHRT_MAX
,
500 "SvxAccessibleTextIndex::GetText: index value overflow");
502 sBullet
= sBullet
.copy(0, sBullet
.getLength() - (aEndIndex
.GetBulletLen() - aEndIndex
.GetBulletOffset()) );
505 sStr
= sStr
.replaceAt( GetTextLen(aStartIndex
.GetParagraph()) - aStartIndex
.GetIndex(), 0, sBullet
);
511 SfxItemSet
SvxAccessibleTextAdapter::GetAttribs( const ESelection
& rSel
, EditEngineAttribs nOnlyHardAttrib
) const
513 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
515 SvxAccessibleTextIndex aStartIndex
;
516 SvxAccessibleTextIndex aEndIndex
;
518 aStartIndex
.SetIndex( rSel
.nStartPara
, rSel
.nStartPos
, *this );
519 aEndIndex
.SetIndex( rSel
.nEndPara
, rSel
.nEndPos
, *this );
521 return mpTextForwarder
->GetAttribs( MakeEESelection(aStartIndex
, aEndIndex
), nOnlyHardAttrib
);
524 SfxItemSet
SvxAccessibleTextAdapter::GetParaAttribs( sal_Int32 nPara
) const
526 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
528 return mpTextForwarder
->GetParaAttribs( nPara
);
531 void SvxAccessibleTextAdapter::SetParaAttribs( sal_Int32 nPara
, const SfxItemSet
& rSet
)
533 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
535 mpTextForwarder
->SetParaAttribs( nPara
, rSet
);
538 void SvxAccessibleTextAdapter::RemoveAttribs( const ESelection
& , bool , sal_uInt16
)
542 void SvxAccessibleTextAdapter::GetPortions( sal_Int32 nPara
, std::vector
<sal_Int32
>& rList
) const
544 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
546 mpTextForwarder
->GetPortions( nPara
, rList
);
549 SfxItemState
SvxAccessibleTextAdapter::GetItemState( const ESelection
& rSel
, sal_uInt16 nWhich
) const
551 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
553 SvxAccessibleTextIndex aStartIndex
;
554 SvxAccessibleTextIndex aEndIndex
;
556 aStartIndex
.SetIndex( rSel
.nStartPara
, rSel
.nStartPos
, *this );
557 aEndIndex
.SetIndex( rSel
.nEndPara
, rSel
.nEndPos
, *this );
559 return mpTextForwarder
->GetItemState( MakeEESelection(aStartIndex
, aEndIndex
),
563 SfxItemState
SvxAccessibleTextAdapter::GetItemState( sal_Int32 nPara
, sal_uInt16 nWhich
) const
565 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
567 return mpTextForwarder
->GetItemState( nPara
, nWhich
);
570 void SvxAccessibleTextAdapter::QuickInsertText( const OUString
& rText
, const ESelection
& rSel
)
572 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
574 SvxAccessibleTextIndex aStartIndex
;
575 SvxAccessibleTextIndex aEndIndex
;
577 aStartIndex
.SetIndex( rSel
.nStartPara
, rSel
.nStartPos
, *this );
578 aEndIndex
.SetIndex( rSel
.nEndPara
, rSel
.nEndPos
, *this );
580 mpTextForwarder
->QuickInsertText( rText
,
581 MakeEESelection(aStartIndex
, aEndIndex
) );
584 void SvxAccessibleTextAdapter::QuickInsertField( const SvxFieldItem
& rFld
, const ESelection
& rSel
)
586 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
588 SvxAccessibleTextIndex aStartIndex
;
589 SvxAccessibleTextIndex aEndIndex
;
591 aStartIndex
.SetIndex( rSel
.nStartPara
, rSel
.nStartPos
, *this );
592 aEndIndex
.SetIndex( rSel
.nEndPara
, rSel
.nEndPos
, *this );
594 mpTextForwarder
->QuickInsertField( rFld
,
595 MakeEESelection(aStartIndex
, aEndIndex
) );
598 void SvxAccessibleTextAdapter::QuickSetAttribs( const SfxItemSet
& rSet
, const ESelection
& rSel
)
600 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
602 SvxAccessibleTextIndex aStartIndex
;
603 SvxAccessibleTextIndex aEndIndex
;
605 aStartIndex
.SetIndex( rSel
.nStartPara
, rSel
.nStartPos
, *this );
606 aEndIndex
.SetIndex( rSel
.nEndPara
, rSel
.nEndPos
, *this );
608 mpTextForwarder
->QuickSetAttribs( rSet
,
609 MakeEESelection(aStartIndex
, aEndIndex
) );
612 void SvxAccessibleTextAdapter::QuickInsertLineBreak( const ESelection
& rSel
)
614 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
616 SvxAccessibleTextIndex aStartIndex
;
617 SvxAccessibleTextIndex aEndIndex
;
619 aStartIndex
.SetIndex( rSel
.nStartPara
, rSel
.nStartPos
, *this );
620 aEndIndex
.SetIndex( rSel
.nEndPara
, rSel
.nEndPos
, *this );
622 mpTextForwarder
->QuickInsertLineBreak( MakeEESelection(aStartIndex
, aEndIndex
) );
625 SfxItemPool
* SvxAccessibleTextAdapter::GetPool() const
627 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
629 return mpTextForwarder
->GetPool();
632 OUString
SvxAccessibleTextAdapter::CalcFieldValue( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
, Color
*& rpTxtColor
, Color
*& rpFldColor
)
634 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
636 return mpTextForwarder
->CalcFieldValue( rField
, nPara
, nPos
, rpTxtColor
, rpFldColor
);
639 void SvxAccessibleTextAdapter::FieldClicked( const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_Int32 nPos
)
641 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
643 mpTextForwarder
->FieldClicked( rField
, nPara
, nPos
);
646 sal_uInt16
SvxAccessibleTextAdapter::CalcEditEngineIndex( sal_Int32 nPara
, sal_Int32 nLogicalIndex
)
648 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
650 SvxAccessibleTextIndex aIndex
;
651 aIndex
.SetIndex(nPara
, nLogicalIndex
, *mpTextForwarder
);
652 return aIndex
.GetEEIndex();
655 bool SvxAccessibleTextAdapter::IsValid() const
657 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
659 if( mpTextForwarder
)
660 return mpTextForwarder
->IsValid();
665 LanguageType
SvxAccessibleTextAdapter::GetLanguage( sal_Int32 nPara
, sal_Int32 nPos
) const
667 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
669 SvxAccessibleTextIndex aIndex
;
671 aIndex
.SetIndex( nPara
, nPos
, *this );
673 return mpTextForwarder
->GetLanguage( nPara
, aIndex
.GetEEIndex() );
676 sal_Int32
SvxAccessibleTextAdapter::GetFieldCount( sal_Int32 nPara
) const
678 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
680 return mpTextForwarder
->GetFieldCount( nPara
);
683 EFieldInfo
SvxAccessibleTextAdapter::GetFieldInfo( sal_Int32 nPara
, sal_uInt16 nField
) const
685 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
687 return mpTextForwarder
->GetFieldInfo( nPara
, nField
);
690 EBulletInfo
SvxAccessibleTextAdapter::GetBulletInfo( sal_Int32 nPara
) const
692 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
694 return mpTextForwarder
->GetBulletInfo( nPara
);
697 void SvxAccessibleTextAdapter::SetUpdateModeForAcc(bool bUp
)
699 return mpTextForwarder
->SetUpdateModeForAcc(bUp
);
702 bool SvxAccessibleTextAdapter::GetUpdateModeForAcc( ) const
704 return mpTextForwarder
->GetUpdateModeForAcc();
707 Rectangle
SvxAccessibleTextAdapter::GetCharBounds( sal_Int32 nPara
, sal_Int32 nIndex
) const
709 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
711 SvxAccessibleTextIndex aIndex
;
712 aIndex
.SetIndex( nPara
, nIndex
, *this );
714 // preset if anything goes wrong below
715 // n-th char in GetParagraphIndex's paragraph
716 Rectangle aRect
= mpTextForwarder
->GetCharBounds( nPara
, aIndex
.GetEEIndex() );
718 if( aIndex
.InBullet() )
720 EBulletInfo aBulletInfo
= GetBulletInfo( nPara
);
722 OutputDevice
* pOutDev
= GetRefDevice();
724 DBG_ASSERT(pOutDev
!=NULL
, "SvxAccessibleTextAdapter::GetCharBounds: No ref device");
726 // preset if anything goes wrong below
727 aRect
= aBulletInfo
.aBounds
; // better than nothing
730 AccessibleStringWrap
aStringWrap( *pOutDev
, aBulletInfo
.aFont
, aBulletInfo
.aText
);
732 aStringWrap
.GetCharacterBounds( aIndex
.GetBulletOffset(), aRect
);
733 aRect
.Move( aBulletInfo
.aBounds
.Left(), aBulletInfo
.aBounds
.Top() );
738 // handle field content manually
739 if( aIndex
.InField() )
741 OutputDevice
* pOutDev
= GetRefDevice();
743 DBG_ASSERT(pOutDev
!=NULL
, "SvxAccessibleTextAdapter::GetCharBounds: No ref device");
747 ESelection aSel
= MakeEESelection( aIndex
);
749 SvxFont aFont
= EditEngine::CreateSvxFontFromItemSet( mpTextForwarder
->GetAttribs( aSel
) );
750 AccessibleStringWrap
aStringWrap( *pOutDev
,
752 mpTextForwarder
->GetText( aSel
) );
754 Rectangle aStartRect
= mpTextForwarder
->GetCharBounds( nPara
, aIndex
.GetEEIndex() );
756 aStringWrap
.GetCharacterBounds( aIndex
.GetFieldOffset(), aRect
);
757 aRect
.Move( aStartRect
.Left(), aStartRect
.Top() );
765 Rectangle
SvxAccessibleTextAdapter::GetParaBounds( sal_Int32 nPara
) const
767 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
769 EBulletInfo aBulletInfo
= GetBulletInfo( nPara
);
771 if( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&&
772 aBulletInfo
.bVisible
&&
773 aBulletInfo
.nType
!= SVX_NUM_BITMAP
)
775 // include bullet in para bounding box
776 Rectangle
aRect( mpTextForwarder
->GetParaBounds( nPara
) );
778 aRect
.Union( aBulletInfo
.aBounds
);
783 return mpTextForwarder
->GetParaBounds( nPara
);
786 MapMode
SvxAccessibleTextAdapter::GetMapMode() const
788 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
790 return mpTextForwarder
->GetMapMode();
793 OutputDevice
* SvxAccessibleTextAdapter::GetRefDevice() const
795 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
797 return mpTextForwarder
->GetRefDevice();
800 bool SvxAccessibleTextAdapter::GetIndexAtPoint( const Point
& rPoint
, sal_Int32
& nPara
, sal_Int32
& nIndex
) const
802 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
804 if( !mpTextForwarder
->GetIndexAtPoint( rPoint
, nPara
, nIndex
) )
807 SvxAccessibleTextIndex aIndex
;
808 aIndex
.SetEEIndex(nPara
, nIndex
, *this);
810 DBG_ASSERT(aIndex
.GetIndex() >= 0 && aIndex
.GetIndex() <= USHRT_MAX
,
811 "SvxAccessibleTextIndex::SetIndex: index value overflow");
813 nIndex
= aIndex
.GetIndex();
815 EBulletInfo aBulletInfo
= GetBulletInfo( nPara
);
818 if( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&&
819 aBulletInfo
.bVisible
&&
820 aBulletInfo
.nType
!= SVX_NUM_BITMAP
)
822 if( aBulletInfo
.aBounds
.IsInside( rPoint
) )
824 OutputDevice
* pOutDev
= GetRefDevice();
826 DBG_ASSERT(pOutDev
!=NULL
, "SvxAccessibleTextAdapter::GetIndexAtPoint: No ref device");
831 AccessibleStringWrap
aStringWrap( *pOutDev
, aBulletInfo
.aFont
, aBulletInfo
.aText
);
833 Point aPoint
= rPoint
;
834 aPoint
.Move( -aBulletInfo
.aBounds
.Left(), -aBulletInfo
.aBounds
.Top() );
836 DBG_ASSERT(aStringWrap
.GetIndexAtPoint( aPoint
) >= 0 &&
837 aStringWrap
.GetIndexAtPoint( aPoint
) <= USHRT_MAX
,
838 "SvxAccessibleTextIndex::SetIndex: index value overflow");
840 nIndex
= aStringWrap
.GetIndexAtPoint( aPoint
);
845 if( aIndex
.InField() )
847 OutputDevice
* pOutDev
= GetRefDevice();
849 DBG_ASSERT(pOutDev
!=NULL
, "SvxAccessibleTextAdapter::GetIndexAtPoint: No ref device");
854 ESelection aSelection
= MakeEESelection( aIndex
);
855 SvxFont aFont
= EditEngine::CreateSvxFontFromItemSet( mpTextForwarder
->GetAttribs( aSelection
) );
856 AccessibleStringWrap
aStringWrap( *pOutDev
,
858 mpTextForwarder
->GetText( aSelection
) );
860 Rectangle aRect
= mpTextForwarder
->GetCharBounds( nPara
, aIndex
.GetEEIndex() );
861 Point aPoint
= rPoint
;
862 aPoint
.Move( -aRect
.Left(), -aRect
.Top() );
864 DBG_ASSERT(aIndex
.GetIndex() + aStringWrap
.GetIndexAtPoint( rPoint
) >= 0 &&
865 aIndex
.GetIndex() + aStringWrap
.GetIndexAtPoint( rPoint
) <= USHRT_MAX
,
866 "SvxAccessibleTextIndex::SetIndex: index value overflow");
868 nIndex
= (aIndex
.GetIndex() + aStringWrap
.GetIndexAtPoint( aPoint
));
875 bool SvxAccessibleTextAdapter::GetWordIndices( sal_Int32 nPara
, sal_Int32 nIndex
, sal_Int32
& nStart
, sal_Int32
& nEnd
) const
877 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
879 SvxAccessibleTextIndex aIndex
;
880 aIndex
.SetIndex(nPara
, nIndex
, *this);
881 nIndex
= aIndex
.GetEEIndex();
883 if( aIndex
.InBullet() )
885 DBG_ASSERT(aIndex
.GetBulletLen() >= 0 &&
886 aIndex
.GetBulletLen() <= USHRT_MAX
,
887 "SvxAccessibleTextIndex::SetIndex: index value overflow");
889 // always treat bullet as separate word
891 nEnd
= aIndex
.GetBulletLen();
896 if( aIndex
.InField() )
898 DBG_ASSERT(aIndex
.GetIndex() - aIndex
.GetFieldOffset() >= 0 &&
899 aIndex
.GetIndex() - aIndex
.GetFieldOffset() <= USHRT_MAX
&&
900 nStart
+ aIndex
.GetFieldLen() >= 0 &&
901 nStart
+ aIndex
.GetFieldLen() <= USHRT_MAX
,
902 "SvxAccessibleTextIndex::SetIndex: index value overflow");
904 // always treat field as separate word
905 // TODO: to circumvent this, _we_ would have to do the break iterator stuff!
906 nStart
= aIndex
.GetIndex() - aIndex
.GetFieldOffset();
907 nEnd
= nStart
+ aIndex
.GetFieldLen();
912 if( !mpTextForwarder
->GetWordIndices( nPara
, nIndex
, nStart
, nEnd
) )
915 aIndex
.SetEEIndex( nPara
, nStart
, *this );
916 DBG_ASSERT(aIndex
.GetIndex() >= 0 &&
917 aIndex
.GetIndex() <= USHRT_MAX
,
918 "SvxAccessibleTextIndex::SetIndex: index value overflow");
919 nStart
= aIndex
.GetIndex();
921 aIndex
.SetEEIndex( nPara
, nEnd
, *this );
922 DBG_ASSERT(aIndex
.GetIndex() >= 0 &&
923 aIndex
.GetIndex() <= USHRT_MAX
,
924 "SvxAccessibleTextIndex::SetIndex: index value overflow");
925 nEnd
= aIndex
.GetIndex();
930 bool SvxAccessibleTextAdapter::GetAttributeRun( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, sal_Int32 nPara
, sal_Int32 nIndex
, bool /* bInCell */ ) const
932 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
934 SvxAccessibleTextIndex aIndex
;
935 aIndex
.SetIndex(nPara
, nIndex
, *this);
936 nIndex
= aIndex
.GetEEIndex();
938 if( aIndex
.InBullet() )
940 DBG_ASSERT(aIndex
.GetBulletLen() >= 0 &&
941 aIndex
.GetBulletLen() <= USHRT_MAX
,
942 "SvxAccessibleTextIndex::SetIndex: index value overflow");
944 // always treat bullet as distinct attribute
946 nEndIndex
= aIndex
.GetBulletLen();
951 if( aIndex
.InField() )
953 DBG_ASSERT(aIndex
.GetIndex() - aIndex
.GetFieldOffset() >= 0 &&
954 aIndex
.GetIndex() - aIndex
.GetFieldOffset() <= USHRT_MAX
,
955 "SvxAccessibleTextIndex::SetIndex: index value overflow");
957 // always treat field as distinct attribute
958 nStartIndex
= aIndex
.GetIndex() - aIndex
.GetFieldOffset();
959 nEndIndex
= nStartIndex
+ aIndex
.GetFieldLen();
964 if( !mpTextForwarder
->GetAttributeRun( nStartIndex
, nEndIndex
, nPara
, nIndex
) )
967 aIndex
.SetEEIndex( nPara
, nStartIndex
, *this );
968 DBG_ASSERT(aIndex
.GetIndex() >= 0 &&
969 aIndex
.GetIndex() <= USHRT_MAX
,
970 "SvxAccessibleTextIndex::SetIndex: index value overflow");
971 nStartIndex
= aIndex
.GetIndex();
973 aIndex
.SetEEIndex( nPara
, nEndIndex
, *this );
974 DBG_ASSERT(aIndex
.GetIndex() >= 0 &&
975 aIndex
.GetIndex() <= USHRT_MAX
,
976 "SvxAccessibleTextIndex::SetIndex: index value overflow");
977 nEndIndex
= aIndex
.GetIndex();
982 sal_Int32
SvxAccessibleTextAdapter::GetLineCount( sal_Int32 nPara
) const
984 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
986 return mpTextForwarder
->GetLineCount( nPara
);
989 sal_Int32
SvxAccessibleTextAdapter::GetLineLen( sal_Int32 nPara
, sal_Int32 nLine
) const
991 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
993 SvxAccessibleTextIndex aStartIndex
;
994 SvxAccessibleTextIndex aEndIndex
;
996 sal_Int32 nCurrIndex
, nLastIndex
;
997 for( nCurrLine
=0, nCurrIndex
=0, nLastIndex
=0; nCurrLine
<=nLine
; ++nCurrLine
)
999 nLastIndex
= nCurrIndex
;
1001 nCurrIndex
+ mpTextForwarder
->GetLineLen( nPara
, nCurrLine
);
1004 aEndIndex
.SetEEIndex( nPara
, nCurrIndex
, *this );
1007 aStartIndex
.SetEEIndex( nPara
, nLastIndex
, *this );
1009 return aEndIndex
.GetIndex() - aStartIndex
.GetIndex();
1012 return aEndIndex
.GetIndex();
1015 void SvxAccessibleTextAdapter::GetLineBoundaries( /*out*/sal_Int32
&rStart
, /*out*/sal_Int32
&rEnd
, sal_Int32 nParagraph
, sal_Int32 nLine
) const
1017 mpTextForwarder
->GetLineBoundaries( rStart
, rEnd
, nParagraph
, nLine
);
1020 sal_Int32
SvxAccessibleTextAdapter::GetLineNumberAtIndex( sal_Int32 nPara
, sal_Int32 nIndex
) const
1022 return mpTextForwarder
->GetLineNumberAtIndex( nPara
, nIndex
);
1025 bool SvxAccessibleTextAdapter::Delete( const ESelection
& rSel
)
1027 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
1029 SvxAccessibleTextIndex aStartIndex
;
1030 SvxAccessibleTextIndex aEndIndex
;
1032 aStartIndex
.SetIndex( rSel
.nStartPara
, rSel
.nStartPos
, *this );
1033 aEndIndex
.SetIndex( rSel
.nEndPara
, rSel
.nEndPos
, *this );
1035 return mpTextForwarder
->Delete( MakeEESelection(aStartIndex
, aEndIndex
) );
1038 bool SvxAccessibleTextAdapter::InsertText( const OUString
& rStr
, const ESelection
& rSel
)
1040 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
1042 SvxAccessibleTextIndex aStartIndex
;
1043 SvxAccessibleTextIndex aEndIndex
;
1045 aStartIndex
.SetIndex( rSel
.nStartPara
, rSel
.nStartPos
, *this );
1046 aEndIndex
.SetIndex( rSel
.nEndPara
, rSel
.nEndPos
, *this );
1048 return mpTextForwarder
->InsertText( rStr
, MakeEESelection(aStartIndex
, aEndIndex
) );
1051 bool SvxAccessibleTextAdapter::QuickFormatDoc( bool bFull
)
1053 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
1055 return mpTextForwarder
->QuickFormatDoc( bFull
);
1058 sal_Int16
SvxAccessibleTextAdapter::GetDepth( sal_Int32 nPara
) const
1060 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
1062 return mpTextForwarder
->GetDepth( nPara
);
1065 bool SvxAccessibleTextAdapter::SetDepth( sal_Int32 nPara
, sal_Int16 nNewDepth
)
1067 assert(mpTextForwarder
&& "SvxAccessibleTextAdapter: no forwarder");
1069 return mpTextForwarder
->SetDepth( nPara
, nNewDepth
);
1072 void SvxAccessibleTextAdapter::SetForwarder( SvxTextForwarder
& rForwarder
)
1074 mpTextForwarder
= &rForwarder
;
1077 bool SvxAccessibleTextAdapter::HaveImageBullet( sal_Int32 nPara
) const
1079 EBulletInfo aBulletInfo
= GetBulletInfo( nPara
);
1081 return ( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&&
1082 aBulletInfo
.bVisible
&&
1083 aBulletInfo
.nType
== SVX_NUM_BITMAP
);
1086 bool SvxAccessibleTextAdapter::HaveTextBullet( sal_Int32 nPara
) const
1088 EBulletInfo aBulletInfo
= GetBulletInfo( nPara
);
1090 return ( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&&
1091 aBulletInfo
.bVisible
&&
1092 aBulletInfo
.nType
!= SVX_NUM_BITMAP
);
1095 bool SvxAccessibleTextAdapter::IsEditable( const ESelection
& rSel
)
1097 SvxAccessibleTextIndex aStartIndex
;
1098 SvxAccessibleTextIndex aEndIndex
;
1100 aStartIndex
.SetIndex( rSel
.nStartPara
, rSel
.nStartPos
, *this );
1101 aEndIndex
.SetIndex( rSel
.nEndPara
, rSel
.nEndPos
, *this );
1103 // normalize selection
1104 if( rSel
.nStartPara
> rSel
.nEndPara
||
1105 (rSel
.nStartPara
== rSel
.nEndPara
&& rSel
.nStartPos
> rSel
.nEndPos
) )
1107 ::std::swap( aStartIndex
, aEndIndex
);
1110 return aStartIndex
.IsEditableRange( aEndIndex
);
1113 const SfxItemSet
* SvxAccessibleTextAdapter::GetEmptyItemSetPtr()
1115 OSL_FAIL( "not implemented" );
1119 void SvxAccessibleTextAdapter::AppendParagraph()
1121 OSL_FAIL( "not implemented" );
1124 sal_Int32
SvxAccessibleTextAdapter::AppendTextPortion( sal_Int32
, const OUString
&, const SfxItemSet
& )
1126 OSL_FAIL( "not implemented" );
1129 void SvxAccessibleTextAdapter::CopyText(const SvxTextForwarder
&)
1131 OSL_FAIL( "not implemented" );
1134 SvxAccessibleTextEditViewAdapter::SvxAccessibleTextEditViewAdapter()
1135 : mpViewForwarder(NULL
)
1136 , mpTextForwarder(NULL
)
1140 SvxAccessibleTextEditViewAdapter::~SvxAccessibleTextEditViewAdapter()
1144 bool SvxAccessibleTextEditViewAdapter::IsValid() const
1146 DBG_ASSERT(mpViewForwarder
, "SvxAccessibleTextEditViewAdapter: no forwarder");
1148 if( mpViewForwarder
)
1149 return mpViewForwarder
->IsValid();
1154 Rectangle
SvxAccessibleTextEditViewAdapter::GetVisArea() const
1156 DBG_ASSERT(mpViewForwarder
, "SvxAccessibleTextEditViewAdapter: no forwarder");
1158 return mpViewForwarder
->GetVisArea();
1161 Point
SvxAccessibleTextEditViewAdapter::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
1163 DBG_ASSERT(mpViewForwarder
, "SvxAccessibleTextEditViewAdapter: no forwarder");
1165 return mpViewForwarder
->LogicToPixel(rPoint
, rMapMode
);
1168 Point
SvxAccessibleTextEditViewAdapter::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
1170 DBG_ASSERT(mpViewForwarder
, "SvxAccessibleTextEditViewAdapter: no forwarder");
1172 return mpViewForwarder
->PixelToLogic(rPoint
, rMapMode
);
1175 bool SvxAccessibleTextEditViewAdapter::GetSelection( ESelection
& rSel
) const
1177 DBG_ASSERT(mpViewForwarder
, "SvxAccessibleTextEditViewAdapter: no forwarder");
1179 ESelection aSelection
;
1181 if( !mpViewForwarder
->GetSelection( aSelection
) )
1184 SvxAccessibleTextIndex aStartIndex
;
1185 SvxAccessibleTextIndex aEndIndex
;
1187 aStartIndex
.SetEEIndex( aSelection
.nStartPara
, aSelection
.nStartPos
, *mpTextForwarder
);
1188 aEndIndex
.SetEEIndex( aSelection
.nEndPara
, aSelection
.nEndPos
, *mpTextForwarder
);
1190 DBG_ASSERT(aStartIndex
.GetIndex() >= 0 && aStartIndex
.GetIndex() <= USHRT_MAX
&&
1191 aEndIndex
.GetIndex() >= 0 && aEndIndex
.GetIndex() <= USHRT_MAX
,
1192 "SvxAccessibleTextEditViewAdapter::GetSelection: index value overflow");
1194 rSel
= ESelection( aStartIndex
.GetParagraph(), aStartIndex
.GetIndex(),
1195 aEndIndex
.GetParagraph(), aEndIndex
.GetIndex() );
1200 bool SvxAccessibleTextEditViewAdapter::SetSelection( const ESelection
& rSel
)
1202 DBG_ASSERT(mpViewForwarder
, "SvxAccessibleTextEditViewAdapter: no forwarder");
1204 SvxAccessibleTextIndex aStartIndex
;
1205 SvxAccessibleTextIndex aEndIndex
;
1207 aStartIndex
.SetIndex( rSel
.nStartPara
, rSel
.nStartPos
, *mpTextForwarder
);
1208 aEndIndex
.SetIndex( rSel
.nEndPara
, rSel
.nEndPos
, *mpTextForwarder
);
1210 return mpViewForwarder
->SetSelection( MakeEESelection(aStartIndex
, aEndIndex
) );
1213 bool SvxAccessibleTextEditViewAdapter::Copy()
1215 DBG_ASSERT(mpViewForwarder
, "SvxAccessibleTextEditViewAdapter: no forwarder");
1217 return mpViewForwarder
->Copy();
1220 bool SvxAccessibleTextEditViewAdapter::Cut()
1222 DBG_ASSERT(mpViewForwarder
, "SvxAccessibleTextEditViewAdapter: no forwarder");
1224 return mpViewForwarder
->Cut();
1227 bool SvxAccessibleTextEditViewAdapter::Paste()
1229 DBG_ASSERT(mpViewForwarder
, "SvxAccessibleTextEditViewAdapter: no forwarder");
1231 return mpViewForwarder
->Paste();
1234 void SvxAccessibleTextEditViewAdapter::SetForwarder( SvxEditViewForwarder
& rForwarder
,
1235 SvxAccessibleTextAdapter
& rTextForwarder
)
1237 mpViewForwarder
= &rForwarder
;
1238 mpTextForwarder
= &rTextForwarder
;
1241 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */