nss: upgrade to release 3.73
[LibreOffice.git] / editeng / source / uno / unoedprx.cxx
blob8cf7d8e624178f6dc6d3b02d0e70afc9929e389c
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 <utility>
25 #include <memory>
26 #include <vector>
27 #include <algorithm>
28 #include <osl/diagnose.h>
29 #include <svl/itemset.hxx>
30 #include <tools/debug.hxx>
33 // Project-local header
36 #include <editeng/unoedprx.hxx>
37 #include <editeng/editdata.hxx>
38 #include <editeng/editeng.hxx>
39 #include <AccessibleStringWrap.hxx>
40 #include <editeng/outliner.hxx>
42 using namespace ::com::sun::star;
44 namespace {
46 class SvxAccessibleTextIndex
48 public:
49 SvxAccessibleTextIndex() :
50 mnPara(0),
51 mnIndex(0),
52 mnEEIndex(0),
53 mnFieldOffset(0),
54 mnFieldLen(0),
55 mbInField(false),
56 mnBulletOffset(0),
57 mnBulletLen(0),
58 mbInBullet(false) {};
60 // Get/Set current paragraph
61 void SetParagraph( sal_Int32 nPara )
63 mnPara = nPara;
65 sal_Int32 GetParagraph() const { return mnPara; }
67 /** Set the index in the UAA semantic
69 @param nIndex
70 The index from the UA API (fields and bullets are expanded)
72 @param rTF
73 The text forwarder to use in the calculations
75 void SetIndex( sal_Int32 nIndex, const SvxTextForwarder& rTF );
76 void SetIndex( sal_Int32 nPara, sal_Int32 nIndex, const SvxTextForwarder& rTF ) { SetParagraph(nPara); SetIndex(nIndex, rTF); }
77 sal_Int32 GetIndex() const { return mnIndex; }
79 /** Set the index in the edit engine semantic
81 Update the object state to reflect the given index position in
82 EditEngine/Outliner index values
84 @param nEEIndex
85 The index from the edit engine (fields span exactly one index increment)
87 @param rTF
88 The text forwarder to use in the calculations
90 void SetEEIndex( sal_Int32 nEEIndex, const SvxTextForwarder& rTF );
91 void SetEEIndex( sal_Int32 nPara, sal_Int32 nEEIndex, const SvxTextForwarder& rTF ) { SetParagraph(nPara); SetEEIndex(nEEIndex, rTF); }
92 sal_Int32 GetEEIndex() const;
94 void SetFieldOffset( sal_Int32 nOffset, sal_Int32 nLen ) { mnFieldOffset = nOffset; mnFieldLen = nLen; }
95 sal_Int32 GetFieldOffset() const { return mnFieldOffset; }
96 sal_Int32 GetFieldLen() const { return mnFieldLen; }
97 void AreInField() { mbInField = true; }
98 bool InField() const { return mbInField; }
100 void SetBulletOffset( sal_Int32 nOffset, sal_Int32 nLen ) { mnBulletOffset = nOffset; mnBulletLen = nLen; }
101 sal_Int32 GetBulletOffset() const { return mnBulletOffset; }
102 sal_Int32 GetBulletLen() const { return mnBulletLen; }
103 bool InBullet() const { return mbInBullet; }
105 /// returns false if the given range is non-editable (e.g. contains bullets or _parts_ of fields)
106 bool IsEditableRange( const SvxAccessibleTextIndex& rEnd ) const;
108 private:
109 sal_Int32 mnPara;
110 sal_Int32 mnIndex;
111 sal_Int32 mnEEIndex;
112 sal_Int32 mnFieldOffset;
113 sal_Int32 mnFieldLen;
114 bool mbInField;
115 sal_Int32 mnBulletOffset;
116 sal_Int32 mnBulletLen;
117 bool mbInBullet;
122 static ESelection MakeEESelection( const SvxAccessibleTextIndex& rStart, const SvxAccessibleTextIndex& rEnd )
124 // deal with field special case: to really get a field contained
125 // within a selection, the start index must be before or on the
126 // field, the end index after it.
128 // The SvxAccessibleTextIndex.GetEEIndex method gives the index on
129 // the field, as long the input index is on the field. Thus,
130 // correction necessary for the end index
132 // Therefore, for _ranges_, if part of the field is touched, all
133 // of the field must be selected
134 if( rStart.GetParagraph() <= rEnd.GetParagraph() ||
135 (rStart.GetParagraph() == rEnd.GetParagraph() &&
136 rStart.GetEEIndex() <= rEnd.GetEEIndex()) )
138 if( rEnd.InField() && rEnd.GetFieldOffset() )
139 return ESelection( rStart.GetParagraph(), rStart.GetEEIndex(),
140 rEnd.GetParagraph(), rEnd.GetEEIndex()+1 );
142 else if( rStart.GetParagraph() > rEnd.GetParagraph() ||
143 (rStart.GetParagraph() == rEnd.GetParagraph() &&
144 rStart.GetEEIndex() > rEnd.GetEEIndex()) )
146 if( rStart.InField() && rStart.GetFieldOffset() )
147 return ESelection( rStart.GetParagraph(), rStart.GetEEIndex()+1,
148 rEnd.GetParagraph(), rEnd.GetEEIndex() );
151 return ESelection( rStart.GetParagraph(), rStart.GetEEIndex(),
152 rEnd.GetParagraph(), rEnd.GetEEIndex() );
155 static ESelection MakeEESelection( const SvxAccessibleTextIndex& rIndex )
157 return ESelection( rIndex.GetParagraph(), rIndex.GetEEIndex(),
158 rIndex.GetParagraph(), rIndex.GetEEIndex() + 1 );
161 sal_Int32 SvxAccessibleTextIndex::GetEEIndex() const
163 DBG_ASSERT(mnEEIndex >= 0,
164 "SvxAccessibleTextIndex::GetEEIndex: index value overflow");
166 return mnEEIndex;
169 void SvxAccessibleTextIndex::SetEEIndex( sal_Int32 nEEIndex, const SvxTextForwarder& rTF )
171 // reset
172 mnFieldOffset = 0;
173 mbInField = false;
174 mnFieldLen = 0;
175 mnBulletOffset = 0;
176 mbInBullet = false;
177 mnBulletLen = 0;
179 // set known values
180 mnEEIndex = nEEIndex;
182 // calculate unknowns
183 sal_Int32 nCurrField, nFieldCount = rTF.GetFieldCount( GetParagraph() );
185 mnIndex = nEEIndex;
187 EBulletInfo aBulletInfo = rTF.GetBulletInfo( GetParagraph() );
189 // any text bullets?
190 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
191 aBulletInfo.bVisible &&
192 aBulletInfo.nType != SVX_NUM_BITMAP )
194 mnIndex += aBulletInfo.aText.getLength();
197 for( nCurrField=0; nCurrField < nFieldCount; ++nCurrField )
199 EFieldInfo aFieldInfo( rTF.GetFieldInfo( GetParagraph(), nCurrField ) );
201 if( aFieldInfo.aPosition.nIndex > nEEIndex )
202 break;
204 if( aFieldInfo.aPosition.nIndex == nEEIndex )
206 AreInField();
207 break;
210 mnIndex += std::max(aFieldInfo.aCurrentText.getLength()-1, sal_Int32(0));
214 void SvxAccessibleTextIndex::SetIndex( sal_Int32 nIndex, const SvxTextForwarder& rTF )
216 // reset
217 mnFieldOffset = 0;
218 mbInField = false;
219 mnFieldLen = 0;
220 mnBulletOffset = 0;
221 mbInBullet = false;
222 mnBulletLen = 0;
224 // set known values
225 mnIndex = nIndex;
227 // calculate unknowns
228 sal_Int32 nCurrField, nFieldCount = rTF.GetFieldCount( GetParagraph() );
230 DBG_ASSERT(nIndex >= 0,
231 "SvxAccessibleTextIndex::SetIndex: index value overflow");
233 mnEEIndex = nIndex;
235 EBulletInfo aBulletInfo = rTF.GetBulletInfo( GetParagraph() );
237 // any text bullets?
238 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
239 aBulletInfo.bVisible &&
240 aBulletInfo.nType != SVX_NUM_BITMAP )
242 sal_Int32 nBulletLen = aBulletInfo.aText.getLength();
244 if( nIndex < nBulletLen )
246 mbInBullet = true;
247 SetBulletOffset( nIndex, nBulletLen );
248 mnEEIndex = 0;
249 return;
252 mnEEIndex = mnEEIndex - nBulletLen;
255 for( nCurrField=0; nCurrField < nFieldCount; ++nCurrField )
257 EFieldInfo aFieldInfo( rTF.GetFieldInfo( GetParagraph(), nCurrField ) );
259 // we're before a field
260 if( aFieldInfo.aPosition.nIndex > mnEEIndex )
261 break;
263 mnEEIndex -= std::max(aFieldInfo.aCurrentText.getLength()-1, sal_Int32(0));
265 // we're within a field
266 if( aFieldInfo.aPosition.nIndex >= mnEEIndex )
268 AreInField();
269 SetFieldOffset( std::max(aFieldInfo.aCurrentText.getLength()-1, sal_Int32(0)) - (aFieldInfo.aPosition.nIndex - mnEEIndex),
270 aFieldInfo.aCurrentText.getLength() );
271 mnEEIndex = aFieldInfo.aPosition.nIndex ;
272 break;
277 bool SvxAccessibleTextIndex::IsEditableRange( const SvxAccessibleTextIndex& rEnd ) const
279 if( GetIndex() > rEnd.GetIndex() )
280 return rEnd.IsEditableRange( *this );
282 if( InBullet() || rEnd.InBullet() )
283 return false;
285 if( InField() && GetFieldOffset() )
286 return false; // within field
288 if( rEnd.InField() && rEnd.GetFieldOffset() >= rEnd.GetFieldLen() - 1 )
289 return false; // within field
291 return true;
295 SvxEditSourceAdapter::SvxEditSourceAdapter() : mbEditSourceValid( false )
299 SvxEditSourceAdapter::~SvxEditSourceAdapter()
303 std::unique_ptr<SvxEditSource> SvxEditSourceAdapter::Clone() const
305 if( mbEditSourceValid && mpAdaptee )
307 std::unique_ptr< SvxEditSource > pClonedAdaptee( mpAdaptee->Clone() );
309 if (pClonedAdaptee)
311 std::unique_ptr<SvxEditSourceAdapter> pClone(new SvxEditSourceAdapter());
312 pClone->SetEditSource( std::move(pClonedAdaptee) );
313 return std::unique_ptr< SvxEditSource >(pClone.release());
317 return nullptr;
320 SvxAccessibleTextAdapter* SvxEditSourceAdapter::GetTextForwarderAdapter()
322 if( mbEditSourceValid && mpAdaptee )
324 SvxTextForwarder* pTextForwarder = mpAdaptee->GetTextForwarder();
326 if( pTextForwarder )
328 maTextAdapter.SetForwarder(*pTextForwarder);
330 return &maTextAdapter;
334 return nullptr;
337 SvxTextForwarder* SvxEditSourceAdapter::GetTextForwarder()
339 return GetTextForwarderAdapter();
342 SvxViewForwarder* SvxEditSourceAdapter::GetViewForwarder()
344 if( mbEditSourceValid && mpAdaptee )
345 return mpAdaptee->GetViewForwarder();
347 return nullptr;
350 SvxAccessibleTextEditViewAdapter* SvxEditSourceAdapter::GetEditViewForwarderAdapter( bool bCreate )
352 if( mbEditSourceValid && mpAdaptee )
354 SvxEditViewForwarder* pEditViewForwarder = mpAdaptee->GetEditViewForwarder(bCreate);
356 if( pEditViewForwarder )
358 SvxAccessibleTextAdapter* pTextAdapter = GetTextForwarderAdapter();
360 if( pTextAdapter )
362 maEditViewAdapter.SetForwarder(*pEditViewForwarder, *pTextAdapter);
364 return &maEditViewAdapter;
369 return nullptr;
372 SvxEditViewForwarder* SvxEditSourceAdapter::GetEditViewForwarder( bool bCreate )
374 return GetEditViewForwarderAdapter( bCreate );
377 void SvxEditSourceAdapter::UpdateData()
379 if( mbEditSourceValid && mpAdaptee )
380 mpAdaptee->UpdateData();
383 SfxBroadcaster& SvxEditSourceAdapter::GetBroadcaster() const
385 if( mbEditSourceValid && mpAdaptee )
386 return mpAdaptee->GetBroadcaster();
388 return maDummyBroadcaster;
391 void SvxEditSourceAdapter::SetEditSource( std::unique_ptr< SvxEditSource > && pAdaptee )
393 if (pAdaptee)
395 mpAdaptee = std::move(pAdaptee);
396 mbEditSourceValid = true;
398 else
400 // do a lazy delete (prevents us from deleting the broadcaster
401 // from within a broadcast in
402 // AccessibleTextHelper_Impl::Notify)
403 mbEditSourceValid = false;
407 SvxAccessibleTextAdapter::SvxAccessibleTextAdapter()
408 : mpTextForwarder(nullptr)
412 SvxAccessibleTextAdapter::~SvxAccessibleTextAdapter()
416 sal_Int32 SvxAccessibleTextAdapter::GetParagraphCount() const
418 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
420 return mpTextForwarder->GetParagraphCount();
423 sal_Int32 SvxAccessibleTextAdapter::GetTextLen( sal_Int32 nParagraph ) const
425 SvxAccessibleTextIndex aIndex;
426 aIndex.SetEEIndex( nParagraph, mpTextForwarder->GetTextLen( nParagraph ), *this );
428 return aIndex.GetIndex();
431 OUString SvxAccessibleTextAdapter::GetText( const ESelection& rSel ) const
433 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
435 SvxAccessibleTextIndex aStartIndex;
436 SvxAccessibleTextIndex aEndIndex;
438 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
439 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
441 // normalize selection
442 if( rSel.nStartPara > rSel.nEndPara ||
443 (rSel.nStartPara == rSel.nEndPara && rSel.nStartPos > rSel.nEndPos) )
445 std::swap( aStartIndex, aEndIndex );
448 OUString sStr = mpTextForwarder->GetText( MakeEESelection(aStartIndex, aEndIndex) );
450 // trim field text, if necessary
451 if( aStartIndex.InField() )
453 DBG_ASSERT(aStartIndex.GetFieldOffset() >= 0,
454 "SvxAccessibleTextIndex::GetText: index value overflow");
456 sStr = sStr.copy( aStartIndex.GetFieldOffset() );
458 if( aEndIndex.InField() && aEndIndex.GetFieldOffset() )
460 DBG_ASSERT(sStr.getLength() - (aEndIndex.GetFieldLen() - aEndIndex.GetFieldOffset()) >= 0,
461 "SvxAccessibleTextIndex::GetText: index value overflow");
463 sStr = sStr.copy(0, sStr.getLength() - (aEndIndex.GetFieldLen() - aEndIndex.GetFieldOffset()) );
466 EBulletInfo aBulletInfo2 = GetBulletInfo( aEndIndex.GetParagraph() );
468 if( aEndIndex.InBullet() )
470 // append trailing bullet
471 sStr += aBulletInfo2.aText;
473 DBG_ASSERT(sStr.getLength() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset()) >= 0,
474 "SvxAccessibleTextIndex::GetText: index value overflow");
476 sStr = sStr.copy(0, sStr.getLength() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset()) );
478 else if( aStartIndex.GetParagraph() != aEndIndex.GetParagraph() &&
479 HaveTextBullet( aEndIndex.GetParagraph() ) )
481 OUString sBullet = aBulletInfo2.aText;
483 DBG_ASSERT(sBullet.getLength() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset()) >= 0,
484 "SvxAccessibleTextIndex::GetText: index value overflow");
486 sBullet = sBullet.copy(0, sBullet.getLength() - (aEndIndex.GetBulletLen() - aEndIndex.GetBulletOffset()) );
488 // insert bullet
489 sStr = sStr.replaceAt( GetTextLen(aStartIndex.GetParagraph()) - aStartIndex.GetIndex(), 0, sBullet );
492 return sStr;
495 SfxItemSet SvxAccessibleTextAdapter::GetAttribs( const ESelection& rSel, EditEngineAttribs nOnlyHardAttrib ) const
497 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
499 SvxAccessibleTextIndex aStartIndex;
500 SvxAccessibleTextIndex aEndIndex;
502 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
503 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
505 return mpTextForwarder->GetAttribs( MakeEESelection(aStartIndex, aEndIndex), nOnlyHardAttrib );
508 SfxItemSet SvxAccessibleTextAdapter::GetParaAttribs( sal_Int32 nPara ) const
510 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
512 return mpTextForwarder->GetParaAttribs( nPara );
515 void SvxAccessibleTextAdapter::SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet )
517 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
519 mpTextForwarder->SetParaAttribs( nPara, rSet );
522 void SvxAccessibleTextAdapter::RemoveAttribs( const ESelection& )
526 void SvxAccessibleTextAdapter::GetPortions( sal_Int32 nPara, std::vector<sal_Int32>& rList ) const
528 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
530 mpTextForwarder->GetPortions( nPara, rList );
533 SfxItemState SvxAccessibleTextAdapter::GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const
535 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
537 SvxAccessibleTextIndex aStartIndex;
538 SvxAccessibleTextIndex aEndIndex;
540 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
541 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
543 return mpTextForwarder->GetItemState( MakeEESelection(aStartIndex, aEndIndex),
544 nWhich );
547 SfxItemState SvxAccessibleTextAdapter::GetItemState( sal_Int32 nPara, sal_uInt16 nWhich ) const
549 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
551 return mpTextForwarder->GetItemState( nPara, nWhich );
554 void SvxAccessibleTextAdapter::QuickInsertText( const OUString& rText, const ESelection& rSel )
556 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
558 SvxAccessibleTextIndex aStartIndex;
559 SvxAccessibleTextIndex aEndIndex;
561 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
562 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
564 mpTextForwarder->QuickInsertText( rText,
565 MakeEESelection(aStartIndex, aEndIndex) );
568 void SvxAccessibleTextAdapter::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
570 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
572 SvxAccessibleTextIndex aStartIndex;
573 SvxAccessibleTextIndex aEndIndex;
575 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
576 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
578 mpTextForwarder->QuickInsertField( rFld,
579 MakeEESelection(aStartIndex, aEndIndex) );
582 void SvxAccessibleTextAdapter::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
584 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
586 SvxAccessibleTextIndex aStartIndex;
587 SvxAccessibleTextIndex aEndIndex;
589 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
590 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
592 mpTextForwarder->QuickSetAttribs( rSet,
593 MakeEESelection(aStartIndex, aEndIndex) );
596 void SvxAccessibleTextAdapter::QuickInsertLineBreak( const ESelection& rSel )
598 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
600 SvxAccessibleTextIndex aStartIndex;
601 SvxAccessibleTextIndex aEndIndex;
603 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
604 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
606 mpTextForwarder->QuickInsertLineBreak( MakeEESelection(aStartIndex, aEndIndex) );
609 SfxItemPool* SvxAccessibleTextAdapter::GetPool() const
611 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
613 return mpTextForwarder->GetPool();
616 OUString SvxAccessibleTextAdapter::CalcFieldValue( const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos, std::optional<Color>& rpTxtColor, std::optional<Color>& rpFldColor )
618 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
620 return mpTextForwarder->CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor );
623 void SvxAccessibleTextAdapter::FieldClicked( const SvxFieldItem& rField )
625 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
627 mpTextForwarder->FieldClicked( rField );
630 sal_Int32 SvxAccessibleTextAdapter::CalcEditEngineIndex( sal_Int32 nPara, sal_Int32 nLogicalIndex )
632 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
634 SvxAccessibleTextIndex aIndex;
635 aIndex.SetIndex(nPara, nLogicalIndex, *mpTextForwarder);
636 return aIndex.GetEEIndex();
639 bool SvxAccessibleTextAdapter::IsValid() const
641 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
643 if( mpTextForwarder )
644 return mpTextForwarder->IsValid();
645 else
646 return false;
649 LanguageType SvxAccessibleTextAdapter::GetLanguage( sal_Int32 nPara, sal_Int32 nPos ) const
651 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
653 SvxAccessibleTextIndex aIndex;
655 aIndex.SetIndex( nPara, nPos, *this );
657 return mpTextForwarder->GetLanguage( nPara, aIndex.GetEEIndex() );
660 sal_Int32 SvxAccessibleTextAdapter::GetFieldCount( sal_Int32 nPara ) const
662 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
664 return mpTextForwarder->GetFieldCount( nPara );
667 EFieldInfo SvxAccessibleTextAdapter::GetFieldInfo( sal_Int32 nPara, sal_uInt16 nField ) const
669 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
671 return mpTextForwarder->GetFieldInfo( nPara, nField );
674 EBulletInfo SvxAccessibleTextAdapter::GetBulletInfo( sal_Int32 nPara ) const
676 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
678 return mpTextForwarder->GetBulletInfo( nPara );
681 tools::Rectangle SvxAccessibleTextAdapter::GetCharBounds( sal_Int32 nPara, sal_Int32 nIndex ) const
683 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
685 SvxAccessibleTextIndex aIndex;
686 aIndex.SetIndex( nPara, nIndex, *this );
688 // preset if anything goes wrong below
689 // n-th char in GetParagraphIndex's paragraph
690 tools::Rectangle aRect = mpTextForwarder->GetCharBounds( nPara, aIndex.GetEEIndex() );
692 if( aIndex.InBullet() )
694 EBulletInfo aBulletInfo = GetBulletInfo( nPara );
696 OutputDevice* pOutDev = GetRefDevice();
698 DBG_ASSERT(pOutDev!=nullptr, "SvxAccessibleTextAdapter::GetCharBounds: No ref device");
700 // preset if anything goes wrong below
701 aRect = aBulletInfo.aBounds; // better than nothing
702 if( pOutDev )
704 AccessibleStringWrap aStringWrap( *pOutDev, aBulletInfo.aFont, aBulletInfo.aText );
706 aStringWrap.GetCharacterBounds( aIndex.GetBulletOffset(), aRect );
707 aRect.Move( aBulletInfo.aBounds.Left(), aBulletInfo.aBounds.Top() );
710 else
712 // handle field content manually
713 if( aIndex.InField() )
715 OutputDevice* pOutDev = GetRefDevice();
717 DBG_ASSERT(pOutDev!=nullptr, "SvxAccessibleTextAdapter::GetCharBounds: No ref device");
719 if( pOutDev )
721 ESelection aSel = MakeEESelection( aIndex );
723 SvxFont aFont = EditEngine::CreateSvxFontFromItemSet( mpTextForwarder->GetAttribs( aSel ) );
724 AccessibleStringWrap aStringWrap( *pOutDev,
725 aFont,
726 mpTextForwarder->GetText( aSel ) );
728 tools::Rectangle aStartRect = mpTextForwarder->GetCharBounds( nPara, aIndex.GetEEIndex() );
730 aStringWrap.GetCharacterBounds( aIndex.GetFieldOffset(), aRect );
731 aRect.Move( aStartRect.Left(), aStartRect.Top() );
736 return aRect;
739 tools::Rectangle SvxAccessibleTextAdapter::GetParaBounds( sal_Int32 nPara ) const
741 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
743 EBulletInfo aBulletInfo = GetBulletInfo( nPara );
745 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
746 aBulletInfo.bVisible &&
747 aBulletInfo.nType != SVX_NUM_BITMAP )
749 // include bullet in para bounding box
750 tools::Rectangle aRect( mpTextForwarder->GetParaBounds( nPara ) );
752 aRect.Union( aBulletInfo.aBounds );
754 return aRect;
757 return mpTextForwarder->GetParaBounds( nPara );
760 MapMode SvxAccessibleTextAdapter::GetMapMode() const
762 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
764 return mpTextForwarder->GetMapMode();
767 OutputDevice* SvxAccessibleTextAdapter::GetRefDevice() const
769 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
771 return mpTextForwarder->GetRefDevice();
774 bool SvxAccessibleTextAdapter::GetIndexAtPoint( const Point& rPoint, sal_Int32& nPara, sal_Int32& nIndex ) const
776 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
778 if( !mpTextForwarder->GetIndexAtPoint( rPoint, nPara, nIndex ) )
779 return false;
781 SvxAccessibleTextIndex aIndex;
782 aIndex.SetEEIndex(nPara, nIndex, *this);
784 DBG_ASSERT(aIndex.GetIndex() >= 0,
785 "SvxAccessibleTextIndex::SetIndex: index value overflow");
787 nIndex = aIndex.GetIndex();
789 EBulletInfo aBulletInfo = GetBulletInfo( nPara );
791 // any text bullets?
792 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
793 aBulletInfo.bVisible &&
794 aBulletInfo.nType != SVX_NUM_BITMAP )
796 if( aBulletInfo.aBounds.IsInside( rPoint) )
798 OutputDevice* pOutDev = GetRefDevice();
800 DBG_ASSERT(pOutDev!=nullptr, "SvxAccessibleTextAdapter::GetIndexAtPoint: No ref device");
802 if( !pOutDev )
803 return false;
805 AccessibleStringWrap aStringWrap( *pOutDev, aBulletInfo.aFont, aBulletInfo.aText );
807 Point aPoint = rPoint;
808 aPoint.Move( -aBulletInfo.aBounds.Left(), -aBulletInfo.aBounds.Top() );
810 DBG_ASSERT(aStringWrap.GetIndexAtPoint( aPoint ) >= 0,
811 "SvxAccessibleTextIndex::SetIndex: index value overflow");
813 nIndex = aStringWrap.GetIndexAtPoint( aPoint );
814 return true;
818 if( aIndex.InField() )
820 OutputDevice* pOutDev = GetRefDevice();
822 DBG_ASSERT(pOutDev!=nullptr, "SvxAccessibleTextAdapter::GetIndexAtPoint: No ref device");
824 if( !pOutDev )
825 return false;
827 ESelection aSelection = MakeEESelection( aIndex );
828 SvxFont aFont = EditEngine::CreateSvxFontFromItemSet( mpTextForwarder->GetAttribs( aSelection ) );
829 AccessibleStringWrap aStringWrap( *pOutDev,
830 aFont,
831 mpTextForwarder->GetText( aSelection ) );
833 tools::Rectangle aRect = mpTextForwarder->GetCharBounds( nPara, aIndex.GetEEIndex() );
834 Point aPoint = rPoint;
835 aPoint.Move( -aRect.Left(), -aRect.Top() );
837 DBG_ASSERT(aIndex.GetIndex() + aStringWrap.GetIndexAtPoint( rPoint ) >= 0,
838 "SvxAccessibleTextIndex::SetIndex: index value overflow");
840 nIndex = (aIndex.GetIndex() + aStringWrap.GetIndexAtPoint( aPoint ));
841 return true;
844 return true;
847 bool SvxAccessibleTextAdapter::GetWordIndices( sal_Int32 nPara, sal_Int32 nIndex, sal_Int32& nStart, sal_Int32& nEnd ) const
849 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
851 SvxAccessibleTextIndex aIndex;
852 aIndex.SetIndex(nPara, nIndex, *this);
853 nIndex = aIndex.GetEEIndex();
855 if( aIndex.InBullet() )
857 DBG_ASSERT(aIndex.GetBulletLen() >= 0,
858 "SvxAccessibleTextIndex::SetIndex: index value overflow");
860 // always treat bullet as separate word
861 nStart = 0;
862 nEnd = aIndex.GetBulletLen();
864 return true;
867 if( aIndex.InField() )
869 DBG_ASSERT(aIndex.GetIndex() - aIndex.GetFieldOffset() >= 0 &&
870 nStart + aIndex.GetFieldLen() >= 0,
871 "SvxAccessibleTextIndex::SetIndex: index value overflow");
873 // always treat field as separate word
874 // TODO: to circumvent this, _we_ would have to do the break iterator stuff!
875 nStart = aIndex.GetIndex() - aIndex.GetFieldOffset();
876 nEnd = nStart + aIndex.GetFieldLen();
878 return true;
881 if( !mpTextForwarder->GetWordIndices( nPara, nIndex, nStart, nEnd ) )
882 return false;
884 aIndex.SetEEIndex( nPara, nStart, *this );
885 DBG_ASSERT(aIndex.GetIndex() >= 0,
886 "SvxAccessibleTextIndex::SetIndex: index value overflow");
887 nStart = aIndex.GetIndex();
889 aIndex.SetEEIndex( nPara, nEnd, *this );
890 DBG_ASSERT(aIndex.GetIndex() >= 0,
891 "SvxAccessibleTextIndex::SetIndex: index value overflow");
892 nEnd = aIndex.GetIndex();
894 return true;
897 bool SvxAccessibleTextAdapter::GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nPara, sal_Int32 nIndex, bool /* bInCell */ ) const
899 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
901 SvxAccessibleTextIndex aIndex;
902 aIndex.SetIndex(nPara, nIndex, *this);
903 nIndex = aIndex.GetEEIndex();
905 if( aIndex.InBullet() )
907 DBG_ASSERT(aIndex.GetBulletLen() >= 0,
908 "SvxAccessibleTextIndex::SetIndex: index value overflow");
910 // always treat bullet as distinct attribute
911 nStartIndex = 0;
912 nEndIndex = aIndex.GetBulletLen();
914 return true;
917 if( aIndex.InField() )
919 DBG_ASSERT(aIndex.GetIndex() - aIndex.GetFieldOffset() >= 0,
920 "SvxAccessibleTextIndex::SetIndex: index value overflow");
922 // always treat field as distinct attribute
923 nStartIndex = aIndex.GetIndex() - aIndex.GetFieldOffset();
924 nEndIndex = nStartIndex + aIndex.GetFieldLen();
926 return true;
929 if( !mpTextForwarder->GetAttributeRun( nStartIndex, nEndIndex, nPara, nIndex ) )
930 return false;
932 aIndex.SetEEIndex( nPara, nStartIndex, *this );
933 DBG_ASSERT(aIndex.GetIndex() >= 0,
934 "SvxAccessibleTextIndex::SetIndex: index value overflow");
935 nStartIndex = aIndex.GetIndex();
937 aIndex.SetEEIndex( nPara, nEndIndex, *this );
938 DBG_ASSERT(aIndex.GetIndex() >= 0,
939 "SvxAccessibleTextIndex::SetIndex: index value overflow");
940 nEndIndex = aIndex.GetIndex();
942 return true;
945 sal_Int32 SvxAccessibleTextAdapter::GetLineCount( sal_Int32 nPara ) const
947 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
949 return mpTextForwarder->GetLineCount( nPara );
952 sal_Int32 SvxAccessibleTextAdapter::GetLineLen( sal_Int32 nPara, sal_Int32 nLine ) const
954 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
956 SvxAccessibleTextIndex aEndIndex;
957 sal_Int32 nCurrLine;
958 sal_Int32 nCurrIndex, nLastIndex;
959 for( nCurrLine=0, nCurrIndex=0, nLastIndex=0; nCurrLine<=nLine; ++nCurrLine )
961 nLastIndex = nCurrIndex;
962 nCurrIndex =
963 nCurrIndex + mpTextForwarder->GetLineLen( nPara, nCurrLine );
966 aEndIndex.SetEEIndex( nPara, nCurrIndex, *this );
967 if( nLine > 0 )
969 SvxAccessibleTextIndex aStartIndex;
970 aStartIndex.SetEEIndex( nPara, nLastIndex, *this );
972 return aEndIndex.GetIndex() - aStartIndex.GetIndex();
974 else
975 return aEndIndex.GetIndex();
978 void SvxAccessibleTextAdapter::GetLineBoundaries( /*out*/sal_Int32 &rStart, /*out*/sal_Int32 &rEnd, sal_Int32 nParagraph, sal_Int32 nLine ) const
980 mpTextForwarder->GetLineBoundaries( rStart, rEnd, nParagraph, nLine );
983 sal_Int32 SvxAccessibleTextAdapter::GetLineNumberAtIndex( sal_Int32 nPara, sal_Int32 nIndex ) const
985 return mpTextForwarder->GetLineNumberAtIndex( nPara, nIndex );
988 bool SvxAccessibleTextAdapter::Delete( const ESelection& rSel )
990 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
992 SvxAccessibleTextIndex aStartIndex;
993 SvxAccessibleTextIndex aEndIndex;
995 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
996 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
998 return mpTextForwarder->Delete( MakeEESelection(aStartIndex, aEndIndex ) );
1001 bool SvxAccessibleTextAdapter::InsertText( const OUString& rStr, const ESelection& rSel )
1003 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
1005 SvxAccessibleTextIndex aStartIndex;
1006 SvxAccessibleTextIndex aEndIndex;
1008 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
1009 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
1011 return mpTextForwarder->InsertText( rStr, MakeEESelection(aStartIndex, aEndIndex) );
1014 bool SvxAccessibleTextAdapter::QuickFormatDoc( bool bFull )
1016 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
1018 return mpTextForwarder->QuickFormatDoc( bFull );
1021 sal_Int16 SvxAccessibleTextAdapter::GetDepth( sal_Int32 nPara ) const
1023 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
1025 return mpTextForwarder->GetDepth( nPara );
1028 bool SvxAccessibleTextAdapter::SetDepth( sal_Int32 nPara, sal_Int16 nNewDepth )
1030 assert(mpTextForwarder && "SvxAccessibleTextAdapter: no forwarder");
1032 return mpTextForwarder->SetDepth( nPara, nNewDepth );
1035 void SvxAccessibleTextAdapter::SetForwarder( SvxTextForwarder& rForwarder )
1037 mpTextForwarder = &rForwarder;
1040 bool SvxAccessibleTextAdapter::HaveImageBullet( sal_Int32 nPara ) const
1042 EBulletInfo aBulletInfo = GetBulletInfo( nPara );
1044 return ( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
1045 aBulletInfo.bVisible &&
1046 aBulletInfo.nType == SVX_NUM_BITMAP );
1049 bool SvxAccessibleTextAdapter::HaveTextBullet( sal_Int32 nPara ) const
1051 EBulletInfo aBulletInfo = GetBulletInfo( nPara );
1053 return ( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
1054 aBulletInfo.bVisible &&
1055 aBulletInfo.nType != SVX_NUM_BITMAP );
1058 bool SvxAccessibleTextAdapter::IsEditable( const ESelection& rSel )
1060 SvxAccessibleTextIndex aStartIndex;
1061 SvxAccessibleTextIndex aEndIndex;
1063 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *this );
1064 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *this );
1066 // normalize selection
1067 if( rSel.nStartPara > rSel.nEndPara ||
1068 (rSel.nStartPara == rSel.nEndPara && rSel.nStartPos > rSel.nEndPos) )
1070 std::swap( aStartIndex, aEndIndex );
1073 return aStartIndex.IsEditableRange( aEndIndex );
1076 const SfxItemSet * SvxAccessibleTextAdapter::GetEmptyItemSetPtr()
1078 OSL_FAIL( "not implemented" );
1079 return nullptr;
1082 void SvxAccessibleTextAdapter::AppendParagraph()
1084 OSL_FAIL( "not implemented" );
1087 sal_Int32 SvxAccessibleTextAdapter::AppendTextPortion( sal_Int32, const OUString &, const SfxItemSet & )
1089 OSL_FAIL( "not implemented" );
1090 return 0;
1092 void SvxAccessibleTextAdapter::CopyText(const SvxTextForwarder&)
1094 OSL_FAIL( "not implemented" );
1097 SvxAccessibleTextEditViewAdapter::SvxAccessibleTextEditViewAdapter()
1098 : mpViewForwarder(nullptr)
1099 , mpTextForwarder(nullptr)
1103 SvxAccessibleTextEditViewAdapter::~SvxAccessibleTextEditViewAdapter()
1107 bool SvxAccessibleTextEditViewAdapter::IsValid() const
1109 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1111 if( mpViewForwarder )
1112 return mpViewForwarder->IsValid();
1113 else
1114 return false;
1117 Point SvxAccessibleTextEditViewAdapter::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
1119 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1121 return mpViewForwarder->LogicToPixel(rPoint, rMapMode);
1124 Point SvxAccessibleTextEditViewAdapter::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
1126 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1128 return mpViewForwarder->PixelToLogic(rPoint, rMapMode);
1131 bool SvxAccessibleTextEditViewAdapter::GetSelection( ESelection& rSel ) const
1133 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1135 ESelection aSelection;
1137 if( !mpViewForwarder->GetSelection( aSelection ) )
1138 return false;
1140 SvxAccessibleTextIndex aStartIndex;
1141 SvxAccessibleTextIndex aEndIndex;
1143 aStartIndex.SetEEIndex( aSelection.nStartPara, aSelection.nStartPos, *mpTextForwarder );
1144 aEndIndex.SetEEIndex( aSelection.nEndPara, aSelection.nEndPos, *mpTextForwarder );
1146 DBG_ASSERT(aStartIndex.GetIndex() >= 0 &&
1147 aEndIndex.GetIndex() >= 0,
1148 "SvxAccessibleTextEditViewAdapter::GetSelection: index value overflow");
1150 rSel = ESelection( aStartIndex.GetParagraph(), aStartIndex.GetIndex(),
1151 aEndIndex.GetParagraph(), aEndIndex.GetIndex() );
1153 return true;
1156 bool SvxAccessibleTextEditViewAdapter::SetSelection( const ESelection& rSel )
1158 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1160 SvxAccessibleTextIndex aStartIndex;
1161 SvxAccessibleTextIndex aEndIndex;
1163 aStartIndex.SetIndex( rSel.nStartPara, rSel.nStartPos, *mpTextForwarder );
1164 aEndIndex.SetIndex( rSel.nEndPara, rSel.nEndPos, *mpTextForwarder );
1166 return mpViewForwarder->SetSelection( MakeEESelection(aStartIndex, aEndIndex) );
1169 bool SvxAccessibleTextEditViewAdapter::Copy()
1171 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1173 return mpViewForwarder->Copy();
1176 bool SvxAccessibleTextEditViewAdapter::Cut()
1178 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1180 return mpViewForwarder->Cut();
1183 bool SvxAccessibleTextEditViewAdapter::Paste()
1185 DBG_ASSERT(mpViewForwarder, "SvxAccessibleTextEditViewAdapter: no forwarder");
1187 return mpViewForwarder->Paste();
1190 void SvxAccessibleTextEditViewAdapter::SetForwarder( SvxEditViewForwarder& rForwarder,
1191 SvxAccessibleTextAdapter& rTextForwarder )
1193 mpViewForwarder = &rForwarder;
1194 mpTextForwarder = &rTextForwarder;
1197 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */