bump product version to 6.4.0.3
[LibreOffice.git] / editeng / source / uno / unotext.cxx
blob4796732b2c74e8ce10f90326cc7b9197d8679be1
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 .
20 #include <vcl/svapp.hxx>
21 #include <com/sun/star/style/LineSpacing.hpp>
22 #include <com/sun/star/text/ControlCharacter.hpp>
23 #include <com/sun/star/text/XTextField.hpp>
24 #include <com/sun/star/text/TextRangeSelection.hpp>
25 #include <com/sun/star/lang/Locale.hpp>
26 #include <com/sun/star/beans/PropertyAttribute.hpp>
27 #include <com/sun/star/container/XNameContainer.hpp>
29 #include <svl/itemset.hxx>
30 #include <svl/itempool.hxx>
31 #include <svl/intitem.hxx>
32 #include <svl/eitem.hxx>
33 #include <rtl/instance.hxx>
35 #include <editeng/fontitem.hxx>
36 #include <editeng/tstpitem.hxx>
37 #include <editeng/unoprnms.hxx>
38 #include <editeng/unotext.hxx>
39 #include <editeng/unoedsrc.hxx>
40 #include <editeng/unonrule.hxx>
41 #include <editeng/unofdesc.hxx>
42 #include <editeng/unofield.hxx>
43 #include <editeng/flditem.hxx>
44 #include <editeng/numitem.hxx>
45 #include <editeng/editeng.hxx>
46 #include <editeng/outliner.hxx>
47 #include <editeng/unoipset.hxx>
48 #include <comphelper/servicehelper.hxx>
49 #include <comphelper/serviceinfohelper.hxx>
50 #include <cppuhelper/supportsservice.hxx>
52 #include <editeng/unonames.hxx>
54 #include <memory>
56 using namespace ::cppu;
57 using namespace ::com::sun::star;
59 namespace {
61 ESelection toESelection(const text::TextRangeSelection& rSel)
63 ESelection aESel;
64 aESel.nStartPara = rSel.Start.Paragraph;
65 aESel.nStartPos = rSel.Start.PositionInParagraph;
66 aESel.nEndPara = rSel.End.Paragraph;
67 aESel.nEndPos = rSel.End.PositionInParagraph;
68 return aESel;
73 #define QUERYINT( xint ) \
74 if( rType == cppu::UnoType<xint>::get() ) \
75 return uno::makeAny(uno::Reference< xint >(this))
77 const SvxItemPropertySet* ImplGetSvxUnoOutlinerTextCursorSvxPropertySet()
79 static SvxItemPropertySet aTextCursorSvxPropertySet( ImplGetSvxUnoOutlinerTextCursorPropertyMap(), EditEngine::GetGlobalItemPool() );
80 return &aTextCursorSvxPropertySet;
83 const SfxItemPropertyMapEntry* ImplGetSvxTextPortionPropertyMap()
85 // Propertymap for an Outliner Text
86 static const SfxItemPropertyMapEntry aSvxTextPortionPropertyMap[] =
88 SVX_UNOEDIT_CHAR_PROPERTIES,
89 SVX_UNOEDIT_FONT_PROPERTIES,
90 SVX_UNOEDIT_OUTLINER_PROPERTIES,
91 SVX_UNOEDIT_PARA_PROPERTIES,
92 { OUString("TextField"), EE_FEATURE_FIELD, cppu::UnoType<text::XTextField>::get(), beans::PropertyAttribute::READONLY, 0 },
93 { OUString("TextPortionType"), WID_PORTIONTYPE, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0 },
94 { OUString("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0},
95 { OUString("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0},
96 { OUString(), 0, css::uno::Type(), 0, 0 }
98 return aSvxTextPortionPropertyMap;
100 const SvxItemPropertySet* ImplGetSvxTextPortionSvxPropertySet()
102 static SvxItemPropertySet aSvxTextPortionPropertySet( ImplGetSvxTextPortionPropertyMap(), EditEngine::GetGlobalItemPool() );
103 return &aSvxTextPortionPropertySet;
106 static const SfxItemPropertySet* ImplGetSvxTextPortionSfxPropertySet()
108 static SfxItemPropertySet aSvxTextPortionSfxPropertySet( ImplGetSvxTextPortionPropertyMap() );
109 return &aSvxTextPortionSfxPropertySet;
112 const SfxItemPropertyMapEntry* ImplGetSvxUnoOutlinerTextCursorPropertyMap()
114 // Propertymap for an Outliner Text
115 static const SfxItemPropertyMapEntry aSvxUnoOutlinerTextCursorPropertyMap[] =
117 SVX_UNOEDIT_CHAR_PROPERTIES,
118 SVX_UNOEDIT_FONT_PROPERTIES,
119 SVX_UNOEDIT_OUTLINER_PROPERTIES,
120 SVX_UNOEDIT_PARA_PROPERTIES,
121 { OUString("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0},
122 { OUString("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0},
123 { OUString(), 0, css::uno::Type(), 0, 0 }
126 return aSvxUnoOutlinerTextCursorPropertyMap;
128 static const SfxItemPropertySet* ImplGetSvxUnoOutlinerTextCursorSfxPropertySet()
130 static SfxItemPropertySet aTextCursorSfxPropertySet( ImplGetSvxUnoOutlinerTextCursorPropertyMap() );
131 return &aTextCursorSfxPropertySet;
135 // helper for Item/Property conversion
138 void GetSelection( struct ESelection& rSel, SvxTextForwarder const * pForwarder ) throw()
140 DBG_ASSERT( pForwarder, "I need a valid SvxTextForwarder!" );
141 if( pForwarder )
143 sal_Int32 nParaCount = pForwarder->GetParagraphCount();
144 if(nParaCount>0)
145 nParaCount--;
147 rSel = ESelection( 0,0, nParaCount, pForwarder->GetTextLen( nParaCount ));
151 void CheckSelection( struct ESelection& rSel, SvxTextForwarder const * pForwarder ) throw()
153 DBG_ASSERT( pForwarder, "I need a valid SvxTextForwarder!" );
154 if( pForwarder )
156 if( rSel.nStartPara == EE_PARA_MAX_COUNT )
158 ::GetSelection( rSel, pForwarder );
160 else
162 ESelection aMaxSelection;
163 GetSelection( aMaxSelection, pForwarder );
165 // check start position
166 if( rSel.nStartPara < aMaxSelection.nStartPara )
168 rSel.nStartPara = aMaxSelection.nStartPara;
169 rSel.nStartPos = aMaxSelection.nStartPos;
171 else if( rSel.nStartPara > aMaxSelection.nEndPara )
173 rSel.nStartPara = aMaxSelection.nEndPara;
174 rSel.nStartPos = aMaxSelection.nEndPos;
176 else if( rSel.nStartPos > pForwarder->GetTextLen( rSel.nStartPara ) )
178 rSel.nStartPos = pForwarder->GetTextLen( rSel.nStartPara );
181 // check end position
182 if( rSel.nEndPara < aMaxSelection.nStartPara )
184 rSel.nEndPara = aMaxSelection.nStartPara;
185 rSel.nEndPos = aMaxSelection.nStartPos;
187 else if( rSel.nEndPara > aMaxSelection.nEndPara )
189 rSel.nEndPara = aMaxSelection.nEndPara;
190 rSel.nEndPos = aMaxSelection.nEndPos;
192 else if( rSel.nEndPos > pForwarder->GetTextLen( rSel.nEndPara ) )
194 rSel.nEndPos = pForwarder->GetTextLen( rSel.nEndPara );
200 static void CheckSelection( struct ESelection& rSel, SvxEditSource *pEdit ) throw()
202 if (!pEdit)
203 return;
204 CheckSelection( rSel, pEdit->GetTextForwarder() );
208 // class SvxUnoTextRangeBase
211 UNO3_GETIMPLEMENTATION_IMPL( SvxUnoTextRangeBase );
213 SvxUnoTextRangeBase::SvxUnoTextRangeBase(const SvxItemPropertySet* _pSet)
214 : mpPropSet(_pSet)
218 SvxUnoTextRangeBase::SvxUnoTextRangeBase(const SvxEditSource* pSource, const SvxItemPropertySet* _pSet)
219 : mpPropSet(_pSet)
221 SolarMutexGuard aGuard;
223 DBG_ASSERT(pSource,"SvxUnoTextRangeBase: I need a valid SvxEditSource!");
225 mpEditSource = pSource->Clone();
226 if (mpEditSource != nullptr)
228 ESelection aSelection;
229 ::GetSelection( aSelection, mpEditSource->GetTextForwarder() );
230 SetSelection( aSelection );
232 mpEditSource->addRange( this );
236 SvxUnoTextRangeBase::SvxUnoTextRangeBase(const SvxUnoTextRangeBase& rRange)
237 : text::XTextRange()
238 , beans::XPropertySet()
239 , beans::XMultiPropertySet()
240 , beans::XMultiPropertyStates()
241 , beans::XPropertyState()
242 , lang::XServiceInfo()
243 , text::XTextRangeCompare()
244 , lang::XUnoTunnel()
245 , osl::DebugBase<SvxUnoTextRangeBase>()
246 , mpPropSet(rRange.getPropertySet())
248 SolarMutexGuard aGuard;
250 if (rRange.mpEditSource)
251 mpEditSource = rRange.mpEditSource->Clone();
253 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
254 if( pForwarder )
256 maSelection = rRange.maSelection;
257 CheckSelection( maSelection, pForwarder );
260 if( mpEditSource )
261 mpEditSource->addRange( this );
264 SvxUnoTextRangeBase::~SvxUnoTextRangeBase() throw()
266 if( mpEditSource )
267 mpEditSource->removeRange( this );
270 void SvxUnoTextRangeBase::SetEditSource( SvxEditSource* pSource ) throw()
272 DBG_ASSERT(pSource,"SvxUnoTextRangeBase: I need a valid SvxEditSource!");
273 DBG_ASSERT(mpEditSource==nullptr,"SvxUnoTextRangeBase::SetEditSource called while SvxEditSource already set" );
275 mpEditSource.reset( pSource );
277 maSelection.nStartPara = EE_PARA_MAX_COUNT;
279 if( mpEditSource )
280 mpEditSource->addRange( this );
283 /** puts a field item with a copy of the given FieldData into the itemset
284 corresponding with this range */
285 void SvxUnoTextRangeBase::attachField( std::unique_ptr<SvxFieldData> pData ) throw()
287 SolarMutexGuard aGuard;
289 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
290 if( pForwarder )
292 SvxFieldItem aField( std::move(pData), EE_FEATURE_FIELD );
293 pForwarder->QuickInsertField( std::move(aField), maSelection );
297 void SvxUnoTextRangeBase::SetSelection( const ESelection& rSelection ) throw()
299 SolarMutexGuard aGuard;
301 maSelection = rSelection;
302 CheckSelection( maSelection, mpEditSource.get() );
305 // Interface XTextRange ( XText )
307 uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextRangeBase::getStart()
309 SolarMutexGuard aGuard;
311 uno::Reference< text::XTextRange > xRange;
313 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
314 if( pForwarder )
316 CheckSelection( maSelection, pForwarder );
318 SvxUnoTextBase* pText = comphelper::getUnoTunnelImplementation<SvxUnoTextBase>( getText() );
320 if(pText == nullptr)
321 throw uno::RuntimeException();
323 SvxUnoTextRange* pRange = new SvxUnoTextRange( *pText );
324 xRange = pRange;
326 ESelection aNewSel = maSelection;
327 aNewSel.nEndPara = aNewSel.nStartPara;
328 aNewSel.nEndPos = aNewSel.nStartPos;
329 pRange->SetSelection( aNewSel );
332 return xRange;
335 uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextRangeBase::getEnd()
337 SolarMutexGuard aGuard;
339 uno::Reference< text::XTextRange > xRet;
341 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
342 if( pForwarder )
344 CheckSelection( maSelection, pForwarder );
346 SvxUnoTextBase* pText = comphelper::getUnoTunnelImplementation<SvxUnoTextBase>( getText() );
348 if(pText == nullptr)
349 throw uno::RuntimeException();
351 SvxUnoTextRange* pNew = new SvxUnoTextRange( *pText );
352 xRet = pNew;
354 ESelection aNewSel = maSelection;
355 aNewSel.nStartPara = aNewSel.nEndPara;
356 aNewSel.nStartPos = aNewSel.nEndPos;
357 pNew->SetSelection( aNewSel );
359 return xRet;
362 OUString SAL_CALL SvxUnoTextRangeBase::getString()
364 SolarMutexGuard aGuard;
366 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
367 if( pForwarder )
369 CheckSelection( maSelection, pForwarder );
371 return pForwarder->GetText( maSelection );
373 else
375 return OUString();
379 void SAL_CALL SvxUnoTextRangeBase::setString(const OUString& aString)
381 SolarMutexGuard aGuard;
383 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
384 if( pForwarder )
386 CheckSelection( maSelection, pForwarder );
388 OUString aConverted(convertLineEnd(aString, LINEEND_LF)); // Simply count the number of line endings
390 pForwarder->QuickInsertText( aConverted, maSelection );
391 mpEditSource->UpdateData();
393 // Adapt selection
394 //! It would be easier if the EditEngine would return the selection
395 //! on QuickInsertText...
396 CollapseToStart();
398 sal_Int32 nLen = aConverted.getLength();
399 if (nLen)
400 GoRight( nLen, true );
404 // Interface beans::XPropertySet
405 uno::Reference< beans::XPropertySetInfo > SAL_CALL SvxUnoTextRangeBase::getPropertySetInfo()
407 return mpPropSet->getPropertySetInfo();
410 void SAL_CALL SvxUnoTextRangeBase::setPropertyValue(const OUString& PropertyName, const uno::Any& aValue)
412 if (PropertyName == UNO_TR_PROP_SELECTION)
414 text::TextRangeSelection aSel = aValue.get<text::TextRangeSelection>();
415 SetSelection(toESelection(aSel));
417 return;
420 _setPropertyValue( PropertyName, aValue );
423 void SvxUnoTextRangeBase::_setPropertyValue( const OUString& PropertyName, const uno::Any& aValue, sal_Int32 nPara )
425 SolarMutexGuard aGuard;
427 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
428 if( pForwarder )
430 CheckSelection( maSelection, pForwarder );
432 const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName );
433 if ( pMap )
435 ESelection aSel( GetSelection() );
436 bool bParaAttrib = (pMap->nWID >= EE_PARA_START) && ( pMap->nWID <= EE_PARA_END );
438 if( nPara == -1 && !bParaAttrib )
440 SfxItemSet aOldSet( pForwarder->GetAttribs( aSel ) );
441 // we have a selection and no para attribute
442 SfxItemSet aNewSet( *aOldSet.GetPool(), aOldSet.GetRanges() );
444 setPropertyValue( pMap, aValue, maSelection, aOldSet, aNewSet );
447 pForwarder->QuickSetAttribs( aNewSet, GetSelection() );
449 else
451 sal_Int32 nEndPara;
453 if( nPara == -1 )
455 nPara = aSel.nStartPara;
456 nEndPara = aSel.nEndPara;
458 else
460 // only one paragraph
461 nEndPara = nPara;
464 while( nPara <= nEndPara )
466 // we have a paragraph
467 SfxItemSet aSet( pForwarder->GetParaAttribs( nPara ) );
468 setPropertyValue( pMap, aValue, maSelection, aSet, aSet );
469 pForwarder->SetParaAttribs( nPara, aSet );
470 nPara++;
474 GetEditSource()->UpdateData();
475 return;
479 throw beans::UnknownPropertyException(PropertyName);
482 void SvxUnoTextRangeBase::setPropertyValue( const SfxItemPropertySimpleEntry* pMap, const uno::Any& rValue, const ESelection& rSelection, const SfxItemSet& rOldSet, SfxItemSet& rNewSet )
484 if(!SetPropertyValueHelper( pMap, rValue, rNewSet, &rSelection, GetEditSource() ))
486 // For parts of composite items with multiple properties (eg background)
487 // must be taken from the document before the old item.
488 rNewSet.Put(rOldSet.Get(pMap->nWID)); // Old Item in new Set
489 SvxItemPropertySet::setPropertyValue(pMap, rValue, rNewSet, false );
493 bool SvxUnoTextRangeBase::SetPropertyValueHelper( const SfxItemPropertySimpleEntry* pMap, const uno::Any& aValue, SfxItemSet& rNewSet, const ESelection* pSelection /* = NULL */, SvxEditSource* pEditSource /* = NULL*/ )
495 switch( pMap->nWID )
497 case WID_FONTDESC:
499 awt::FontDescriptor aDesc;
500 if(aValue >>= aDesc)
502 SvxUnoFontDescriptor::FillItemSet( aDesc, rNewSet );
503 return true;
506 break;
508 case EE_PARA_NUMBULLET:
510 uno::Reference< container::XIndexReplace > xRule;
511 return !aValue.hasValue() || ((aValue >>= xRule) && !xRule.is());
514 case WID_NUMLEVEL:
516 SvxTextForwarder* pForwarder = pEditSource? pEditSource->GetTextForwarder() : nullptr;
517 if(pForwarder && pSelection)
519 sal_Int16 nLevel = sal_Int16();
520 if( aValue >>= nLevel )
522 // #101004# Call interface method instead of unsafe cast
523 if(! pForwarder->SetDepth( pSelection->nStartPara, nLevel ) )
524 throw lang::IllegalArgumentException();
526 return true;
530 break;
531 case WID_NUMBERINGSTARTVALUE:
533 SvxTextForwarder* pForwarder = pEditSource? pEditSource->GetTextForwarder() : nullptr;
534 if(pForwarder && pSelection)
536 sal_Int16 nStartValue = -1;
537 if( aValue >>= nStartValue )
539 pForwarder->SetNumberingStartValue( pSelection->nStartPara, nStartValue );
540 return true;
544 break;
545 case WID_PARAISNUMBERINGRESTART:
547 SvxTextForwarder* pForwarder = pEditSource? pEditSource->GetTextForwarder() : nullptr;
548 if(pForwarder && pSelection)
550 bool bParaIsNumberingRestart = false;
551 if( aValue >>= bParaIsNumberingRestart )
553 pForwarder->SetParaIsNumberingRestart( pSelection->nStartPara, bParaIsNumberingRestart );
554 return true;
558 break;
559 case EE_PARA_BULLETSTATE:
561 bool bBullet = true;
562 if( aValue >>= bBullet )
564 SfxBoolItem aItem( EE_PARA_BULLETSTATE, bBullet );
565 rNewSet.Put(aItem);
566 return true;
569 break;
571 default:
572 return false;
575 throw lang::IllegalArgumentException();
578 uno::Any SAL_CALL SvxUnoTextRangeBase::getPropertyValue(const OUString& PropertyName)
580 if (PropertyName == UNO_TR_PROP_SELECTION)
582 const ESelection& rSel = GetSelection();
583 text::TextRangeSelection aSel;
584 aSel.Start.Paragraph = rSel.nStartPara;
585 aSel.Start.PositionInParagraph = rSel.nStartPos;
586 aSel.End.Paragraph = rSel.nEndPara;
587 aSel.End.PositionInParagraph = rSel.nEndPos;
588 return uno::makeAny(aSel);
591 return _getPropertyValue( PropertyName );
594 uno::Any SvxUnoTextRangeBase::_getPropertyValue(const OUString& PropertyName, sal_Int32 nPara )
596 SolarMutexGuard aGuard;
598 uno::Any aAny;
600 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
601 if( pForwarder )
603 const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName );
604 if( pMap )
606 std::unique_ptr<SfxItemSet> pAttribs;
607 if( nPara != -1 )
608 pAttribs = pForwarder->GetParaAttribs( nPara ).Clone();
609 else
610 pAttribs = pForwarder->GetAttribs( GetSelection() ).Clone();
612 // Replace Dontcare with Default, so that one always has a mirror
613 pAttribs->ClearInvalidItems();
615 getPropertyValue( pMap, aAny, *pAttribs );
617 return aAny;
621 throw beans::UnknownPropertyException(PropertyName);
624 void SvxUnoTextRangeBase::getPropertyValue( const SfxItemPropertySimpleEntry* pMap, uno::Any& rAny, const SfxItemSet& rSet )
626 switch( pMap->nWID )
628 case EE_FEATURE_FIELD:
629 if ( rSet.GetItemState( EE_FEATURE_FIELD, false ) == SfxItemState::SET )
631 const SvxFieldItem* pItem = rSet.GetItem<SvxFieldItem>( EE_FEATURE_FIELD );
632 const SvxFieldData* pData = pItem->GetField();
633 uno::Reference< text::XTextRange > xAnchor( this );
635 // get presentation string for field
636 boost::optional<Color> pTColor;
637 boost::optional<Color> pFColor;
639 SvxTextForwarder* pForwarder = mpEditSource->GetTextForwarder();
640 OUString aPresentation( pForwarder->CalcFieldValue( SvxFieldItem(*pData, EE_FEATURE_FIELD), maSelection.nStartPara, maSelection.nStartPos, pTColor, pFColor ) );
642 uno::Reference< text::XTextField > xField( new SvxUnoTextField( xAnchor, aPresentation, pData ) );
643 rAny <<= xField;
645 break;
647 case WID_PORTIONTYPE:
648 if ( rSet.GetItemState( EE_FEATURE_FIELD, false ) == SfxItemState::SET )
650 rAny <<= OUString("TextField");
652 else
654 rAny <<= OUString("Text");
656 break;
658 default:
659 if(!GetPropertyValueHelper( *const_cast<SfxItemSet*>(&rSet), pMap, rAny, &maSelection, GetEditSource() ))
660 rAny = SvxItemPropertySet::getPropertyValue(pMap, rSet, true, false );
664 bool SvxUnoTextRangeBase::GetPropertyValueHelper( SfxItemSet const & rSet, const SfxItemPropertySimpleEntry* pMap, uno::Any& aAny, const ESelection* pSelection /* = NULL */, SvxEditSource* pEditSource /* = NULL */ )
666 switch( pMap->nWID )
668 case WID_FONTDESC:
670 awt::FontDescriptor aDesc;
671 SvxUnoFontDescriptor::FillFromItemSet( rSet, aDesc );
672 aAny <<= aDesc;
674 break;
676 case EE_PARA_NUMBULLET:
678 SfxItemState eState = rSet.GetItemState( EE_PARA_NUMBULLET );
679 if( eState != SfxItemState::SET && eState != SfxItemState::DEFAULT)
680 throw uno::RuntimeException();
682 const SvxNumBulletItem* pBulletItem = rSet.GetItem( EE_PARA_NUMBULLET );
684 if( pBulletItem == nullptr )
685 throw uno::RuntimeException();
687 aAny <<= SvxCreateNumRule( pBulletItem->GetNumRule() );
689 break;
691 case WID_NUMLEVEL:
693 SvxTextForwarder* pForwarder = pEditSource? pEditSource->GetTextForwarder() : nullptr;
694 if(pForwarder && pSelection)
696 sal_Int16 nLevel = pForwarder->GetDepth( pSelection->nStartPara );
697 if( nLevel >= 0 )
698 aAny <<= nLevel;
701 break;
702 case WID_NUMBERINGSTARTVALUE:
704 SvxTextForwarder* pForwarder = pEditSource? pEditSource->GetTextForwarder() : nullptr;
705 if(pForwarder && pSelection)
706 aAny <<= pForwarder->GetNumberingStartValue( pSelection->nStartPara );
708 break;
709 case WID_PARAISNUMBERINGRESTART:
711 SvxTextForwarder* pForwarder = pEditSource? pEditSource->GetTextForwarder() : nullptr;
712 if(pForwarder && pSelection)
713 aAny <<= pForwarder->IsParaIsNumberingRestart( pSelection->nStartPara );
715 break;
717 case EE_PARA_BULLETSTATE:
719 bool bState = false;
720 SfxItemState eState = rSet.GetItemState( EE_PARA_BULLETSTATE );
721 if( eState == SfxItemState::SET || eState == SfxItemState::DEFAULT )
723 const SfxBoolItem* pItem = rSet.GetItem<SfxBoolItem>( EE_PARA_BULLETSTATE );
724 bState = pItem->GetValue();
727 aAny <<= bState;
729 break;
730 default:
732 return false;
735 return true;
738 // is not (yet) supported
739 void SAL_CALL SvxUnoTextRangeBase::addPropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) {}
740 void SAL_CALL SvxUnoTextRangeBase::removePropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) {}
741 void SAL_CALL SvxUnoTextRangeBase::addVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) {}
742 void SAL_CALL SvxUnoTextRangeBase::removeVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) {}
744 // XMultiPropertySet
745 void SAL_CALL SvxUnoTextRangeBase::setPropertyValues( const uno::Sequence< OUString >& aPropertyNames, const uno::Sequence< uno::Any >& aValues )
747 _setPropertyValues( aPropertyNames, aValues );
750 void SvxUnoTextRangeBase::_setPropertyValues( const uno::Sequence< OUString >& aPropertyNames, const uno::Sequence< uno::Any >& aValues, sal_Int32 nPara )
752 SolarMutexGuard aGuard;
754 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
755 if( pForwarder )
757 CheckSelection( maSelection, pForwarder );
759 ESelection aSel( GetSelection() );
761 const OUString* pPropertyNames = aPropertyNames.getConstArray();
762 const uno::Any* pValues = aValues.getConstArray();
763 sal_Int32 nCount = aPropertyNames.getLength();
765 sal_Int32 nEndPara = nPara;
766 sal_Int32 nTempPara = nPara;
768 if( nTempPara == -1 )
770 nTempPara = aSel.nStartPara;
771 nEndPara = aSel.nEndPara;
774 std::unique_ptr<SfxItemSet> pOldAttrSet;
775 std::unique_ptr<SfxItemSet> pNewAttrSet;
777 std::unique_ptr<SfxItemSet> pOldParaSet;
778 std::unique_ptr<SfxItemSet> pNewParaSet;
780 for( ; nCount; nCount--, pPropertyNames++, pValues++ )
782 const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry( *pPropertyNames );
784 if( pMap )
786 bool bParaAttrib = (pMap->nWID >= EE_PARA_START) && ( pMap->nWID <= EE_PARA_END );
788 if( (nPara == -1) && !bParaAttrib )
790 if( nullptr == pNewAttrSet )
792 const SfxItemSet aSet( pForwarder->GetAttribs( aSel ) );
793 pOldAttrSet.reset(new SfxItemSet( aSet ));
794 pNewAttrSet.reset(new SfxItemSet( *pOldAttrSet->GetPool(), pOldAttrSet->GetRanges() ));
797 setPropertyValue( pMap, *pValues, GetSelection(), *pOldAttrSet, *pNewAttrSet );
799 if( pMap->nWID >= EE_ITEMS_START && pMap->nWID <= EE_ITEMS_END )
801 const SfxPoolItem* pItem;
802 if( pNewAttrSet->GetItemState( pMap->nWID, true, &pItem ) == SfxItemState::SET )
804 pOldAttrSet->Put( *pItem );
808 else
810 if( nullptr == pNewParaSet )
812 const SfxItemSet & rSet = pForwarder->GetParaAttribs( nTempPara );
813 pOldParaSet.reset(new SfxItemSet( rSet ));
814 pNewParaSet.reset(new SfxItemSet( *pOldParaSet->GetPool(), pOldParaSet->GetRanges() ));
817 setPropertyValue( pMap, *pValues, GetSelection(), *pOldParaSet, *pNewParaSet );
819 if( pMap->nWID >= EE_ITEMS_START && pMap->nWID <= EE_ITEMS_END )
821 const SfxPoolItem* pItem;
822 if( pNewParaSet->GetItemState( pMap->nWID, true, &pItem ) == SfxItemState::SET )
824 pOldParaSet->Put( *pItem );
832 bool bNeedsUpdate = false;
834 if( pNewParaSet )
836 if( pNewParaSet->Count() )
838 while( nTempPara <= nEndPara )
840 SfxItemSet aSet( pForwarder->GetParaAttribs( nTempPara ) );
841 aSet.Put( *pNewParaSet );
842 pForwarder->SetParaAttribs( nTempPara, aSet );
843 nTempPara++;
845 bNeedsUpdate = true;
848 pNewParaSet.reset();
849 pOldParaSet.reset();
852 if( pNewAttrSet )
854 if( pNewAttrSet->Count() )
856 pForwarder->QuickSetAttribs( *pNewAttrSet, GetSelection() );
857 bNeedsUpdate = true;
859 pNewAttrSet.reset();
860 pOldAttrSet.reset();
863 if( bNeedsUpdate )
864 GetEditSource()->UpdateData();
868 uno::Sequence< uno::Any > SAL_CALL SvxUnoTextRangeBase::getPropertyValues( const uno::Sequence< OUString >& aPropertyNames )
870 return _getPropertyValues( aPropertyNames );
873 uno::Sequence< uno::Any > SvxUnoTextRangeBase::_getPropertyValues( const uno::Sequence< OUString >& aPropertyNames, sal_Int32 nPara )
875 SolarMutexGuard aGuard;
877 sal_Int32 nCount = aPropertyNames.getLength();
880 uno::Sequence< uno::Any > aValues( nCount );
882 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
883 if( pForwarder )
885 std::unique_ptr<SfxItemSet> pAttribs;
886 if( nPara != -1 )
887 pAttribs = pForwarder->GetParaAttribs( nPara ).Clone();
888 else
889 pAttribs = pForwarder->GetAttribs( GetSelection() ).Clone();
891 pAttribs->ClearInvalidItems();
893 const OUString* pPropertyNames = aPropertyNames.getConstArray();
894 uno::Any* pValues = aValues.getArray();
896 for( ; nCount; nCount--, pPropertyNames++, pValues++ )
898 const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry( *pPropertyNames );
899 if( pMap )
901 getPropertyValue( pMap, *pValues, *pAttribs );
906 return aValues;
909 void SAL_CALL SvxUnoTextRangeBase::addPropertiesChangeListener( const uno::Sequence< OUString >& , const uno::Reference< beans::XPropertiesChangeListener >& )
913 void SAL_CALL SvxUnoTextRangeBase::removePropertiesChangeListener( const uno::Reference< beans::XPropertiesChangeListener >& )
917 void SAL_CALL SvxUnoTextRangeBase::firePropertiesChangeEvent( const uno::Sequence< OUString >& , const uno::Reference< beans::XPropertiesChangeListener >& )
921 // beans::XPropertyState
922 beans::PropertyState SAL_CALL SvxUnoTextRangeBase::getPropertyState( const OUString& PropertyName )
924 return _getPropertyState( PropertyName );
927 static const sal_uInt16 aSvxUnoFontDescriptorWhichMap[] = { EE_CHAR_FONTINFO, EE_CHAR_FONTHEIGHT, EE_CHAR_ITALIC,
928 EE_CHAR_UNDERLINE, EE_CHAR_WEIGHT, EE_CHAR_STRIKEOUT, EE_CHAR_CASEMAP,
929 EE_CHAR_WLM, 0 };
931 beans::PropertyState SvxUnoTextRangeBase::_getPropertyState(const SfxItemPropertySimpleEntry* pMap, sal_Int32 nPara)
933 if ( pMap )
935 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
936 if( pForwarder )
938 SfxItemState eItemState = SfxItemState::UNKNOWN;
939 sal_uInt16 nWID = 0;
941 switch( pMap->nWID )
943 case WID_FONTDESC:
945 const sal_uInt16* pWhichId = aSvxUnoFontDescriptorWhichMap;
946 SfxItemState eTempItemState = SfxItemState::UNKNOWN;
947 while( *pWhichId )
949 if(nPara != -1)
950 eTempItemState = pForwarder->GetItemState( nPara, *pWhichId );
951 else
952 eTempItemState = pForwarder->GetItemState( GetSelection(), *pWhichId );
954 switch( eTempItemState )
956 case SfxItemState::DISABLED:
957 case SfxItemState::DONTCARE:
958 eItemState = SfxItemState::DONTCARE;
959 break;
961 case SfxItemState::DEFAULT:
962 if( eItemState != SfxItemState::DEFAULT )
964 if( eItemState == SfxItemState::UNKNOWN )
965 eItemState = SfxItemState::DEFAULT;
967 break;
969 case SfxItemState::READONLY:
970 case SfxItemState::SET:
971 if( eItemState != SfxItemState::SET )
973 if( eItemState == SfxItemState::UNKNOWN )
974 eItemState = SfxItemState::SET;
976 break;
977 default:
978 throw beans::UnknownPropertyException();
981 pWhichId++;
984 break;
986 case WID_NUMLEVEL:
987 case WID_NUMBERINGSTARTVALUE:
988 case WID_PARAISNUMBERINGRESTART:
989 eItemState = SfxItemState::SET;
990 break;
992 default:
993 nWID = pMap->nWID;
996 if( nWID != 0 )
998 if( nPara != -1 )
999 eItemState = pForwarder->GetItemState( nPara, nWID );
1000 else
1001 eItemState = pForwarder->GetItemState( GetSelection(), nWID );
1004 switch( eItemState )
1006 case SfxItemState::DONTCARE:
1007 case SfxItemState::DISABLED:
1008 return beans::PropertyState_AMBIGUOUS_VALUE;
1009 case SfxItemState::READONLY:
1010 case SfxItemState::SET:
1011 return beans::PropertyState_DIRECT_VALUE;
1012 case SfxItemState::DEFAULT:
1013 return beans::PropertyState_DEFAULT_VALUE;
1014 default: break;
1015 // case SfxItemState::UNKNOWN:
1019 throw beans::UnknownPropertyException();
1022 beans::PropertyState SvxUnoTextRangeBase::_getPropertyState(const OUString& PropertyName, sal_Int32 nPara /* = -1 */)
1024 SolarMutexGuard aGuard;
1026 return _getPropertyState( mpPropSet->getPropertyMapEntry( PropertyName ), nPara);
1029 uno::Sequence< beans::PropertyState > SAL_CALL SvxUnoTextRangeBase::getPropertyStates( const uno::Sequence< OUString >& aPropertyName )
1031 return _getPropertyStates( aPropertyName );
1034 uno::Sequence< beans::PropertyState > SvxUnoTextRangeBase::_getPropertyStates(const uno::Sequence< OUString >& PropertyName, sal_Int32 nPara /* = -1 */)
1036 uno::Sequence< beans::PropertyState > aRet( PropertyName.getLength() );
1038 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
1039 if( pForwarder )
1041 std::unique_ptr<SfxItemSet> pSet;
1042 if( nPara != -1 )
1044 pSet.reset(new SfxItemSet( pForwarder->GetParaAttribs( nPara ) ));
1046 else
1048 ESelection aSel( GetSelection() );
1049 CheckSelection( aSel, pForwarder );
1050 pSet.reset(new SfxItemSet( pForwarder->GetAttribs( aSel, EditEngineAttribs::OnlyHard ) ));
1053 beans::PropertyState* pState = aRet.getArray();
1054 for( const OUString& rName : PropertyName )
1056 const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry( rName );
1057 if( !_getOnePropertyStates(pSet.get(), pMap, *pState++) )
1059 throw beans::UnknownPropertyException(rName);
1064 return aRet;
1067 bool SvxUnoTextRangeBase::_getOnePropertyStates(const SfxItemSet* pSet, const SfxItemPropertySimpleEntry* pMap, beans::PropertyState& rState)
1069 bool bUnknownPropertyFound = false;
1070 if(pSet && pMap)
1072 SfxItemState eItemState = SfxItemState::UNKNOWN;
1073 sal_uInt16 nWID = 0;
1075 switch( pMap->nWID )
1077 case WID_FONTDESC:
1079 const sal_uInt16* pWhichId = aSvxUnoFontDescriptorWhichMap;
1080 SfxItemState eTempItemState = SfxItemState::UNKNOWN;
1081 while( *pWhichId )
1083 eTempItemState = pSet->GetItemState( *pWhichId );
1085 switch( eTempItemState )
1087 case SfxItemState::DISABLED:
1088 case SfxItemState::DONTCARE:
1089 eItemState = SfxItemState::DONTCARE;
1090 break;
1092 case SfxItemState::DEFAULT:
1093 if( eItemState != SfxItemState::DEFAULT )
1095 if( eItemState == SfxItemState::UNKNOWN )
1096 eItemState = SfxItemState::DEFAULT;
1098 break;
1100 case SfxItemState::READONLY:
1101 case SfxItemState::SET:
1102 if( eItemState != SfxItemState::SET )
1104 if( eItemState == SfxItemState::UNKNOWN )
1105 eItemState = SfxItemState::SET;
1107 break;
1108 default:
1109 bUnknownPropertyFound = true;
1110 break;
1113 pWhichId++;
1116 break;
1118 case WID_NUMLEVEL:
1119 case WID_NUMBERINGSTARTVALUE:
1120 case WID_PARAISNUMBERINGRESTART:
1121 eItemState = SfxItemState::SET;
1122 break;
1124 default:
1125 nWID = pMap->nWID;
1128 if( bUnknownPropertyFound )
1129 return false;
1131 if( nWID != 0 )
1132 eItemState = pSet->GetItemState( nWID, false );
1134 switch( eItemState )
1136 case SfxItemState::READONLY:
1137 case SfxItemState::SET:
1138 rState = beans::PropertyState_DIRECT_VALUE;
1139 break;
1140 case SfxItemState::DEFAULT:
1141 rState = beans::PropertyState_DEFAULT_VALUE;
1142 break;
1143 // case SfxItemState::UNKNOWN:
1144 // case SfxItemState::DONTCARE:
1145 // case SfxItemState::DISABLED:
1146 default:
1147 rState = beans::PropertyState_AMBIGUOUS_VALUE;
1150 return true;
1153 void SAL_CALL SvxUnoTextRangeBase::setPropertyToDefault( const OUString& PropertyName )
1155 _setPropertyToDefault( PropertyName );
1158 void SvxUnoTextRangeBase::_setPropertyToDefault(const OUString& PropertyName, sal_Int32 nPara /* = -1 */)
1160 SolarMutexGuard aGuard;
1162 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
1164 if( pForwarder )
1166 const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry( PropertyName );
1167 if ( pMap )
1169 CheckSelection( maSelection, mpEditSource->GetTextForwarder() );
1170 _setPropertyToDefault( pForwarder, pMap, nPara );
1171 return;
1175 throw beans::UnknownPropertyException(PropertyName);
1178 void SvxUnoTextRangeBase::_setPropertyToDefault(SvxTextForwarder* pForwarder, const SfxItemPropertySimpleEntry* pMap, sal_Int32 nPara )
1182 SfxItemSet aSet(*pForwarder->GetPool());
1184 if( pMap->nWID == WID_FONTDESC )
1186 SvxUnoFontDescriptor::setPropertyToDefault( aSet );
1188 else if( pMap->nWID == WID_NUMLEVEL )
1190 // #101004# Call interface method instead of unsafe cast
1191 pForwarder->SetDepth( maSelection.nStartPara, -1 );
1192 return;
1194 else if( pMap->nWID == WID_NUMBERINGSTARTVALUE )
1196 pForwarder->SetNumberingStartValue( maSelection.nStartPara, -1 );
1198 else if( pMap->nWID == WID_PARAISNUMBERINGRESTART )
1200 pForwarder->SetParaIsNumberingRestart( maSelection.nStartPara, false );
1202 else
1204 aSet.InvalidateItem( pMap->nWID );
1207 if(nPara != -1)
1208 pForwarder->SetParaAttribs( nPara, aSet );
1209 else
1210 pForwarder->QuickSetAttribs( aSet, GetSelection() );
1212 GetEditSource()->UpdateData();
1214 return;
1216 while(false);
1219 uno::Any SAL_CALL SvxUnoTextRangeBase::getPropertyDefault( const OUString& aPropertyName )
1221 SolarMutexGuard aGuard;
1223 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
1224 if( pForwarder )
1226 const SfxItemPropertySimpleEntry* pMap = mpPropSet->getPropertyMapEntry( aPropertyName );
1227 if( pMap )
1229 SfxItemPool* pPool = pForwarder->GetPool();
1231 switch( pMap->nWID )
1233 case WID_FONTDESC:
1234 return SvxUnoFontDescriptor::getPropertyDefault( pPool );
1236 case WID_NUMLEVEL:
1238 uno::Any aAny;
1239 return aAny;
1242 case WID_NUMBERINGSTARTVALUE:
1243 return uno::Any( sal_Int16(-1) );
1245 case WID_PARAISNUMBERINGRESTART:
1246 return uno::Any( false );
1248 default:
1250 // Get Default from ItemPool
1251 if(SfxItemPool::IsWhich(pMap->nWID))
1253 SfxItemSet aSet( *pPool, {{pMap->nWID, pMap->nWID}});
1254 aSet.Put(pPool->GetDefaultItem(pMap->nWID));
1255 return SvxItemPropertySet::getPropertyValue(pMap, aSet, true, false );
1261 throw beans::UnknownPropertyException(aPropertyName);
1264 // beans::XMultiPropertyStates
1265 void SAL_CALL SvxUnoTextRangeBase::setAllPropertiesToDefault()
1267 SolarMutexGuard aGuard;
1269 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
1271 if( pForwarder )
1273 for (auto & entry : mpPropSet->getPropertyMap().getPropertyEntries())
1275 _setPropertyToDefault( pForwarder, &entry, -1 );
1280 void SAL_CALL SvxUnoTextRangeBase::setPropertiesToDefault( const uno::Sequence< OUString >& aPropertyNames )
1282 for( const OUString& rName : aPropertyNames )
1284 setPropertyToDefault( rName );
1288 uno::Sequence< uno::Any > SAL_CALL SvxUnoTextRangeBase::getPropertyDefaults( const uno::Sequence< OUString >& aPropertyNames )
1290 uno::Sequence< uno::Any > ret( aPropertyNames.getLength() );
1291 uno::Any* pDefaults = ret.getArray();
1293 for( const OUString& rName : aPropertyNames )
1295 *pDefaults++ = getPropertyDefault( rName );
1298 return ret;
1301 // internal
1302 void SvxUnoTextRangeBase::CollapseToStart() throw()
1304 CheckSelection( maSelection, mpEditSource.get() );
1306 maSelection.nEndPara = maSelection.nStartPara;
1307 maSelection.nEndPos = maSelection.nStartPos;
1310 void SvxUnoTextRangeBase::CollapseToEnd() throw()
1312 CheckSelection( maSelection, mpEditSource.get() );
1314 maSelection.nStartPara = maSelection.nEndPara;
1315 maSelection.nStartPos = maSelection.nEndPos;
1318 bool SvxUnoTextRangeBase::IsCollapsed() throw()
1320 CheckSelection( maSelection, mpEditSource.get() );
1322 return ( maSelection.nStartPara == maSelection.nEndPara &&
1323 maSelection.nStartPos == maSelection.nEndPos );
1326 bool SvxUnoTextRangeBase::GoLeft(sal_Int16 nCount, bool Expand) throw()
1328 CheckSelection( maSelection, mpEditSource.get() );
1330 // #75098# use end position, as in Writer (start is anchor, end is cursor)
1331 sal_uInt16 nNewPos = maSelection.nEndPos;
1332 sal_Int32 nNewPar = maSelection.nEndPara;
1334 bool bOk = true;
1335 SvxTextForwarder* pForwarder = nullptr;
1336 while ( nCount > nNewPos && bOk )
1338 if ( nNewPar == 0 )
1339 bOk = false;
1340 else
1342 if ( !pForwarder )
1343 pForwarder = mpEditSource->GetTextForwarder(); // first here, it is necessary...
1345 --nNewPar;
1346 nCount -= nNewPos + 1;
1347 nNewPos = pForwarder->GetTextLen( nNewPar );
1351 if ( bOk )
1353 nNewPos = nNewPos - nCount;
1354 maSelection.nStartPara = nNewPar;
1355 maSelection.nStartPos = nNewPos;
1358 if (!Expand)
1359 CollapseToStart();
1361 return bOk;
1364 bool SvxUnoTextRangeBase::GoRight(sal_Int16 nCount, bool Expand) throw()
1366 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
1367 if( pForwarder )
1369 CheckSelection( maSelection, pForwarder );
1371 sal_Int32 nNewPos = maSelection.nEndPos + nCount; //! Overflow???
1372 sal_Int32 nNewPar = maSelection.nEndPara;
1374 bool bOk = true;
1375 sal_Int32 nParCount = pForwarder->GetParagraphCount();
1376 sal_Int32 nThisLen = pForwarder->GetTextLen( nNewPar );
1377 while ( nNewPos > nThisLen && bOk )
1379 if ( nNewPar + 1 >= nParCount )
1380 bOk = false;
1381 else
1383 nNewPos -= nThisLen+1;
1384 ++nNewPar;
1385 nThisLen = pForwarder->GetTextLen( nNewPar );
1389 if (bOk)
1391 maSelection.nEndPara = nNewPar;
1392 maSelection.nEndPos = nNewPos;
1395 if (!Expand)
1396 CollapseToEnd();
1398 return bOk;
1400 return false;
1403 void SvxUnoTextRangeBase::GotoStart(bool Expand) throw()
1405 maSelection.nStartPara = 0;
1406 maSelection.nStartPos = 0;
1408 if (!Expand)
1409 CollapseToStart();
1412 void SvxUnoTextRangeBase::GotoEnd(bool Expand) throw()
1414 CheckSelection( maSelection, mpEditSource.get() );
1416 SvxTextForwarder* pForwarder = mpEditSource ? mpEditSource->GetTextForwarder() : nullptr;
1417 if( pForwarder )
1420 sal_Int32 nPar = pForwarder->GetParagraphCount();
1421 if (nPar)
1422 --nPar;
1424 maSelection.nEndPara = nPar;
1425 maSelection.nEndPos = pForwarder->GetTextLen( nPar );
1427 if (!Expand)
1428 CollapseToEnd();
1432 // lang::XServiceInfo
1433 sal_Bool SAL_CALL SvxUnoTextRangeBase::supportsService( const OUString& ServiceName )
1435 return cppu::supportsService( this, ServiceName );
1438 uno::Sequence< OUString > SAL_CALL SvxUnoTextRangeBase::getSupportedServiceNames()
1440 return getSupportedServiceNames_Static();
1443 uno::Sequence< OUString > SvxUnoTextRangeBase::getSupportedServiceNames_Static()
1445 return { "com.sun.star.style.CharacterProperties",
1446 "com.sun.star.style.CharacterPropertiesComplex",
1447 "com.sun.star.style.CharacterPropertiesAsian" };
1450 // XTextRangeCompare
1451 sal_Int16 SAL_CALL SvxUnoTextRangeBase::compareRegionStarts( const uno::Reference< text::XTextRange >& xR1, const uno::Reference< text::XTextRange >& xR2 )
1453 SvxUnoTextRangeBase* pR1 = comphelper::getUnoTunnelImplementation<SvxUnoTextRangeBase>( xR1 );
1454 SvxUnoTextRangeBase* pR2 = comphelper::getUnoTunnelImplementation<SvxUnoTextRangeBase>( xR2 );
1456 if( (pR1 == nullptr) || (pR2 == nullptr) )
1457 throw lang::IllegalArgumentException();
1459 const ESelection& r1 = pR1->maSelection;
1460 const ESelection& r2 = pR2->maSelection;
1462 if( r1.nStartPara == r2.nStartPara )
1464 if( r1.nStartPos == r2.nStartPos )
1465 return 0;
1466 else
1467 return r1.nStartPos < r2.nStartPos ? 1 : -1;
1469 else
1471 return r1.nStartPara < r2.nStartPara ? 1 : -1;
1475 sal_Int16 SAL_CALL SvxUnoTextRangeBase::compareRegionEnds( const uno::Reference< text::XTextRange >& xR1, const uno::Reference< text::XTextRange >& xR2 )
1477 SvxUnoTextRangeBase* pR1 = comphelper::getUnoTunnelImplementation<SvxUnoTextRangeBase>( xR1 );
1478 SvxUnoTextRangeBase* pR2 = comphelper::getUnoTunnelImplementation<SvxUnoTextRangeBase>( xR2 );
1480 if( (pR1 == nullptr) || (pR2 == nullptr) )
1481 throw lang::IllegalArgumentException();
1483 const ESelection& r1 = pR1->maSelection;
1484 const ESelection& r2 = pR2->maSelection;
1486 if( r1.nEndPara == r2.nEndPara )
1488 if( r1.nEndPos == r2.nEndPos )
1489 return 0;
1490 else
1491 return r1.nEndPos < r2.nEndPos ? 1 : -1;
1493 else
1495 return r1.nEndPara < r2.nEndPara ? 1 : -1;
1499 SvxUnoTextRange::SvxUnoTextRange(const SvxUnoTextBase& rParent, bool bPortion /* = false */)
1500 :SvxUnoTextRangeBase( rParent.GetEditSource(), bPortion ? ImplGetSvxTextPortionSvxPropertySet() : rParent.getPropertySet() ),
1501 mbPortion( bPortion )
1503 xParentText = static_cast<text::XText*>(const_cast<SvxUnoTextBase *>(&rParent));
1506 SvxUnoTextRange::~SvxUnoTextRange() throw()
1510 uno::Any SAL_CALL SvxUnoTextRange::queryAggregation( const uno::Type & rType )
1512 QUERYINT( text::XTextRange );
1513 else if( rType == cppu::UnoType<beans::XMultiPropertyStates>::get())
1514 return uno::makeAny(uno::Reference< beans::XMultiPropertyStates >(this));
1515 else if( rType == cppu::UnoType<beans::XPropertySet>::get())
1516 return uno::makeAny(uno::Reference< beans::XPropertySet >(this));
1517 else QUERYINT( beans::XPropertyState );
1518 else QUERYINT( text::XTextRangeCompare );
1519 else if( rType == cppu::UnoType<beans::XMultiPropertySet>::get())
1520 return uno::makeAny(uno::Reference< beans::XMultiPropertySet >(this));
1521 else QUERYINT( lang::XServiceInfo );
1522 else QUERYINT( lang::XTypeProvider );
1523 else QUERYINT( lang::XUnoTunnel );
1524 else
1525 return OWeakAggObject::queryAggregation( rType );
1528 uno::Any SAL_CALL SvxUnoTextRange::queryInterface( const uno::Type & rType )
1530 return OWeakAggObject::queryInterface(rType);
1533 void SAL_CALL SvxUnoTextRange::acquire()
1534 throw( )
1536 OWeakAggObject::acquire();
1539 void SAL_CALL SvxUnoTextRange::release()
1540 throw( )
1542 OWeakAggObject::release();
1545 // XTypeProvider
1547 namespace
1549 struct theSvxUnoTextRangeTypes :
1550 public rtl::StaticWithInit<uno::Sequence<uno::Type>, theSvxUnoTextRangeTypes>
1552 uno::Sequence<uno::Type> operator () ()
1554 uno::Sequence< uno::Type > aTypeSequence;
1556 aTypeSequence.realloc( 9 ); // !DANGER! keep this updated
1557 uno::Type* pTypes = aTypeSequence.getArray();
1559 *pTypes++ = cppu::UnoType<text::XTextRange>::get();
1560 *pTypes++ = cppu::UnoType<beans::XPropertySet>::get();
1561 *pTypes++ = cppu::UnoType<beans::XMultiPropertySet>::get();
1562 *pTypes++ = cppu::UnoType<beans::XMultiPropertyStates>::get();
1563 *pTypes++ = cppu::UnoType<beans::XPropertyState>::get();
1564 *pTypes++ = cppu::UnoType<lang::XServiceInfo>::get();
1565 *pTypes++ = cppu::UnoType<lang::XTypeProvider>::get();
1566 *pTypes++ = cppu::UnoType<lang::XUnoTunnel>::get();
1567 *pTypes++ = cppu::UnoType<text::XTextRangeCompare>::get();
1569 return aTypeSequence;
1574 uno::Sequence< uno::Type > SAL_CALL SvxUnoTextRange::getTypes()
1576 return theSvxUnoTextRangeTypes::get();
1579 uno::Sequence< sal_Int8 > SAL_CALL SvxUnoTextRange::getImplementationId()
1581 return css::uno::Sequence<sal_Int8>();
1584 // XTextRange
1585 uno::Reference< text::XText > SAL_CALL SvxUnoTextRange::getText()
1587 return xParentText;
1590 // lang::XServiceInfo
1591 OUString SAL_CALL SvxUnoTextRange::getImplementationName()
1593 return "SvxUnoTextRange";
1597 // class SvxUnoText
1600 SvxUnoTextBase::SvxUnoTextBase(const SvxItemPropertySet* _pSet)
1601 : SvxUnoTextRangeBase(_pSet)
1605 SvxUnoTextBase::SvxUnoTextBase(const SvxEditSource* pSource, const SvxItemPropertySet* _pSet, uno::Reference < text::XText > const & xParent)
1606 : SvxUnoTextRangeBase(pSource, _pSet)
1608 xParentText = xParent;
1609 ESelection aSelection;
1610 ::GetSelection( aSelection, GetEditSource()->GetTextForwarder() );
1611 SetSelection( aSelection );
1614 SvxUnoTextBase::SvxUnoTextBase(const SvxUnoTextBase& rText)
1615 : SvxUnoTextRangeBase( rText )
1616 , text::XTextAppend()
1617 , text::XTextCopy()
1618 , container::XEnumerationAccess()
1619 , text::XTextRangeMover()
1620 , lang::XTypeProvider()
1622 xParentText = rText.xParentText;
1625 SvxUnoTextBase::~SvxUnoTextBase() throw()
1629 // XInterface
1630 uno::Any SAL_CALL SvxUnoTextBase::queryAggregation( const uno::Type & rType )
1632 QUERYINT( text::XText );
1633 QUERYINT( text::XSimpleText );
1634 if( rType == cppu::UnoType<text::XTextRange>::get())
1635 return uno::makeAny(uno::Reference< text::XTextRange >(static_cast<text::XText*>(this)));
1636 QUERYINT(container::XEnumerationAccess );
1637 QUERYINT( container::XElementAccess );
1638 QUERYINT( beans::XMultiPropertyStates );
1639 QUERYINT( beans::XPropertySet );
1640 QUERYINT( beans::XMultiPropertySet );
1641 QUERYINT( beans::XPropertyState );
1642 QUERYINT( text::XTextRangeCompare );
1643 QUERYINT( lang::XServiceInfo );
1644 QUERYINT( text::XTextRangeMover );
1645 QUERYINT( text::XTextCopy );
1646 QUERYINT( text::XTextAppend );
1647 QUERYINT( text::XParagraphAppend );
1648 QUERYINT( text::XTextPortionAppend );
1649 QUERYINT( lang::XTypeProvider );
1650 QUERYINT( lang::XUnoTunnel );
1652 return uno::Any();
1655 // XTypeProvider
1657 namespace
1659 struct theSvxUnoTextBaseTypes :
1660 public rtl::StaticWithInit<uno::Sequence<uno::Type>, theSvxUnoTextBaseTypes>
1662 uno::Sequence<uno::Type> operator () ()
1664 uno::Sequence< uno::Type > aTypeSequence;
1666 aTypeSequence.realloc( 15 ); // !DANGER! keep this updated
1667 uno::Type* pTypes = aTypeSequence.getArray();
1669 *pTypes++ = cppu::UnoType<text::XText>::get();
1670 *pTypes++ = cppu::UnoType<container::XEnumerationAccess>::get();
1671 *pTypes++ = cppu::UnoType<beans::XPropertySet>::get();
1672 *pTypes++ = cppu::UnoType<beans::XMultiPropertySet>::get();
1673 *pTypes++ = cppu::UnoType<beans::XMultiPropertyStates>::get();
1674 *pTypes++ = cppu::UnoType<beans::XPropertyState>::get();
1675 *pTypes++ = cppu::UnoType<text::XTextRangeMover>::get();
1676 *pTypes++ = cppu::UnoType<text::XTextAppend>::get();
1677 *pTypes++ = cppu::UnoType<text::XTextCopy>::get();
1678 *pTypes++ = cppu::UnoType<text::XParagraphAppend>::get();
1679 *pTypes++ = cppu::UnoType<text::XTextPortionAppend>::get();
1680 *pTypes++ = cppu::UnoType<lang::XServiceInfo>::get();
1681 *pTypes++ = cppu::UnoType<lang::XTypeProvider>::get();
1682 *pTypes++ = cppu::UnoType<lang::XUnoTunnel>::get();
1683 *pTypes++ = cppu::UnoType<text::XTextRangeCompare>::get();
1685 return aTypeSequence;
1690 uno::Sequence< uno::Type > SAL_CALL SvxUnoTextBase::getTypes()
1692 return theSvxUnoTextBaseTypes::get();
1695 uno::Sequence< sal_Int8 > SAL_CALL SvxUnoTextBase::getImplementationId()
1697 return css::uno::Sequence<sal_Int8>();
1700 uno::Reference< text::XTextCursor > SvxUnoTextBase::createTextCursorBySelection( const ESelection& rSel )
1702 SvxUnoTextCursor* pCursor = new SvxUnoTextCursor( *this );
1703 uno::Reference< text::XTextCursor > xCursor( pCursor );
1704 pCursor->SetSelection( rSel );
1705 return xCursor;
1708 // XSimpleText
1710 uno::Reference< text::XTextCursor > SAL_CALL SvxUnoTextBase::createTextCursor()
1712 SolarMutexGuard aGuard;
1713 return new SvxUnoTextCursor( *this );
1716 uno::Reference< text::XTextCursor > SAL_CALL SvxUnoTextBase::createTextCursorByRange( const uno::Reference< text::XTextRange >& aTextPosition )
1718 SolarMutexGuard aGuard;
1720 uno::Reference< text::XTextCursor > xCursor;
1722 if( aTextPosition.is() )
1724 SvxUnoTextRangeBase* pRange = comphelper::getUnoTunnelImplementation<SvxUnoTextRangeBase>( aTextPosition );
1725 if(pRange)
1726 xCursor = createTextCursorBySelection( pRange->GetSelection() );
1729 return xCursor;
1732 void SAL_CALL SvxUnoTextBase::insertString( const uno::Reference< text::XTextRange >& xRange, const OUString& aString, sal_Bool bAbsorb )
1734 SolarMutexGuard aGuard;
1736 if( !xRange.is() )
1737 return;
1739 ESelection aSelection;
1740 if (GetEditSource())
1742 ::GetSelection( aSelection, GetEditSource()->GetTextForwarder() );
1743 SetSelection( aSelection );
1746 SvxUnoTextRangeBase* pRange = comphelper::getUnoTunnelImplementation<SvxUnoTextRange>( xRange );
1747 if(pRange)
1749 // setString on SvxUnoTextRangeBase instead of itself QuickInsertText
1750 // and UpdateData, so that the selection will be adjusted to
1751 // SvxUnoTextRangeBase. Actually all cursor objects of this Text must
1752 // to be statement to be adapted!
1754 if (!bAbsorb) // do not replace -> append on tail
1755 pRange->CollapseToEnd();
1757 pRange->setString( aString );
1759 pRange->CollapseToEnd();
1763 void SAL_CALL SvxUnoTextBase::insertControlCharacter( const uno::Reference< text::XTextRange >& xRange, sal_Int16 nControlCharacter, sal_Bool bAbsorb )
1765 SolarMutexGuard aGuard;
1767 SvxTextForwarder* pForwarder = GetEditSource() ? GetEditSource()->GetTextForwarder() : nullptr;
1769 if( pForwarder )
1771 ESelection aSelection;
1772 ::GetSelection( aSelection, pForwarder );
1773 SetSelection( aSelection );
1775 switch( nControlCharacter )
1777 case text::ControlCharacter::PARAGRAPH_BREAK:
1779 const OUString aText( u'\x000D' ); // '\r' does not work on Mac
1780 insertString( xRange, aText, bAbsorb );
1782 return;
1784 case text::ControlCharacter::LINE_BREAK:
1786 SvxUnoTextRangeBase* pRange = comphelper::getUnoTunnelImplementation<SvxUnoTextRange>( xRange );
1787 if(pRange)
1789 ESelection aRange = pRange->GetSelection();
1791 if( bAbsorb )
1793 pForwarder->QuickInsertText( "", aRange );
1795 aRange.nEndPos = aRange.nStartPos;
1796 aRange.nEndPara = aRange.nStartPara;
1798 else
1800 aRange.nStartPara = aRange.nEndPara;
1801 aRange.nStartPos = aRange.nEndPos;
1804 pForwarder->QuickInsertLineBreak( aRange );
1805 GetEditSource()->UpdateData();
1807 aRange.nEndPos += 1;
1808 if( !bAbsorb )
1809 aRange.nStartPos += 1;
1811 pRange->SetSelection( aRange );
1813 return;
1815 case text::ControlCharacter::APPEND_PARAGRAPH:
1817 SvxUnoTextRangeBase* pRange = comphelper::getUnoTunnelImplementation<SvxUnoTextRange>( xRange );
1818 if(pRange)
1820 ESelection aRange = pRange->GetSelection();
1821 // ESelection aOldSelection = aRange;
1823 aRange.nStartPos = pForwarder->GetTextLen( aRange.nStartPara );
1825 aRange.nEndPara = aRange.nStartPara;
1826 aRange.nEndPos = aRange.nStartPos;
1828 pRange->SetSelection( aRange );
1829 const OUString aText( u'\x000D' ); // '\r' does not work on Mac
1830 pRange->setString( aText );
1832 aRange.nStartPos = 0;
1833 aRange.nStartPara += 1;
1834 aRange.nEndPos = 0;
1835 aRange.nEndPara += 1;
1837 pRange->SetSelection( aRange );
1839 return;
1841 [[fallthrough]];
1843 default:
1844 throw lang::IllegalArgumentException();
1849 // XText
1850 void SAL_CALL SvxUnoTextBase::insertTextContent( const uno::Reference< text::XTextRange >& xRange, const uno::Reference< text::XTextContent >& xContent, sal_Bool bAbsorb )
1852 SolarMutexGuard aGuard;
1854 SvxTextForwarder* pForwarder = GetEditSource() ? GetEditSource()->GetTextForwarder() : nullptr;
1855 if (!pForwarder)
1856 return;
1858 uno::Reference<beans::XPropertySet> xPropSet(xRange, uno::UNO_QUERY);
1859 if (!xPropSet.is())
1860 throw lang::IllegalArgumentException();
1862 uno::Any aAny = xPropSet->getPropertyValue(UNO_TR_PROP_SELECTION);
1863 text::TextRangeSelection aSel = aAny.get<text::TextRangeSelection>();
1864 if (!bAbsorb)
1865 aSel.Start = aSel.End;
1867 std::unique_ptr<SvxFieldData> pFieldData(SvxFieldData::Create(xContent));
1868 if (!pFieldData)
1869 throw lang::IllegalArgumentException();
1871 SvxFieldItem aField( *pFieldData, EE_FEATURE_FIELD );
1872 pForwarder->QuickInsertField(aField, toESelection(aSel));
1873 GetEditSource()->UpdateData();
1875 uno::Reference<beans::XPropertySet> xPropSetContent(xContent, uno::UNO_QUERY);
1876 if (!xContent.is())
1877 throw lang::IllegalArgumentException();
1879 xPropSetContent->setPropertyValue(UNO_TC_PROP_ANCHOR, uno::makeAny(xRange));
1881 aSel.End.PositionInParagraph += 1;
1882 aSel.Start.PositionInParagraph = aSel.End.PositionInParagraph;
1883 xPropSet->setPropertyValue(UNO_TR_PROP_SELECTION, uno::makeAny(aSel));
1886 void SAL_CALL SvxUnoTextBase::removeTextContent( const uno::Reference< text::XTextContent >& )
1890 // XTextRange
1892 uno::Reference< text::XText > SAL_CALL SvxUnoTextBase::getText()
1894 SolarMutexGuard aGuard;
1896 if (GetEditSource())
1898 ESelection aSelection;
1899 ::GetSelection( aSelection, GetEditSource()->GetTextForwarder() );
1900 SetSelection( aSelection );
1903 return static_cast<text::XText*>(this);
1906 uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::getStart()
1908 return SvxUnoTextRangeBase::getStart();
1911 uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::getEnd()
1913 return SvxUnoTextRangeBase::getEnd();
1916 OUString SAL_CALL SvxUnoTextBase::getString()
1918 return SvxUnoTextRangeBase::getString();
1921 void SAL_CALL SvxUnoTextBase::setString( const OUString& aString )
1923 SvxUnoTextRangeBase::setString(aString);
1927 // XEnumerationAccess
1928 uno::Reference< container::XEnumeration > SAL_CALL SvxUnoTextBase::createEnumeration()
1930 SolarMutexGuard aGuard;
1931 if( maSelection == ESelection(0,0,0,0) || maSelection == ESelection(EE_PARA_MAX_COUNT,0,0,0) )
1933 ESelection aSelection;
1934 ::GetSelection( aSelection, GetEditSource()->GetTextForwarder() );
1935 return new SvxUnoTextContentEnumeration(*this, aSelection);
1937 else
1939 return new SvxUnoTextContentEnumeration(*this, maSelection);
1943 // XElementAccess ( container::XEnumerationAccess )
1944 uno::Type SAL_CALL SvxUnoTextBase::getElementType( )
1946 return cppu::UnoType<text::XTextRange>::get();
1949 sal_Bool SAL_CALL SvxUnoTextBase::hasElements( )
1951 SolarMutexGuard aGuard;
1953 if(GetEditSource())
1955 SvxTextForwarder* pForwarder = GetEditSource()->GetTextForwarder();
1956 if(pForwarder)
1957 return pForwarder->GetParagraphCount() != 0;
1960 return false;
1963 // text::XTextRangeMover
1964 void SAL_CALL SvxUnoTextBase::moveTextRange( const uno::Reference< text::XTextRange >&, sal_Int16 )
1968 /// @throws lang::IllegalArgumentException
1969 /// @throws beans::UnknownPropertyException
1970 /// @throws uno::RuntimeException
1971 static void SvxPropertyValuesToItemSet(
1972 SfxItemSet &rItemSet,
1973 const uno::Sequence< beans::PropertyValue >& rPropertyVaules,
1974 const SfxItemPropertySet *pPropSet,
1975 SvxTextForwarder *pForwarder /*needed for WID_NUMLEVEL*/,
1976 sal_Int32 nPara /*needed for WID_NUMLEVEL*/)
1978 for (const beans::PropertyValue& rProp : rPropertyVaules)
1980 const SfxItemPropertySimpleEntry *pEntry = pPropSet->getPropertyMap().getByName( rProp.Name );
1981 if (!pEntry)
1982 throw beans::UnknownPropertyException( "Unknown property: " + rProp.Name, static_cast < cppu::OWeakObject * > ( nullptr ) );
1983 // Note: there is no need to take special care of the properties
1984 // TextField (EE_FEATURE_FIELD) and
1985 // TextPortionType (WID_PORTIONTYPE)
1986 // since they are read-only and thus are already taken care of below.
1988 if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
1989 // should be PropertyVetoException which is not yet defined for the new import API's functions
1990 throw uno::RuntimeException("Property is read-only: " + rProp.Name, static_cast < cppu::OWeakObject * > ( nullptr ) );
1991 //throw PropertyVetoException ("Property is read-only: " + rProp.Name, static_cast < cppu::OWeakObject * > ( 0 ) );
1993 if (pEntry->nWID == WID_FONTDESC)
1995 awt::FontDescriptor aDesc;
1996 if (rProp.Value >>= aDesc)
1997 SvxUnoFontDescriptor::FillItemSet( aDesc, rItemSet );
1999 else if (pEntry->nWID == WID_NUMLEVEL)
2001 if (pForwarder)
2003 sal_Int16 nLevel = -1;
2004 rProp.Value >>= nLevel;
2006 // #101004# Call interface method instead of unsafe cast
2007 if (!pForwarder->SetDepth( nPara, nLevel ))
2008 throw lang::IllegalArgumentException();
2011 else if (pEntry->nWID == WID_NUMBERINGSTARTVALUE )
2013 if( pForwarder )
2015 sal_Int16 nStartValue = -1;
2016 if( !(rProp.Value >>= nStartValue) )
2017 throw lang::IllegalArgumentException();
2019 pForwarder->SetNumberingStartValue( nPara, nStartValue );
2022 else if (pEntry->nWID == WID_PARAISNUMBERINGRESTART )
2024 if( pForwarder )
2026 bool bParaIsNumberingRestart = false;
2027 if( !(rProp.Value >>= bParaIsNumberingRestart) )
2028 throw lang::IllegalArgumentException();
2030 pForwarder->SetParaIsNumberingRestart( nPara, bParaIsNumberingRestart );
2033 else
2034 pPropSet->setPropertyValue( rProp.Name, rProp.Value, rItemSet );
2038 uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::finishParagraphInsert(
2039 const uno::Sequence< beans::PropertyValue >& /*rCharAndParaProps*/,
2040 const uno::Reference< text::XTextRange >& /*rTextRange*/ )
2042 uno::Reference< text::XTextRange > xRet;
2043 return xRet;
2046 uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::finishParagraph(
2047 const uno::Sequence< beans::PropertyValue >& rCharAndParaProps )
2049 SolarMutexGuard aGuard;
2051 uno::Reference< text::XTextRange > xRet;
2052 SvxEditSource *pEditSource = GetEditSource();
2053 SvxTextForwarder *pTextForwarder = pEditSource ? pEditSource->GetTextForwarder() : nullptr;
2054 if (pTextForwarder)
2056 sal_Int32 nParaCount = pTextForwarder->GetParagraphCount();
2057 DBG_ASSERT( nParaCount > 0, "paragraph count is 0 or negative" );
2058 pTextForwarder->AppendParagraph();
2060 // set properties for the previously last paragraph
2061 sal_Int32 nPara = nParaCount - 1;
2062 ESelection aSel( nPara, 0, nPara, 0 );
2063 SfxItemSet aItemSet( *pTextForwarder->GetEmptyItemSetPtr() );
2064 SvxPropertyValuesToItemSet( aItemSet, rCharAndParaProps,
2065 ImplGetSvxUnoOutlinerTextCursorSfxPropertySet(), pTextForwarder, nPara );
2066 pTextForwarder->QuickSetAttribs( aItemSet, aSel );
2067 pEditSource->UpdateData();
2068 SvxUnoTextRange* pRange = new SvxUnoTextRange( *this );
2069 xRet = pRange;
2070 pRange->SetSelection( aSel );
2072 return xRet;
2075 uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::insertTextPortion(
2076 const OUString& /*rText*/,
2077 const uno::Sequence< beans::PropertyValue >& /*rCharAndParaProps*/,
2078 const uno::Reference< text::XTextRange>& /*rTextRange*/ )
2080 uno::Reference< text::XTextRange > xRet;
2081 return xRet;
2084 // css::text::XTextPortionAppend (new import API)
2085 uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::appendTextPortion(
2086 const OUString& rText,
2087 const uno::Sequence< beans::PropertyValue >& rCharAndParaProps )
2089 SolarMutexGuard aGuard;
2091 SvxEditSource *pEditSource = GetEditSource();
2092 SvxTextForwarder *pTextForwarder = pEditSource ? pEditSource->GetTextForwarder() : nullptr;
2093 uno::Reference< text::XTextRange > xRet;
2094 if (pTextForwarder)
2096 sal_Int32 nParaCount = pTextForwarder->GetParagraphCount();
2097 DBG_ASSERT( nParaCount > 0, "paragraph count is 0 or negative" );
2098 sal_Int32 nPara = nParaCount - 1;
2099 SfxItemSet aSet( pTextForwarder->GetParaAttribs( nPara ) );
2100 sal_Int32 nStart = pTextForwarder->AppendTextPortion( nPara, rText, aSet );
2101 pEditSource->UpdateData();
2102 sal_Int32 nEnd = pTextForwarder->GetTextLen( nPara );
2104 // set properties for the new text portion
2105 ESelection aSel( nPara, nStart, nPara, nEnd );
2106 pTextForwarder->RemoveAttribs( aSel );
2107 pEditSource->UpdateData();
2109 SfxItemSet aItemSet( *pTextForwarder->GetEmptyItemSetPtr() );
2110 SvxPropertyValuesToItemSet( aItemSet, rCharAndParaProps,
2111 ImplGetSvxTextPortionSfxPropertySet(), pTextForwarder, nPara );
2112 pTextForwarder->QuickSetAttribs( aItemSet, aSel );
2113 SvxUnoTextRange* pRange = new SvxUnoTextRange( *this );
2114 xRet = pRange;
2115 pRange->SetSelection( aSel );
2116 for( const beans::PropertyValue& rProp : rCharAndParaProps )
2117 pRange->setPropertyValue( rProp.Name, rProp.Value );
2119 return xRet;
2122 void SvxUnoTextBase::copyText(
2123 const uno::Reference< text::XTextCopy >& xSource )
2125 SolarMutexGuard aGuard;
2126 uno::Reference< lang::XUnoTunnel > xUT( xSource, uno::UNO_QUERY );
2127 SvxEditSource *pEditSource = GetEditSource();
2128 SvxTextForwarder *pTextForwarder = pEditSource ? pEditSource->GetTextForwarder() : nullptr;
2129 if( !pTextForwarder )
2130 return;
2131 if( xUT.is() )
2133 SvxUnoTextBase* pSource = reinterpret_cast<SvxUnoTextBase*>(sal::static_int_cast<sal_uIntPtr>(
2134 xUT->getSomething( SvxUnoTextBase::getUnoTunnelId())));
2135 SvxEditSource *pSourceEditSource = pSource->GetEditSource();
2136 SvxTextForwarder *pSourceTextForwarder = pSourceEditSource ? pSourceEditSource->GetTextForwarder() : nullptr;
2137 if( pSourceTextForwarder )
2139 pTextForwarder->CopyText( *pSourceTextForwarder );
2140 pEditSource->UpdateData();
2143 else
2145 uno::Reference< text::XText > xSourceText( xSource, uno::UNO_QUERY );
2146 if( xSourceText.is() )
2148 setString( xSourceText->getString() );
2153 // lang::XServiceInfo
2154 OUString SAL_CALL SvxUnoTextBase::getImplementationName()
2156 return "SvxUnoTextBase";
2159 uno::Sequence< OUString > SAL_CALL SvxUnoTextBase::getSupportedServiceNames( )
2161 return getSupportedServiceNames_Static();
2164 uno::Sequence< OUString > SAL_CALL SvxUnoTextBase::getSupportedServiceNames_Static( )
2166 uno::Sequence< OUString > aSeq( SvxUnoTextRangeBase::getSupportedServiceNames_Static() );
2167 comphelper::ServiceInfoHelper::addToSequence( aSeq, {"com.sun.star.text.Text"} );
2168 return aSeq;
2171 namespace
2173 class theSvxUnoTextBaseUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSvxUnoTextBaseUnoTunnelId > {};
2176 const uno::Sequence< sal_Int8 > & SvxUnoTextBase::getUnoTunnelId() throw()
2178 return theSvxUnoTextBaseUnoTunnelId::get().getSeq();
2181 sal_Int64 SAL_CALL SvxUnoTextBase::getSomething( const uno::Sequence< sal_Int8 >& rId )
2183 if( isUnoTunnelId<SvxUnoTextBase>(rId) )
2185 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
2187 else
2189 return SvxUnoTextRangeBase::getSomething( rId );
2193 SvxUnoText::SvxUnoText( const SvxItemPropertySet* _pSet ) throw()
2194 : SvxUnoTextBase( _pSet )
2198 SvxUnoText::SvxUnoText( const SvxEditSource* pSource, const SvxItemPropertySet* _pSet, uno::Reference < text::XText > const & xParent ) throw()
2199 : SvxUnoTextBase( pSource, _pSet, xParent )
2203 SvxUnoText::SvxUnoText( const SvxUnoText& rText ) throw()
2204 : SvxUnoTextBase( rText )
2205 , cppu::OWeakAggObject()
2209 SvxUnoText::~SvxUnoText() throw()
2213 // uno::XInterface
2214 uno::Any SAL_CALL SvxUnoText::queryAggregation( const uno::Type & rType )
2216 uno::Any aAny( SvxUnoTextBase::queryAggregation( rType ) );
2217 if( !aAny.hasValue() )
2218 aAny = OWeakAggObject::queryAggregation( rType );
2220 return aAny;
2223 uno::Any SAL_CALL SvxUnoText::queryInterface( const uno::Type & rType )
2225 return OWeakAggObject::queryInterface( rType );
2228 void SAL_CALL SvxUnoText::acquire() throw( )
2230 OWeakAggObject::acquire();
2233 void SAL_CALL SvxUnoText::release() throw( )
2235 OWeakAggObject::release();
2238 // lang::XTypeProvider
2239 uno::Sequence< uno::Type > SAL_CALL SvxUnoText::getTypes( )
2241 return SvxUnoTextBase::getTypes();
2244 uno::Sequence< sal_Int8 > SAL_CALL SvxUnoText::getImplementationId( )
2246 return css::uno::Sequence<sal_Int8>();
2249 namespace
2251 class theSvxUnoTextUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSvxUnoTextUnoTunnelId > {};
2254 const uno::Sequence< sal_Int8 > & SvxUnoText::getUnoTunnelId() throw()
2256 return theSvxUnoTextUnoTunnelId::get().getSeq();
2259 sal_Int64 SAL_CALL SvxUnoText::getSomething( const uno::Sequence< sal_Int8 >& rId )
2261 if( isUnoTunnelId<SvxUnoText>(rId) )
2263 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
2265 else
2267 return SvxUnoTextBase::getSomething( rId );
2272 SvxDummyTextSource::~SvxDummyTextSource()
2276 std::unique_ptr<SvxEditSource> SvxDummyTextSource::Clone() const
2278 return std::unique_ptr<SvxEditSource>(new SvxDummyTextSource);
2281 SvxTextForwarder* SvxDummyTextSource::GetTextForwarder()
2283 return this;
2286 void SvxDummyTextSource::UpdateData()
2290 sal_Int32 SvxDummyTextSource::GetParagraphCount() const
2292 return 0;
2295 sal_Int32 SvxDummyTextSource::GetTextLen( sal_Int32 ) const
2297 return 0;
2300 OUString SvxDummyTextSource::GetText( const ESelection& ) const
2302 return OUString();
2305 SfxItemSet SvxDummyTextSource::GetAttribs( const ESelection&, EditEngineAttribs ) const
2307 // Very dangerous: The former implementation used a SfxItemPool created on the
2308 // fly which of course was deleted again ASAP. Thus, the returned SfxItemSet was using
2309 // a deleted Pool by design.
2310 return SfxItemSet(EditEngine::GetGlobalItemPool());
2313 SfxItemSet SvxDummyTextSource::GetParaAttribs( sal_Int32 ) const
2315 return GetAttribs(ESelection());
2318 void SvxDummyTextSource::SetParaAttribs( sal_Int32, const SfxItemSet& )
2322 void SvxDummyTextSource::RemoveAttribs( const ESelection& )
2326 void SvxDummyTextSource::GetPortions( sal_Int32, std::vector<sal_Int32>& ) const
2330 SfxItemState SvxDummyTextSource::GetItemState( const ESelection&, sal_uInt16 ) const
2332 return SfxItemState::UNKNOWN;
2335 SfxItemState SvxDummyTextSource::GetItemState( sal_Int32, sal_uInt16 ) const
2337 return SfxItemState::UNKNOWN;
2340 SfxItemPool* SvxDummyTextSource::GetPool() const
2342 return nullptr;
2345 void SvxDummyTextSource::QuickInsertText( const OUString&, const ESelection& )
2349 void SvxDummyTextSource::QuickInsertField( const SvxFieldItem&, const ESelection& )
2353 void SvxDummyTextSource::QuickSetAttribs( const SfxItemSet&, const ESelection& )
2357 void SvxDummyTextSource::QuickInsertLineBreak( const ESelection& )
2361 OUString SvxDummyTextSource::CalcFieldValue( const SvxFieldItem&, sal_Int32, sal_Int32, boost::optional<Color>&, boost::optional<Color>& )
2363 return OUString();
2366 void SvxDummyTextSource::FieldClicked( const SvxFieldItem& )
2370 bool SvxDummyTextSource::IsValid() const
2372 return false;
2375 LanguageType SvxDummyTextSource::GetLanguage( sal_Int32, sal_Int32 ) const
2377 return LANGUAGE_DONTKNOW;
2380 sal_Int32 SvxDummyTextSource::GetFieldCount( sal_Int32 ) const
2382 return 0;
2385 EFieldInfo SvxDummyTextSource::GetFieldInfo( sal_Int32, sal_uInt16 ) const
2387 return EFieldInfo();
2390 EBulletInfo SvxDummyTextSource::GetBulletInfo( sal_Int32 ) const
2392 return EBulletInfo();
2395 tools::Rectangle SvxDummyTextSource::GetCharBounds( sal_Int32, sal_Int32 ) const
2397 return tools::Rectangle();
2400 tools::Rectangle SvxDummyTextSource::GetParaBounds( sal_Int32 ) const
2402 return tools::Rectangle();
2405 MapMode SvxDummyTextSource::GetMapMode() const
2407 return MapMode();
2410 OutputDevice* SvxDummyTextSource::GetRefDevice() const
2412 return nullptr;
2415 bool SvxDummyTextSource::GetIndexAtPoint( const Point&, sal_Int32&, sal_Int32& ) const
2417 return false;
2420 bool SvxDummyTextSource::GetWordIndices( sal_Int32, sal_Int32, sal_Int32&, sal_Int32& ) const
2422 return false;
2425 bool SvxDummyTextSource::GetAttributeRun( sal_Int32&, sal_Int32&, sal_Int32, sal_Int32, bool ) const
2427 return false;
2430 sal_Int32 SvxDummyTextSource::GetLineCount( sal_Int32 ) const
2432 return 0;
2435 sal_Int32 SvxDummyTextSource::GetLineLen( sal_Int32, sal_Int32 ) const
2437 return 0;
2440 void SvxDummyTextSource::GetLineBoundaries( /*out*/sal_Int32 &rStart, /*out*/sal_Int32 &rEnd, sal_Int32 /*nParagraph*/, sal_Int32 /*nLine*/ ) const
2442 rStart = rEnd = 0;
2445 sal_Int32 SvxDummyTextSource::GetLineNumberAtIndex( sal_Int32 /*nPara*/, sal_Int32 /*nIndex*/ ) const
2447 return 0;
2450 bool SvxDummyTextSource::QuickFormatDoc( bool )
2452 return false;
2455 sal_Int16 SvxDummyTextSource::GetDepth( sal_Int32 ) const
2457 return -1;
2460 bool SvxDummyTextSource::SetDepth( sal_Int32, sal_Int16 nNewDepth )
2462 return nNewDepth == 0;
2465 bool SvxDummyTextSource::Delete( const ESelection& )
2467 return false;
2470 bool SvxDummyTextSource::InsertText( const OUString&, const ESelection& )
2472 return false;
2475 const SfxItemSet * SvxDummyTextSource::GetEmptyItemSetPtr()
2477 return nullptr;
2480 void SvxDummyTextSource::AppendParagraph()
2484 sal_Int32 SvxDummyTextSource::AppendTextPortion( sal_Int32, const OUString &, const SfxItemSet & )
2486 return 0;
2489 void SvxDummyTextSource::CopyText(const SvxTextForwarder& )
2493 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */