bump product version to 6.3.0.0.beta1
[LibreOffice.git] / editeng / source / uno / unoedprx.cxx
blob35784061f5015e137499ef53a369a6e7fce24fd7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 // Global header
24 #include <limits.h>
25 #include <utility>
26 #include <memory>
27 #include <vector>
28 #include <algorithm>
29 #include <vcl/window.hxx>
30 #include <vcl/svapp.hxx>
31 #include <tools/debug.hxx>
34 // Project-local header
37 #include <editeng/unoedprx.hxx>
38 #include <editeng/unotext.hxx>
39 #include <editeng/unoedhlp.hxx>
40 #include <editeng/editdata.hxx>
41 #include <editeng/editeng.hxx>
42 #include <editeng/editview.hxx>
43 #include <editeng/AccessibleStringWrap.hxx>
44 #include <editeng/outliner.hxx>
46 using namespace ::com::sun::star;
49 class SvxAccessibleTextIndex
51 public:
52 SvxAccessibleTextIndex() :
53 mnPara(0),
54 mnIndex(0),
55 mnEEIndex(0),
56 mnFieldOffset(0),
57 mnFieldLen(0),
58 mbInField(false),
59 mnBulletOffset(0),
60 mnBulletLen(0),
61 mbInBullet(false) {};
63 // Get/Set current paragraph
64 void SetParagraph( sal_Int32 nPara )
66 mnPara = nPara;
68 sal_Int32 GetParagraph() const { return mnPara; }
70 /** Set the index in the UAA semantic
72 @param nIndex
73 The index from the UA API (fields and bullets are expanded)
75 @param rTF
76 The text forwarder to use in the calculations
78 void SetIndex( sal_Int32 nIndex, const SvxTextForwarder& rTF );
79 void SetIndex( sal_Int32 nPara, sal_Int32 nIndex, const SvxTextForwarder& rTF ) { SetParagraph(nPara); SetIndex(nIndex, rTF); }
80 sal_Int32 GetIndex() const { return mnIndex; }
82 /** Set the index in the edit engine semantic
84 Update the object state to reflect the given index position in
85 EditEngine/Outliner index values
87 @param nEEIndex
88 The index from the edit engine (fields span exactly one index increment)
90 @param rTF
91 The text forwarder to use in the calculations
93 void SetEEIndex( sal_Int32 nEEIndex, const SvxTextForwarder& rTF );
94 void SetEEIndex( sal_Int32 nPara, sal_Int32 nEEIndex, const SvxTextForwarder& rTF ) { SetParagraph(nPara); SetEEIndex(nEEIndex, rTF); }
95 sal_Int32 GetEEIndex() const;
97 void SetFieldOffset( sal_Int32 nOffset, sal_Int32 nLen ) { mnFieldOffset = nOffset; mnFieldLen = nLen; }
98 sal_Int32 GetFieldOffset() const { return mnFieldOffset; }
99 sal_Int32 GetFieldLen() const { return mnFieldLen; }
100 void AreInField() { mbInField = true; }
101 bool InField() const { return mbInField; }
103 void SetBulletOffset( sal_Int32 nOffset, sal_Int32 nLen ) { mnBulletOffset = nOffset; mnBulletLen = nLen; }
104 sal_Int32 GetBulletOffset() const { return mnBulletOffset; }
105 sal_Int32 GetBulletLen() const { return mnBulletLen; }
106 bool InBullet() const { return mbInBullet; }
108 /// returns false if the given range is non-editable (e.g. contains bullets or _parts_ of fields)
109 bool IsEditableRange( const SvxAccessibleTextIndex& rEnd ) const;
111 private:
112 sal_Int32 mnPara;
113 sal_Int32 mnIndex;
114 sal_Int32 mnEEIndex;
115 sal_Int32 mnFieldOffset;
116 sal_Int32 mnFieldLen;
117 bool mbInField;
118 sal_Int32 mnBulletOffset;
119 sal_Int32 mnBulletLen;
120 bool mbInBullet;
123 static ESelection MakeEESelection( const SvxAccessibleTextIndex& rStart, const SvxAccessibleTextIndex& rEnd )
125 // deal with field special case: to really get a field contained
126 // within a selection, the start index must be before or on the
127 // field, the end index after it.
129 // The SvxAccessibleTextIndex.GetEEIndex method gives the index on
130 // the field, as long the input index is on the field. Thus,
131 // correction necessary for the end index
133 // Therefore, for _ranges_, if part of the field is touched, all
134 // of the field must be selected
135 if( rStart.GetParagraph() <= rEnd.GetParagraph() ||
136 (rStart.GetParagraph() == rEnd.GetParagraph() &&
137 rStart.GetEEIndex() <= rEnd.GetEEIndex()) )
139 if( rEnd.InField() && rEnd.GetFieldOffset() )
140 return ESelection( rStart.GetParagraph(), rStart.GetEEIndex(),
141 rEnd.GetParagraph(), rEnd.GetEEIndex()+1 );
143 else if( rStart.GetParagraph() > rEnd.GetParagraph() ||
144 (rStart.GetParagraph() == rEnd.GetParagraph() &&
145 rStart.GetEEIndex() > rEnd.GetEEIndex()) )
147 if( rStart.InField() && rStart.GetFieldOffset() )
148 return ESelection( rStart.GetParagraph(), rStart.GetEEIndex()+1,
149 rEnd.GetParagraph(), rEnd.GetEEIndex() );
152 return ESelection( rStart.GetParagraph(), rStart.GetEEIndex(),
153 rEnd.GetParagraph(), rEnd.GetEEIndex() );
156 static ESelection MakeEESelection( const SvxAccessibleTextIndex& rIndex )
158 return ESelection( rIndex.GetParagraph(), rIndex.GetEEIndex(),
159 rIndex.GetParagraph(), rIndex.GetEEIndex() + 1 );
162 sal_Int32 SvxAccessibleTextIndex::GetEEIndex() const
164 DBG_ASSERT(mnEEIndex >= 0,
165 "SvxAccessibleTextIndex::GetEEIndex: index value overflow");
167 return mnEEIndex;
170 void SvxAccessibleTextIndex::SetEEIndex( sal_Int32 nEEIndex, const SvxTextForwarder& rTF )
172 // reset
173 mnFieldOffset = 0;
174 mbInField = false;
175 mnFieldLen = 0;
176 mnBulletOffset = 0;
177 mbInBullet = false;
178 mnBulletLen = 0;
180 // set known values
181 mnEEIndex = nEEIndex;
183 // calculate unknowns
184 sal_Int32 nCurrField, nFieldCount = rTF.GetFieldCount( GetParagraph() );
186 mnIndex = nEEIndex;
188 EBulletInfo aBulletInfo = rTF.GetBulletInfo( GetParagraph() );
190 // any text bullets?
191 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
192 aBulletInfo.bVisible &&
193 aBulletInfo.nType != SVX_NUM_BITMAP )
195 mnIndex += aBulletInfo.aText.getLength();
198 for( nCurrField=0; nCurrField < nFieldCount; ++nCurrField )
200 EFieldInfo aFieldInfo( rTF.GetFieldInfo( GetParagraph(), nCurrField ) );
202 if( aFieldInfo.aPosition.nIndex > nEEIndex )
203 break;
205 if( aFieldInfo.aPosition.nIndex == nEEIndex )
207 AreInField();
208 break;
211 mnIndex += std::max(aFieldInfo.aCurrentText.getLength()-1, sal_Int32(0));
215 void SvxAccessibleTextIndex::SetIndex( sal_Int32 nIndex, const SvxTextForwarder& rTF )
217 // reset
218 mnFieldOffset = 0;
219 mbInField = false;
220 mnFieldLen = 0;
221 mnBulletOffset = 0;
222 mbInBullet = false;
223 mnBulletLen = 0;
225 // set known values
226 mnIndex = nIndex;
228 // calculate unknowns
229 sal_Int32 nCurrField, nFieldCount = rTF.GetFieldCount( GetParagraph() );
231 DBG_ASSERT(nIndex >= 0,
232 "SvxAccessibleTextIndex::SetIndex: index value overflow");
234 mnEEIndex = nIndex;
236 EBulletInfo aBulletInfo = rTF.GetBulletInfo( GetParagraph() );
238 // any text bullets?
239 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
240 aBulletInfo.bVisible &&
241 aBulletInfo.nType != SVX_NUM_BITMAP )
243 sal_Int32 nBulletLen = aBulletInfo.aText.getLength();
245 if( nIndex < nBulletLen )
247 mbInBullet = true;
248 SetBulletOffset( nIndex, nBulletLen );
249 mnEEIndex = 0;
250 return;
253 mnEEIndex = mnEEIndex - nBulletLen;
256 for( nCurrField=0; nCurrField < nFieldCount; ++nCurrField )
258 EFieldInfo aFieldInfo( rTF.GetFieldInfo( GetParagraph(), nCurrField ) );
260 // we're before a field
261 if( aFieldInfo.aPosition.nIndex > mnEEIndex )
262 break;
264 mnEEIndex -= std::max(aFieldInfo.aCurrentText.getLength()-1, sal_Int32(0));
266 // we're within a field
267 if( aFieldInfo.aPosition.nIndex >= mnEEIndex )
269 AreInField();
270 SetFieldOffset( std::max(aFieldInfo.aCurrentText.getLength()-1, sal_Int32(0)) - (aFieldInfo.aPosition.nIndex - mnEEIndex),
271 aFieldInfo.aCurrentText.getLength() );
272 mnEEIndex = aFieldInfo.aPosition.nIndex ;
273 break;
278 bool SvxAccessibleTextIndex::IsEditableRange( const SvxAccessibleTextIndex& rEnd ) const
280 if( GetIndex() > rEnd.GetIndex() )
281 return rEnd.IsEditableRange( *this );
283 if( InBullet() || rEnd.InBullet() )
284 return false;
286 if( InField() && GetFieldOffset() )
287 return false; // within field
289 if( rEnd.InField() && rEnd.GetFieldOffset() >= rEnd.GetFieldLen() - 1 )
290 return false; // within field
292 return true;
296 SvxEditSourceAdapter::SvxEditSourceAdapter() : mbEditSourceValid( false )
300 SvxEditSourceAdapter::~SvxEditSourceAdapter()
304 std::unique_ptr<SvxEditSource> SvxEditSourceAdapter::Clone() const
306 if( mbEditSourceValid && mpAdaptee.get() )
308 std::unique_ptr< SvxEditSource > pClonedAdaptee( mpAdaptee->Clone() );
310 if (pClonedAdaptee)
312 std::unique_ptr<SvxEditSourceAdapter> pClone(new SvxEditSourceAdapter());
313 pClone->SetEditSource( std::move(pClonedAdaptee) );
314 return std::unique_ptr< SvxEditSource >(pClone.release());
318 return nullptr;
321 SvxAccessibleTextAdapter* SvxEditSourceAdapter::GetTextForwarderAdapter()
323 if( mbEditSourceValid && mpAdaptee.get() )
325 SvxTextForwarder* pTextForwarder = mpAdaptee->GetTextForwarder();
327 if( pTextForwarder )
329 maTextAdapter.SetForwarder(*pTextForwarder);
331 return &maTextAdapter;
335 return nullptr;
338 SvxTextForwarder* SvxEditSourceAdapter::GetTextForwarder()
340 return GetTextForwarderAdapter();
343 SvxViewForwarder* SvxEditSourceAdapter::GetViewForwarder()
345 if( mbEditSourceValid && mpAdaptee.get() )
346 return mpAdaptee->GetViewForwarder();
348 return nullptr;
351 SvxAccessibleTextEditViewAdapter* SvxEditSourceAdapter::GetEditViewForwarderAdapter( bool bCreate )
353 if( mbEditSourceValid && mpAdaptee.get() )
355 SvxEditViewForwarder* pEditViewForwarder = mpAdaptee->GetEditViewForwarder(bCreate);
357 if( pEditViewForwarder )
359 SvxAccessibleTextAdapter* pTextAdapter = GetTextForwarderAdapter();
361 if( pTextAdapter )
363 maEditViewAdapter.SetForwarder(*pEditViewForwarder, *pTextAdapter);
365 return &maEditViewAdapter;
370 return nullptr;
373 SvxEditViewForwarder* SvxEditSourceAdapter::GetEditViewForwarder( bool bCreate )
375 return GetEditViewForwarderAdapter( bCreate );
378 void SvxEditSourceAdapter::UpdateData()
380 if( mbEditSourceValid && mpAdaptee.get() )
381 mpAdaptee->UpdateData();
384 SfxBroadcaster& SvxEditSourceAdapter::GetBroadcaster() const
386 if( mbEditSourceValid && mpAdaptee.get() )
387 return mpAdaptee->GetBroadcaster();
389 return maDummyBroadcaster;
392 void SvxEditSourceAdapter::SetEditSource( std::unique_ptr< SvxEditSource > && pAdaptee )
394 if (pAdaptee)
396 mpAdaptee = std::move(pAdaptee);
397 mbEditSourceValid = true;
399 else
401 // do a lazy delete (prevents us from deleting the broadcaster
402 // from within a broadcast in
403 // AccessibleTextHelper_Impl::Notify)
404 mbEditSourceValid = false;
408 SvxAccessibleTextAdapter::SvxAccessibleTextAdapter()
409 : mpTextForwarder(nullptr)
413 SvxAccessibleTextAdapter::~SvxAccessibleTextAdapter()
417 sal_Int32 SvxAccessibleTextAdapter::GetParagraphCount() const
419 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
421 return mpTextForwarder->GetParagraphCount();
424 sal_Int32 SvxAccessibleTextAdapter::GetTextLen( sal_Int32 nParagraph ) const
426 SvxAccessibleTextIndex aIndex;
427 aIndex.SetEEIndex( nParagraph, mpTextForwarder->GetTextLen( nParagraph ), *this );
429 return aIndex.GetIndex();
432 OUString SvxAccessibleTextAdapter::GetText( const ESelection& rSel ) const
434 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
436 SvxAccessibleTextIndex aStartIndex;
437 SvxAccessibleTextIndex aEndIndex;
439 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
440 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
442 // normalize selection
443 if( rSel.nStartPara > rSel.nEndPara ||
444 (rSel.nStartPara == rSel.nEndPara && rSel.nStartPos > rSel.nEndPos) )
446 std::swap( aStartIndex, aEndIndex );
449 OUString sStr = mpTextForwarder->GetText( MakeEESelection(aStartIndex, aEndIndex) );
451 // trim field text, if necessary
452 if( aStartIndex.InField() )
454 DBG_ASSERT(aStartIndex.GetFieldOffset() >= 0,
455 "SvxAccessibleTextIndex::GetText: index value overflow");
457 sStr = sStr.copy( aStartIndex.GetFieldOffset() );
459 if( aEndIndex.InField() && aEndIndex.GetFieldOffset() )
461 DBG_ASSERT(sStr.getLength() - (aEndIndex.GetFieldLen() - aEndIndex.GetFieldOffset()) >= 0,
462 "SvxAccessibleTextIndex::GetText: index value overflow");
464 sStr = sStr.copy(0, sStr.getLength() - (aEndIndex.GetFieldLen() - aEndIndex.GetFieldOffset()) );
467 EBulletInfo aBulletInfo1 = GetBulletInfo( aStartIndex.GetParagraph() );
468 EBulletInfo aBulletInfo2 = GetBulletInfo( aEndIndex.GetParagraph() );
470 if( aEndIndex.InBullet() )
472 // append trailing bullet
473 sStr += aBulletInfo2.aText;
475 DBG_ASSERT(sStr.getLength() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset()) >= 0,
476 "SvxAccessibleTextIndex::GetText: index value overflow");
478 sStr = sStr.copy(0, sStr.getLength() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset()) );
480 else if( aStartIndex.GetParagraph() != aEndIndex.GetParagraph() &&
481 HaveTextBullet( aEndIndex.GetParagraph() ) )
483 OUString sBullet = aBulletInfo2.aText;
485 DBG_ASSERT(sBullet.getLength() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset()) >= 0,
486 "SvxAccessibleTextIndex::GetText: index value overflow");
488 sBullet = sBullet.copy(0, sBullet.getLength() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset()) );
490 // insert bullet
491 sStr = sStr.replaceAt( GetTextLen(aStartIndex.GetParagraph()) - aStartIndex.GetIndex(), 0, sBullet );
494 return sStr;
497 SfxItemSet SvxAccessibleTextAdapter::GetAttribs( const ESelection& rSel, EditEngineAttribs nOnlyHardAttrib ) const
499 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
501 SvxAccessibleTextIndex aStartIndex;
502 SvxAccessibleTextIndex aEndIndex;
504 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
505 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
507 return mpTextForwarder->GetAttribs( MakeEESelection(aStartIndex, aEndIndex), nOnlyHardAttrib );
510 SfxItemSet SvxAccessibleTextAdapter::GetParaAttribs( sal_Int32 nPara ) const
512 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
514 return mpTextForwarder->GetParaAttribs( nPara );
517 void SvxAccessibleTextAdapter::SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet )
519 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
521 mpTextForwarder->SetParaAttribs( nPara, rSet );
524 void SvxAccessibleTextAdapter::RemoveAttribs( const ESelection& )
528 void SvxAccessibleTextAdapter::GetPortions( sal_Int32 nPara, std::vector<sal_Int32>& rList ) const
530 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
532 mpTextForwarder->GetPortions( nPara, rList );
535 SfxItemState SvxAccessibleTextAdapter::GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const
537 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
539 SvxAccessibleTextIndex aStartIndex;
540 SvxAccessibleTextIndex aEndIndex;
542 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
543 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
545 return mpTextForwarder->GetItemState( MakeEESelection(aStartIndex, aEndIndex),
546 nWhich );
549 SfxItemState SvxAccessibleTextAdapter::GetItemState( sal_Int32 nPara, sal_uInt16 nWhich ) const
551 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
553 return mpTextForwarder->GetItemState( nPara, nWhich );
556 void SvxAccessibleTextAdapter::QuickInsertText( const OUString& rText, const ESelection& rSel )
558 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
560 SvxAccessibleTextIndex aStartIndex;
561 SvxAccessibleTextIndex aEndIndex;
563 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
564 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
566 mpTextForwarder->QuickInsertText( rText,
567 MakeEESelection(aStartIndex, aEndIndex) );
570 void SvxAccessibleTextAdapter::QuickInsertField( const SvxFieldItem& rFld, 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->QuickInsertField( rFld,
581 MakeEESelection(aStartIndex, aEndIndex) );
584 void SvxAccessibleTextAdapter::QuickSetAttribs( const SfxItemSet& rSet, 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->QuickSetAttribs( rSet,
595 MakeEESelection(aStartIndex, aEndIndex) );
598 void SvxAccessibleTextAdapter::QuickInsertLineBreak( 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->QuickInsertLineBreak( MakeEESelection(aStartIndex, aEndIndex) );
611 SfxItemPool* SvxAccessibleTextAdapter::GetPool() const
613 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
615 return mpTextForwarder->GetPool();
618 OUString SvxAccessibleTextAdapter::CalcFieldValue( const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos, boost::optional<Color>& rpTxtColor, boost::optional<Color>& rpFldColor )
620 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
622 return mpTextForwarder->CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor );
625 void SvxAccessibleTextAdapter::FieldClicked( const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos )
627 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
629 mpTextForwarder->FieldClicked( rField, nPara, nPos );
632 sal_Int32 SvxAccessibleTextAdapter::CalcEditEngineIndex( sal_Int32 nPara, sal_Int32 nLogicalIndex )
634 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
636 SvxAccessibleTextIndex aIndex;
637 aIndex.SetIndex(nPara, nLogicalIndex, *mpTextForwarder);
638 return aIndex.GetEEIndex();
641 bool SvxAccessibleTextAdapter::IsValid() const
643 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
645 if( mpTextForwarder )
646 return mpTextForwarder->IsValid();
647 else
648 return false;
651 LanguageType SvxAccessibleTextAdapter::GetLanguage( sal_Int32 nPara, sal_Int32 nPos ) const
653 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
655 SvxAccessibleTextIndex aIndex;
657 aIndex.SetIndex( nPara, nPos, *this );
659 return mpTextForwarder->GetLanguage( nPara, aIndex.GetEEIndex() );
662 sal_Int32 SvxAccessibleTextAdapter::GetFieldCount( sal_Int32 nPara ) const
664 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
666 return mpTextForwarder->GetFieldCount( nPara );
669 EFieldInfo SvxAccessibleTextAdapter::GetFieldInfo( sal_Int32 nPara, sal_uInt16 nField ) const
671 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
673 return mpTextForwarder->GetFieldInfo( nPara, nField );
676 EBulletInfo SvxAccessibleTextAdapter::GetBulletInfo( sal_Int32 nPara ) const
678 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
680 return mpTextForwarder->GetBulletInfo( nPara );
683 tools::Rectangle SvxAccessibleTextAdapter::GetCharBounds( sal_Int32 nPara, sal_Int32 nIndex ) const
685 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
687 SvxAccessibleTextIndex aIndex;
688 aIndex.SetIndex( nPara, nIndex, *this );
690 // preset if anything goes wrong below
691 // n-th char in GetParagraphIndex's paragraph
692 tools::Rectangle aRect = mpTextForwarder->GetCharBounds( nPara, aIndex.GetEEIndex() );
694 if( aIndex.InBullet() )
696 EBulletInfo aBulletInfo = GetBulletInfo( nPara );
698 OutputDevice* pOutDev = GetRefDevice();
700 DBG_ASSERT(pOutDev!=nullptr, "SvxAccessibleTextAdapter::GetCharBounds: No ref device");
702 // preset if anything goes wrong below
703 aRect = aBulletInfo.aBounds; // better than nothing
704 if( pOutDev )
706 AccessibleStringWrap aStringWrap( *pOutDev, aBulletInfo.aFont, aBulletInfo.aText );
708 aStringWrap.GetCharacterBounds( aIndex.GetBulletOffset(), aRect );
709 aRect.Move( aBulletInfo.aBounds.Left(), aBulletInfo.aBounds.Top() );
712 else
714 // handle field content manually
715 if( aIndex.InField() )
717 OutputDevice* pOutDev = GetRefDevice();
719 DBG_ASSERT(pOutDev!=nullptr, "SvxAccessibleTextAdapter::GetCharBounds: No ref device");
721 if( pOutDev )
723 ESelection aSel = MakeEESelection( aIndex );
725 SvxFont aFont = EditEngine::CreateSvxFontFromItemSet( mpTextForwarder->GetAttribs( aSel ) );
726 AccessibleStringWrap aStringWrap( *pOutDev,
727 aFont,
728 mpTextForwarder->GetText( aSel ) );
730 tools::Rectangle aStartRect = mpTextForwarder->GetCharBounds( nPara, aIndex.GetEEIndex() );
732 aStringWrap.GetCharacterBounds( aIndex.GetFieldOffset(), aRect );
733 aRect.Move( aStartRect.Left(), aStartRect.Top() );
738 return aRect;
741 tools::Rectangle SvxAccessibleTextAdapter::GetParaBounds( sal_Int32 nPara ) const
743 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
745 EBulletInfo aBulletInfo = GetBulletInfo( nPara );
747 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
748 aBulletInfo.bVisible &&
749 aBulletInfo.nType != SVX_NUM_BITMAP )
751 // include bullet in para bounding box
752 tools::Rectangle aRect( mpTextForwarder->GetParaBounds( nPara ) );
754 aRect.Union( aBulletInfo.aBounds );
756 return aRect;
759 return mpTextForwarder->GetParaBounds( nPara );
762 MapMode SvxAccessibleTextAdapter::GetMapMode() const
764 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
766 return mpTextForwarder->GetMapMode();
769 OutputDevice* SvxAccessibleTextAdapter::GetRefDevice() const
771 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
773 return mpTextForwarder->GetRefDevice();
776 bool SvxAccessibleTextAdapter::GetIndexAtPoint( const Point& rPoint, sal_Int32& nPara, sal_Int32& nIndex ) const
778 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
780 if( !mpTextForwarder->GetIndexAtPoint( rPoint, nPara, nIndex ) )
781 return false;
783 SvxAccessibleTextIndex aIndex;
784 aIndex.SetEEIndex(nPara, nIndex, *this);
786 DBG_ASSERT(aIndex.GetIndex() >= 0,
787 "SvxAccessibleTextIndex::SetIndex: index value overflow");
789 nIndex = aIndex.GetIndex();
791 EBulletInfo aBulletInfo = GetBulletInfo( nPara );
793 // any text bullets?
794 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
795 aBulletInfo.bVisible &&
796 aBulletInfo.nType != SVX_NUM_BITMAP )
798 if( aBulletInfo.aBounds.IsInside( rPoint) )
800 OutputDevice* pOutDev = GetRefDevice();
802 DBG_ASSERT(pOutDev!=nullptr, "SvxAccessibleTextAdapter::GetIndexAtPoint: No ref device");
804 if( !pOutDev )
805 return false;
807 AccessibleStringWrap aStringWrap( *pOutDev, aBulletInfo.aFont, aBulletInfo.aText );
809 Point aPoint = rPoint;
810 aPoint.Move( -aBulletInfo.aBounds.Left(), -aBulletInfo.aBounds.Top() );
812 DBG_ASSERT(aStringWrap.GetIndexAtPoint( aPoint ) >= 0,
813 "SvxAccessibleTextIndex::SetIndex: index value overflow");
815 nIndex = aStringWrap.GetIndexAtPoint( aPoint );
816 return true;
820 if( aIndex.InField() )
822 OutputDevice* pOutDev = GetRefDevice();
824 DBG_ASSERT(pOutDev!=nullptr, "SvxAccessibleTextAdapter::GetIndexAtPoint: No ref device");
826 if( !pOutDev )
827 return false;
829 ESelection aSelection = MakeEESelection( aIndex );
830 SvxFont aFont = EditEngine::CreateSvxFontFromItemSet( mpTextForwarder->GetAttribs( aSelection ) );
831 AccessibleStringWrap aStringWrap( *pOutDev,
832 aFont,
833 mpTextForwarder->GetText( aSelection ) );
835 tools::Rectangle aRect = mpTextForwarder->GetCharBounds( nPara, aIndex.GetEEIndex() );
836 Point aPoint = rPoint;
837 aPoint.Move( -aRect.Left(), -aRect.Top() );
839 DBG_ASSERT(aIndex.GetIndex() + aStringWrap.GetIndexAtPoint( rPoint ) >= 0,
840 "SvxAccessibleTextIndex::SetIndex: index value overflow");
842 nIndex = (aIndex.GetIndex() + aStringWrap.GetIndexAtPoint( aPoint ));
843 return true;
846 return true;
849 bool SvxAccessibleTextAdapter::GetWordIndices( sal_Int32 nPara, sal_Int32 nIndex, sal_Int32& nStart, sal_Int32& nEnd ) const
851 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
853 SvxAccessibleTextIndex aIndex;
854 aIndex.SetIndex(nPara, nIndex, *this);
855 nIndex = aIndex.GetEEIndex();
857 if( aIndex.InBullet() )
859 DBG_ASSERT(aIndex.GetBulletLen() >= 0,
860 "SvxAccessibleTextIndex::SetIndex: index value overflow");
862 // always treat bullet as separate word
863 nStart = 0;
864 nEnd = aIndex.GetBulletLen();
866 return true;
869 if( aIndex.InField() )
871 DBG_ASSERT(aIndex.GetIndex() - aIndex.GetFieldOffset() >= 0 &&
872 nStart + aIndex.GetFieldLen() >= 0,
873 "SvxAccessibleTextIndex::SetIndex: index value overflow");
875 // always treat field as separate word
876 // TODO: to circumvent this, _we_ would have to do the break iterator stuff!
877 nStart = aIndex.GetIndex() - aIndex.GetFieldOffset();
878 nEnd = nStart + aIndex.GetFieldLen();
880 return true;
883 if( !mpTextForwarder->GetWordIndices( nPara, nIndex, nStart, nEnd ) )
884 return false;
886 aIndex.SetEEIndex( nPara, nStart, *this );
887 DBG_ASSERT(aIndex.GetIndex() >= 0,
888 "SvxAccessibleTextIndex::SetIndex: index value overflow");
889 nStart = aIndex.GetIndex();
891 aIndex.SetEEIndex( nPara, nEnd, *this );
892 DBG_ASSERT(aIndex.GetIndex() >= 0,
893 "SvxAccessibleTextIndex::SetIndex: index value overflow");
894 nEnd = aIndex.GetIndex();
896 return true;
899 bool SvxAccessibleTextAdapter::GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nPara, sal_Int32 nIndex, bool /* bInCell */ ) const
901 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
903 SvxAccessibleTextIndex aIndex;
904 aIndex.SetIndex(nPara, nIndex, *this);
905 nIndex = aIndex.GetEEIndex();
907 if( aIndex.InBullet() )
909 DBG_ASSERT(aIndex.GetBulletLen() >= 0,
910 "SvxAccessibleTextIndex::SetIndex: index value overflow");
912 // always treat bullet as distinct attribute
913 nStartIndex = 0;
914 nEndIndex = aIndex.GetBulletLen();
916 return true;
919 if( aIndex.InField() )
921 DBG_ASSERT(aIndex.GetIndex() - aIndex.GetFieldOffset() >= 0,
922 "SvxAccessibleTextIndex::SetIndex: index value overflow");
924 // always treat field as distinct attribute
925 nStartIndex = aIndex.GetIndex() - aIndex.GetFieldOffset();
926 nEndIndex = nStartIndex + aIndex.GetFieldLen();
928 return true;
931 if( !mpTextForwarder->GetAttributeRun( nStartIndex, nEndIndex, nPara, nIndex ) )
932 return false;
934 aIndex.SetEEIndex( nPara, nStartIndex, *this );
935 DBG_ASSERT(aIndex.GetIndex() >= 0,
936 "SvxAccessibleTextIndex::SetIndex: index value overflow");
937 nStartIndex = aIndex.GetIndex();
939 aIndex.SetEEIndex( nPara, nEndIndex, *this );
940 DBG_ASSERT(aIndex.GetIndex() >= 0,
941 "SvxAccessibleTextIndex::SetIndex: index value overflow");
942 nEndIndex = aIndex.GetIndex();
944 return true;
947 sal_Int32 SvxAccessibleTextAdapter::GetLineCount( sal_Int32 nPara ) const
949 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
951 return mpTextForwarder->GetLineCount( nPara );
954 sal_Int32 SvxAccessibleTextAdapter::GetLineLen( sal_Int32 nPara, sal_Int32 nLine ) const
956 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
958 SvxAccessibleTextIndex aStartIndex;
959 SvxAccessibleTextIndex aEndIndex;
960 sal_Int32 nCurrLine;
961 sal_Int32 nCurrIndex, nLastIndex;
962 for( nCurrLine=0, nCurrIndex=0, nLastIndex=0; nCurrLine<=nLine; ++nCurrLine )
964 nLastIndex = nCurrIndex;
965 nCurrIndex =
966 nCurrIndex + mpTextForwarder->GetLineLen( nPara, nCurrLine );
969 aEndIndex.SetEEIndex( nPara, nCurrIndex, *this );
970 if( nLine > 0 )
972 aStartIndex.SetEEIndex( nPara, nLastIndex, *this );
974 return aEndIndex.GetIndex() - aStartIndex.GetIndex();
976 else
977 return aEndIndex.GetIndex();
980 void SvxAccessibleTextAdapter::GetLineBoundaries( /*out*/sal_Int32 &rStart, /*out*/sal_Int32 &rEnd, sal_Int32 nParagraph, sal_Int32 nLine ) const
982 mpTextForwarder->GetLineBoundaries( rStart, rEnd, nParagraph, nLine );
985 sal_Int32 SvxAccessibleTextAdapter::GetLineNumberAtIndex( sal_Int32 nPara, sal_Int32 nIndex ) const
987 return mpTextForwarder->GetLineNumberAtIndex( nPara, nIndex );
990 bool SvxAccessibleTextAdapter::Delete( const ESelection& rSel )
992 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
994 SvxAccessibleTextIndex aStartIndex;
995 SvxAccessibleTextIndex aEndIndex;
997 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
998 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
1000 return mpTextForwarder->Delete( MakeEESelection(aStartIndex, aEndIndex ) );
1003 bool SvxAccessibleTextAdapter::InsertText( const OUString& rStr, const ESelection& rSel )
1005 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
1007 SvxAccessibleTextIndex aStartIndex;
1008 SvxAccessibleTextIndex aEndIndex;
1010 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
1011 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
1013 return mpTextForwarder->InsertText( rStr, MakeEESelection(aStartIndex, aEndIndex) );
1016 bool SvxAccessibleTextAdapter::QuickFormatDoc( bool bFull )
1018 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
1020 return mpTextForwarder->QuickFormatDoc( bFull );
1023 sal_Int16 SvxAccessibleTextAdapter::GetDepth( sal_Int32 nPara ) const
1025 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
1027 return mpTextForwarder->GetDepth( nPara );
1030 bool SvxAccessibleTextAdapter::SetDepth( sal_Int32 nPara, sal_Int16 nNewDepth )
1032 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
1034 return mpTextForwarder->SetDepth( nPara, nNewDepth );
1037 void SvxAccessibleTextAdapter::SetForwarder( SvxTextForwarder& rForwarder )
1039 mpTextForwarder = &rForwarder;
1042 bool SvxAccessibleTextAdapter::HaveImageBullet( sal_Int32 nPara ) const
1044 EBulletInfo aBulletInfo = GetBulletInfo( nPara );
1046 return ( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
1047 aBulletInfo.bVisible &&
1048 aBulletInfo.nType == SVX_NUM_BITMAP );
1051 bool SvxAccessibleTextAdapter::HaveTextBullet( sal_Int32 nPara ) const
1053 EBulletInfo aBulletInfo = GetBulletInfo( nPara );
1055 return ( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
1056 aBulletInfo.bVisible &&
1057 aBulletInfo.nType != SVX_NUM_BITMAP );
1060 bool SvxAccessibleTextAdapter::IsEditable( const ESelection& rSel )
1062 SvxAccessibleTextIndex aStartIndex;
1063 SvxAccessibleTextIndex aEndIndex;
1065 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
1066 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
1068 // normalize selection
1069 if( rSel.nStartPara > rSel.nEndPara ||
1070 (rSel.nStartPara == rSel.nEndPara && rSel.nStartPos > rSel.nEndPos) )
1072 std::swap( aStartIndex, aEndIndex );
1075 return aStartIndex.IsEditableRange( aEndIndex );
1078 const SfxItemSet * SvxAccessibleTextAdapter::GetEmptyItemSetPtr()
1080 OSL_FAIL( "not implemented" );
1081 return nullptr;
1084 void SvxAccessibleTextAdapter::AppendParagraph()
1086 OSL_FAIL( "not implemented" );
1089 sal_Int32 SvxAccessibleTextAdapter::AppendTextPortion( sal_Int32, const OUString &, const SfxItemSet & )
1091 OSL_FAIL( "not implemented" );
1092 return 0;
1094 void SvxAccessibleTextAdapter::CopyText(const SvxTextForwarder&)
1096 OSL_FAIL( "not implemented" );
1099 SvxAccessibleTextEditViewAdapter::SvxAccessibleTextEditViewAdapter()
1100 : mpViewForwarder(nullptr)
1101 , mpTextForwarder(nullptr)
1105 SvxAccessibleTextEditViewAdapter::~SvxAccessibleTextEditViewAdapter()
1109 bool SvxAccessibleTextEditViewAdapter::IsValid() const
1111 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1113 if( mpViewForwarder )
1114 return mpViewForwarder->IsValid();
1115 else
1116 return false;
1119 Point SvxAccessibleTextEditViewAdapter::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
1121 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1123 return mpViewForwarder->LogicToPixel(rPoint, rMapMode);
1126 Point SvxAccessibleTextEditViewAdapter::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
1128 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1130 return mpViewForwarder->PixelToLogic(rPoint, rMapMode);
1133 bool SvxAccessibleTextEditViewAdapter::GetSelection( ESelection& rSel ) const
1135 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1137 ESelection aSelection;
1139 if( !mpViewForwarder->GetSelection( aSelection ) )
1140 return false;
1142 SvxAccessibleTextIndex aStartIndex;
1143 SvxAccessibleTextIndex aEndIndex;
1145 aStartIndex.SetEEIndex( aSelection.nStartPara, aSelection.nStartPos, *mpTextForwarder );
1146 aEndIndex.SetEEIndex( aSelection.nEndPara, aSelection.nEndPos, *mpTextForwarder );
1148 DBG_ASSERT(aStartIndex.GetIndex() >= 0 &&
1149 aEndIndex.GetIndex() >= 0,
1150 "SvxAccessibleTextEditViewAdapter::GetSelection: index value overflow");
1152 rSel = ESelection( aStartIndex.GetParagraph(), aStartIndex.GetIndex(),
1153 aEndIndex.GetParagraph(), aEndIndex.GetIndex() );
1155 return true;
1158 bool SvxAccessibleTextEditViewAdapter::SetSelection( const ESelection& rSel )
1160 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1162 SvxAccessibleTextIndex aStartIndex;
1163 SvxAccessibleTextIndex aEndIndex;
1165 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *mpTextForwarder );
1166 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *mpTextForwarder );
1168 return mpViewForwarder->SetSelection( MakeEESelection(aStartIndex, aEndIndex) );
1171 bool SvxAccessibleTextEditViewAdapter::Copy()
1173 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1175 return mpViewForwarder->Copy();
1178 bool SvxAccessibleTextEditViewAdapter::Cut()
1180 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1182 return mpViewForwarder->Cut();
1185 bool SvxAccessibleTextEditViewAdapter::Paste()
1187 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1189 return mpViewForwarder->Paste();
1192 void SvxAccessibleTextEditViewAdapter::SetForwarder( SvxEditViewForwarder& rForwarder,
1193 SvxAccessibleTextAdapter& rTextForwarder )
1195 mpViewForwarder = &rForwarder;
1196 mpTextForwarder = &rTextForwarder;
1199 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */