bump product version to 5.0.4.1
[LibreOffice.git] / editeng / source / uno / unoedprx.cxx
blob9de8512a70a58602870375b896bc98175fde62b3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 // Global header
27 #include <limits.h>
28 #include <utility>
29 #include <vector>
30 #include <algorithm>
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
56 public:
57 SvxAccessibleTextIndex() :
58 mnPara(0),
59 mnIndex(0),
60 mnEEIndex(0),
61 mnFieldOffset(0),
62 mnFieldLen(0),
63 mbInField(false),
64 mnBulletOffset(0),
65 mnBulletLen(0),
66 mbInBullet(false) {};
67 ~SvxAccessibleTextIndex() {};
69 // Get/Set current paragraph
70 void SetParagraph( sal_Int32 nPara )
72 mnPara = nPara;
74 sal_Int32 GetParagraph() const { return mnPara; }
76 /** Set the index in the UAA semantic
78 @param nIndex
79 The index from the UA API (fields and bullets are expanded)
81 @param rTF
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
93 @param nEEIndex
94 The index from the edit engine (fields span exactly one index increment)
96 @param rTF
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;
118 private:
119 sal_Int32 mnPara;
120 sal_Int32 mnIndex;
121 sal_Int32 mnEEIndex;
122 sal_Int32 mnFieldOffset;
123 sal_Int32 mnFieldLen;
124 bool mbInField;
125 sal_Int32 mnBulletOffset;
126 sal_Int32 mnBulletLen;
127 bool mbInBullet;
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 )
179 // reset
180 mnFieldOffset = 0;
181 mbInField = false;
182 mnFieldLen = 0;
183 mnBulletOffset = 0;
184 mbInBullet = false;
185 mnBulletLen = 0;
187 // set known values
188 mnEEIndex = nEEIndex;
190 // calculate unknowns
191 sal_Int32 nCurrField, nFieldCount = rTF.GetFieldCount( GetParagraph() );
193 mnIndex = nEEIndex;
195 EBulletInfo aBulletInfo = rTF.GetBulletInfo( GetParagraph() );
197 // any text bullets?
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 )
210 break;
212 if( aFieldInfo.aPosition.nIndex == nEEIndex )
214 AreInField();
215 break;
218 // #106010#
219 mnIndex += ::std::max(aFieldInfo.aCurrentText.getLength()-1, (sal_Int32)0);
223 void SvxAccessibleTextIndex::SetIndex( sal_Int32 nIndex, const SvxTextForwarder& rTF )
225 // reset
226 mnFieldOffset = 0;
227 mbInField = false;
228 mnFieldLen = 0;
229 mnBulletOffset = 0;
230 mbInBullet = false;
231 mnBulletLen = 0;
233 // set known values
234 mnIndex = nIndex;
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");
242 mnEEIndex = nIndex;
244 EBulletInfo aBulletInfo = rTF.GetBulletInfo( GetParagraph() );
246 // any text bullets?
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 )
255 AreInBullet();
256 SetBulletOffset( nIndex, nBulletLen );
257 mnEEIndex = 0;
258 return;
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 )
270 break;
272 // #106010#
273 mnEEIndex -= ::std::max(aFieldInfo.aCurrentText.getLength()-1, (sal_Int32)0);
275 // we're within a field
276 if( aFieldInfo.aPosition.nIndex >= mnEEIndex )
278 AreInField();
279 SetFieldOffset( ::std::max(aFieldInfo.aCurrentText.getLength()-1, (sal_Int32)0) - (aFieldInfo.aPosition.nIndex - mnEEIndex),
280 aFieldInfo.aCurrentText.getLength() );
281 mnEEIndex = aFieldInfo.aPosition.nIndex ;
282 break;
287 bool SvxAccessibleTextIndex::IsEditableRange( const SvxAccessibleTextIndex& rEnd ) const
289 if( GetIndex() > rEnd.GetIndex() )
290 return rEnd.IsEditableRange( *this );
292 if( InBullet() || rEnd.InBullet() )
293 return false;
295 if( InField() && GetFieldOffset() )
296 return false; // within field
298 if( rEnd.InField() && rEnd.GetFieldOffset() >= rEnd.GetFieldLen() - 1 )
299 return false; // within field
301 return true;
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) );
324 return pClone;
328 return NULL;
331 SvxAccessibleTextAdapter* SvxEditSourceAdapter::GetTextForwarderAdapter()
333 if( mbEditSourceValid && mpAdaptee.get() )
335 SvxTextForwarder* pTextForwarder = mpAdaptee->GetTextForwarder();
337 if( pTextForwarder )
339 maTextAdapter.SetForwarder(*pTextForwarder);
341 return &maTextAdapter;
345 return NULL;
348 SvxTextForwarder* SvxEditSourceAdapter::GetTextForwarder()
350 return GetTextForwarderAdapter();
353 SvxViewForwarder* SvxEditSourceAdapter::GetViewForwarder()
355 if( mbEditSourceValid && mpAdaptee.get() )
356 return mpAdaptee->GetViewForwarder();
358 return NULL;
361 SvxAccessibleTextEditViewAdapter* SvxEditSourceAdapter::GetEditViewForwarderAdapter( bool bCreate )
363 if( mbEditSourceValid && mpAdaptee.get() )
365 SvxEditViewForwarder* pEditViewForwarder = mpAdaptee->GetEditViewForwarder(bCreate);
367 if( pEditViewForwarder )
369 SvxAccessibleTextAdapter* pTextAdapter = GetTextForwarderAdapter();
371 if( pTextAdapter )
373 maEditViewAdapter.SetForwarder(*pEditViewForwarder, *pTextAdapter);
375 return &maEditViewAdapter;
380 return NULL;
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 )
404 if( pAdaptee.get() )
406 mpAdaptee = std::move(pAdaptee);
407 mbEditSourceValid = true;
409 else
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()) );
504 // insert bullet
505 sStr = sStr.replaceAt( GetTextLen(aStartIndex.GetParagraph()) - aStartIndex.GetIndex(), 0, sBullet );
508 return sStr;
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),
560 nWhich );
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();
661 else
662 return false;
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
728 if( pOutDev )
730 AccessibleStringWrap aStringWrap( *pOutDev, aBulletInfo.aFont, aBulletInfo.aText );
732 aStringWrap.GetCharacterBounds( aIndex.GetBulletOffset(), aRect );
733 aRect.Move( aBulletInfo.aBounds.Left(), aBulletInfo.aBounds.Top() );
736 else
738 // handle field content manually
739 if( aIndex.InField() )
741 OutputDevice* pOutDev = GetRefDevice();
743 DBG_ASSERT(pOutDev!=NULL, "SvxAccessibleTextAdapter::GetCharBounds: No ref device");
745 if( pOutDev )
747 ESelection aSel = MakeEESelection( aIndex );
749 SvxFont aFont = EditEngine::CreateSvxFontFromItemSet( mpTextForwarder->GetAttribs( aSel ) );
750 AccessibleStringWrap aStringWrap( *pOutDev,
751 aFont,
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() );
762 return aRect;
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 );
780 return aRect;
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 ) )
805 return false;
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 );
817 // any text bullets?
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");
828 if( !pOutDev )
829 return false;
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 );
841 return true;
845 if( aIndex.InField() )
847 OutputDevice* pOutDev = GetRefDevice();
849 DBG_ASSERT(pOutDev!=NULL, "SvxAccessibleTextAdapter::GetIndexAtPoint: No ref device");
851 if( !pOutDev )
852 return false;
854 ESelection aSelection = MakeEESelection( aIndex );
855 SvxFont aFont = EditEngine::CreateSvxFontFromItemSet( mpTextForwarder->GetAttribs( aSelection ) );
856 AccessibleStringWrap aStringWrap( *pOutDev,
857 aFont,
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 ));
869 return true;
872 return true;
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
890 nStart = 0;
891 nEnd = aIndex.GetBulletLen();
893 return true;
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();
909 return true;
912 if( !mpTextForwarder->GetWordIndices( nPara, nIndex, nStart, nEnd ) )
913 return false;
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();
927 return true;
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
945 nStartIndex = 0;
946 nEndIndex = aIndex.GetBulletLen();
948 return true;
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();
961 return true;
964 if( !mpTextForwarder->GetAttributeRun( nStartIndex, nEndIndex, nPara, nIndex ) )
965 return false;
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();
979 return true;
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;
995 sal_Int32 nCurrLine;
996 sal_Int32 nCurrIndex, nLastIndex;
997 for( nCurrLine=0, nCurrIndex=0, nLastIndex=0; nCurrLine<=nLine; ++nCurrLine )
999 nLastIndex = nCurrIndex;
1000 nCurrIndex =
1001 nCurrIndex + mpTextForwarder->GetLineLen( nPara, nCurrLine );
1004 aEndIndex.SetEEIndex( nPara, nCurrIndex, *this );
1005 if( nLine > 0 )
1007 aStartIndex.SetEEIndex( nPara, nLastIndex, *this );
1009 return aEndIndex.GetIndex() - aStartIndex.GetIndex();
1011 else
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" );
1116 return 0;
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" );
1127 return 0;
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();
1150 else
1151 return false;
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 ) )
1182 return false;
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() );
1197 return true;
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: */