1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <initializer_list>
23 #include <string_view>
25 #include <o3tl/safeint.hxx>
26 #include <vcl/svapp.hxx>
28 #include <editeng/unotext.hxx>
29 #include <comphelper/sequence.hxx>
30 #include <cppuhelper/supportsservice.hxx>
32 using namespace ::cppu
;
33 using namespace ::com::sun::star
;
35 #define QUERYINT( xint ) \
36 if( rType == cppu::UnoType<xint>::get() ) \
37 return uno::Any(uno::Reference< xint >(this))
40 // SvxUnoTextContentEnumeration
43 SvxUnoTextContentEnumeration::SvxUnoTextContentEnumeration( const SvxUnoTextBase
& rText
, const ESelection
& rSel
) noexcept
45 mxParentText
= const_cast<SvxUnoTextBase
*>(&rText
);
46 if( rText
.GetEditSource() )
47 mpEditSource
= rText
.GetEditSource()->Clone();
53 const SvxTextForwarder
* pTextForwarder
= rText
.GetEditSource()->GetTextForwarder();
54 const sal_Int32 maxParaIndex
= std::min( rSel
.end
.nPara
+ 1, pTextForwarder
->GetParagraphCount() );
56 for (sal_Int32 currentPara
= rSel
.start
.nPara
; currentPara
< maxParaIndex
; currentPara
++)
58 const SvxUnoTextRangeBaseVec
& rRanges( mpEditSource
->getRanges() );
59 rtl::Reference
<SvxUnoTextContent
> pContent
;
60 sal_Int32 nStartPos
= 0;
61 sal_Int32 nEndPos
= pTextForwarder
->GetTextLen( currentPara
);
62 if (currentPara
== rSel
.start
.nPara
)
63 nStartPos
= std::max(nStartPos
, rSel
.start
.nIndex
);
64 if (currentPara
== rSel
.end
.nPara
)
65 nEndPos
= std::min(nEndPos
, rSel
.end
.nIndex
);
66 ESelection
aCurrentParaSel( currentPara
, nStartPos
, currentPara
, nEndPos
);
67 for (auto const& elemRange
: rRanges
)
71 SvxUnoTextContent
* pIterContent
= dynamic_cast< SvxUnoTextContent
* >( elemRange
);
72 if( pIterContent
&& (pIterContent
->mnParagraph
== currentPara
) )
74 ESelection aIterSel
= pIterContent
->GetSelection();
75 if( aIterSel
== aCurrentParaSel
)
77 pContent
= pIterContent
;
78 maContents
.emplace_back(pContent
);
82 if( pContent
== nullptr )
84 pContent
= new SvxUnoTextContent( rText
, currentPara
);
85 pContent
->SetSelection( aCurrentParaSel
);
86 maContents
.emplace_back(pContent
);
91 SvxUnoTextContentEnumeration::~SvxUnoTextContentEnumeration() noexcept
95 // container::XEnumeration
96 sal_Bool SAL_CALL
SvxUnoTextContentEnumeration::hasMoreElements()
98 SolarMutexGuard aGuard
;
99 if( mpEditSource
&& !maContents
.empty() )
100 return o3tl::make_unsigned(mnNextParagraph
) < maContents
.size();
105 uno::Any
SvxUnoTextContentEnumeration::nextElement()
107 SolarMutexGuard aGuard
;
109 if(!hasMoreElements())
110 throw container::NoSuchElementException();
112 uno::Reference
< text::XTextContent
> xRef( maContents
.at(mnNextParagraph
) );
114 return uno::Any( xRef
);
120 SvxUnoTextContent::SvxUnoTextContent( const SvxUnoTextBase
& rText
, sal_Int32 nPara
) noexcept
121 : SvxUnoTextRangeBase(rText
)
123 , mrParentText(rText
)
124 , mbDisposing( false )
126 mxParentText
= const_cast<SvxUnoTextBase
*>(&rText
);
129 SvxUnoTextContent::SvxUnoTextContent( const SvxUnoTextContent
& rContent
) noexcept
130 : SvxUnoTextRangeBase(rContent
)
131 , text::XTextContent()
132 , container::XEnumerationAccess()
133 , lang::XTypeProvider()
134 , cppu::OWeakAggObject()
135 , mrParentText(rContent
.mrParentText
)
136 , mbDisposing( false )
138 mxParentText
= rContent
.mxParentText
;
139 mnParagraph
= rContent
.mnParagraph
;
140 SetSelection( rContent
.GetSelection() );
143 SvxUnoTextContent::~SvxUnoTextContent() noexcept
148 uno::Any SAL_CALL
SvxUnoTextContent::queryAggregation( const uno::Type
& rType
)
150 QUERYINT( text::XTextRange
);
151 else QUERYINT( beans::XMultiPropertyStates
);
152 else QUERYINT( beans::XPropertySet
);
153 else QUERYINT( beans::XMultiPropertySet
);
154 else QUERYINT( beans::XPropertyState
);
155 else QUERYINT( text::XTextContent
);
156 else QUERYINT( text::XTextRangeCompare
);
157 else QUERYINT( lang::XComponent
);
158 else QUERYINT( container::XEnumerationAccess
);
159 else QUERYINT( container::XElementAccess
);
160 else QUERYINT( lang::XServiceInfo
);
161 else QUERYINT( lang::XTypeProvider
);
162 else QUERYINT( lang::XUnoTunnel
);
164 return OWeakAggObject::queryAggregation( rType
);
167 uno::Any SAL_CALL
SvxUnoTextContent::queryInterface( const uno::Type
& rType
)
169 return OWeakAggObject::queryInterface(rType
);
172 void SAL_CALL
SvxUnoTextContent::acquire() noexcept
174 OWeakAggObject::acquire();
177 void SAL_CALL
SvxUnoTextContent::release() noexcept
179 OWeakAggObject::release();
184 uno::Sequence
< uno::Type
> SAL_CALL
SvxUnoTextContent::getTypes()
186 static const uno::Sequence
< uno::Type
> TYPES
{
187 cppu::UnoType
<text::XTextRange
>::get(),
188 cppu::UnoType
<beans::XPropertySet
>::get(),
189 cppu::UnoType
<beans::XMultiPropertySet
>::get(),
190 cppu::UnoType
<beans::XMultiPropertyStates
>::get(),
191 cppu::UnoType
<beans::XPropertyState
>::get(),
192 cppu::UnoType
<text::XTextRangeCompare
>::get(),
193 cppu::UnoType
<text::XTextContent
>::get(),
194 cppu::UnoType
<container::XEnumerationAccess
>::get(),
195 cppu::UnoType
<lang::XServiceInfo
>::get(),
196 cppu::UnoType
<lang::XTypeProvider
>::get(),
197 cppu::UnoType
<lang::XUnoTunnel
>::get() };
201 uno::Sequence
< sal_Int8
> SAL_CALL
SvxUnoTextContent::getImplementationId()
203 return css::uno::Sequence
<sal_Int8
>();
208 uno::Reference
< text::XText
> SAL_CALL
SvxUnoTextContent::getText()
213 // text::XTextContent
214 void SAL_CALL
SvxUnoTextContent::attach( const uno::Reference
< text::XTextRange
>& )
218 uno::Reference
< text::XTextRange
> SAL_CALL
SvxUnoTextContent::getAnchor()
225 void SAL_CALL
SvxUnoTextContent::dispose()
227 SolarMutexGuard aGuard
;
230 return; // caught a recursion
234 lang::EventObject aEvt
;
235 aEvt
.Source
= *static_cast<OWeakAggObject
*>(this);
237 std::unique_lock
aMutexGuard(maDisposeContainerMutex
);
238 maDisposeListeners
.disposeAndClear(aMutexGuard
, aEvt
);
241 if( mxParentText
.is() )
243 mxParentText
->removeTextContent( this );
244 mxParentText
.clear();
248 void SAL_CALL
SvxUnoTextContent::addEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
250 std::unique_lock
aGuard(maDisposeContainerMutex
);
251 maDisposeListeners
.addInterface(aGuard
, xListener
);
254 void SAL_CALL
SvxUnoTextContent::removeEventListener( const uno::Reference
< lang::XEventListener
>& aListener
)
256 std::unique_lock
aGuard(maDisposeContainerMutex
);
257 maDisposeListeners
.removeInterface(aGuard
, aListener
);
260 // XEnumerationAccess
262 uno::Reference
< container::XEnumeration
> SAL_CALL
SvxUnoTextContent::createEnumeration()
264 SolarMutexGuard aGuard
;
266 return new SvxUnoTextRangeEnumeration( mrParentText
, mnParagraph
, maSelection
);
269 // XElementAccess ( container::XEnumerationAccess )
271 uno::Type SAL_CALL
SvxUnoTextContent::getElementType()
273 return cppu::UnoType
<text::XTextRange
>::get();
276 sal_Bool SAL_CALL
SvxUnoTextContent::hasElements()
278 SolarMutexGuard aGuard
;
280 SvxTextForwarder
* pForwarder
= GetEditSource() ? GetEditSource()->GetTextForwarder() : nullptr;
283 std::vector
<sal_Int32
> aPortions
;
284 pForwarder
->GetPortions( mnParagraph
, aPortions
);
285 return !aPortions
.empty();
295 void SAL_CALL
SvxUnoTextContent::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& aValue
)
297 _setPropertyValue( aPropertyName
, aValue
, mnParagraph
);
300 uno::Any SAL_CALL
SvxUnoTextContent::getPropertyValue( const OUString
& PropertyName
)
302 return _getPropertyValue( PropertyName
, mnParagraph
);
306 void SAL_CALL
SvxUnoTextContent::setPropertyValues( const uno::Sequence
< OUString
>& aPropertyNames
, const uno::Sequence
< uno::Any
>& aValues
)
308 _setPropertyValues( aPropertyNames
, aValues
, mnParagraph
);
311 uno::Sequence
< uno::Any
> SAL_CALL
SvxUnoTextContent::getPropertyValues( const uno::Sequence
< OUString
>& aPropertyNames
)
313 return _getPropertyValues( aPropertyNames
, mnParagraph
);
316 /*// XTolerantMultiPropertySet
317 uno::Sequence< beans::SetPropertyTolerantFailed > SAL_CALL SvxUnoTextContent::setPropertyValuesTolerant( const uno::Sequence< OUString >& aPropertyNames, const uno::Sequence< uno::Any >& aValues ) throw (lang::IllegalArgumentException, uno::RuntimeException)
319 return _setPropertyValuesTolerant(aPropertyNames, aValues, mnParagraph);
322 uno::Sequence< beans::GetPropertyTolerantResult > SAL_CALL SvxUnoTextContent::getPropertyValuesTolerant( const uno::Sequence< OUString >& aPropertyNames ) throw (uno::RuntimeException)
324 return _getPropertyValuesTolerant(aPropertyNames, mnParagraph);
327 uno::Sequence< beans::GetDirectPropertyTolerantResult > SAL_CALL SvxUnoTextContent::getDirectPropertyValuesTolerant( const uno::Sequence< OUString >& aPropertyNames )
328 throw (uno::RuntimeException)
330 return _getDirectPropertyValuesTolerant(aPropertyNames, mnParagraph);
333 // beans::XPropertyState
334 beans::PropertyState SAL_CALL
SvxUnoTextContent::getPropertyState( const OUString
& PropertyName
)
336 return _getPropertyState( PropertyName
, mnParagraph
);
339 uno::Sequence
< beans::PropertyState
> SAL_CALL
SvxUnoTextContent::getPropertyStates( const uno::Sequence
< OUString
>& aPropertyName
)
341 return _getPropertyStates( aPropertyName
, mnParagraph
);
344 void SAL_CALL
SvxUnoTextContent::setPropertyToDefault( const OUString
& PropertyName
)
346 _setPropertyToDefault( PropertyName
, mnParagraph
);
349 // lang::XServiceInfo
351 OUString SAL_CALL
SvxUnoTextContent::getImplementationName()
353 return u
"SvxUnoTextContent"_ustr
;
356 uno::Sequence
< OUString
> SAL_CALL
SvxUnoTextContent::getSupportedServiceNames()
358 return comphelper::concatSequences(
359 SvxUnoTextRangeBase::getSupportedServiceNames(),
360 std::initializer_list
<std::u16string_view
>{ u
"com.sun.star.style.ParagraphProperties",
361 u
"com.sun.star.style.ParagraphPropertiesComplex",
362 u
"com.sun.star.style.ParagraphPropertiesAsian",
363 u
"com.sun.star.text.TextContent",
364 u
"com.sun.star.text.Paragraph" });
370 SvxUnoTextRangeEnumeration::SvxUnoTextRangeEnumeration(const SvxUnoTextBase
& rParentText
, sal_Int32 nParagraph
, const ESelection
& rSel
)
371 : mxParentText( const_cast<SvxUnoTextBase
*>(&rParentText
) ),
374 if (rParentText
.GetEditSource())
375 mpEditSource
= rParentText
.GetEditSource()->Clone();
377 if( !(mpEditSource
&& mpEditSource
->GetTextForwarder() && (nParagraph
== rSel
.start
.nPara
&& nParagraph
== rSel
.end
.nPara
)) )
380 std::vector
<sal_Int32
> aPortions
;
381 mpEditSource
->GetTextForwarder()->GetPortions( nParagraph
, aPortions
);
382 for( size_t aPortionIndex
= 0; aPortionIndex
< aPortions
.size(); aPortionIndex
++ )
384 sal_Int32 nStartPos
= 0;
385 if ( aPortionIndex
> 0 )
386 nStartPos
= aPortions
.at( aPortionIndex
- 1 );
387 if (nStartPos
> rSel
.end
.nIndex
)
389 sal_Int32 nEndPos
= aPortions
.at(aPortionIndex
);
390 if (nEndPos
< rSel
.start
.nIndex
)
393 nStartPos
= std::max(nStartPos
, rSel
.start
.nIndex
);
394 nEndPos
= std::min(nEndPos
, rSel
.end
.nIndex
);
395 ESelection
aSel( nParagraph
, nStartPos
, nParagraph
, nEndPos
);
397 const SvxUnoTextRangeBaseVec
& rRanges( mpEditSource
->getRanges() );
398 rtl::Reference
<SvxUnoTextRange
> pRange
;
399 for (auto const& elemRange
: rRanges
)
403 SvxUnoTextRange
* pIterRange
= dynamic_cast< SvxUnoTextRange
* >( elemRange
);
404 if( pIterRange
&& pIterRange
->mbPortion
&& (aSel
== pIterRange
->maSelection
) )
407 if( pRange
== nullptr )
409 pRange
= new SvxUnoTextRange( rParentText
, true );
410 pRange
->SetSelection( aSel
);
412 maPortions
.emplace_back(pRange
);
416 SvxUnoTextRangeEnumeration::~SvxUnoTextRangeEnumeration() noexcept
420 // container::XEnumeration
422 sal_Bool SAL_CALL
SvxUnoTextRangeEnumeration::hasMoreElements()
424 SolarMutexGuard aGuard
;
426 return !maPortions
.empty() && mnNextPortion
< maPortions
.size();
429 uno::Any SAL_CALL
SvxUnoTextRangeEnumeration::nextElement()
431 SolarMutexGuard aGuard
;
433 if( maPortions
.empty() || mnNextPortion
>= maPortions
.size() )
434 throw container::NoSuchElementException();
436 uno::Reference
< text::XTextRange
> xRange
= maPortions
.at(mnNextPortion
);
438 return uno::Any( xRange
);
441 SvxUnoTextCursor::SvxUnoTextCursor( const SvxUnoTextBase
& rText
) noexcept
442 : SvxUnoTextRangeBase(rText
),
443 mxParentText( const_cast<SvxUnoTextBase
*>(&rText
) )
447 SvxUnoTextCursor::SvxUnoTextCursor( const SvxUnoTextCursor
& rCursor
) noexcept
448 : SvxUnoTextRangeBase(rCursor
)
449 , text::XTextCursor()
450 , lang::XTypeProvider()
451 , cppu::OWeakAggObject()
452 , mxParentText(rCursor
.mxParentText
)
456 SvxUnoTextCursor::~SvxUnoTextCursor() noexcept
460 // Comment out automatically - [getIdlClass(es) or queryInterface]
461 // Please use the XTypeProvider!
462 //sal_Bool SvxUnoTextCursor::queryInterface( uno::Uik aUIK, Reference< uno::XInterface > & xRef)
463 uno::Any SAL_CALL
SvxUnoTextCursor::queryAggregation( const uno::Type
& rType
)
465 if( rType
== cppu::UnoType
<text::XTextRange
>::get())
466 return uno::Any(uno::Reference
< text::XTextRange
>(static_cast<SvxUnoTextRangeBase
*>(this)));
467 else QUERYINT( text::XTextCursor
);
468 else QUERYINT( beans::XMultiPropertyStates
);
469 else QUERYINT( beans::XPropertySet
);
470 else QUERYINT( beans::XMultiPropertySet
);
471 else QUERYINT( beans::XPropertyState
);
472 else QUERYINT( text::XTextRangeCompare
);
473 else QUERYINT( lang::XServiceInfo
);
474 else QUERYINT( lang::XTypeProvider
);
475 else QUERYINT( lang::XUnoTunnel
);
477 return OWeakAggObject::queryAggregation( rType
);
480 uno::Any SAL_CALL
SvxUnoTextCursor::queryInterface( const uno::Type
& rType
)
482 return OWeakAggObject::queryInterface(rType
);
485 void SAL_CALL
SvxUnoTextCursor::acquire() noexcept
487 OWeakAggObject::acquire();
490 void SAL_CALL
SvxUnoTextCursor::release() noexcept
492 OWeakAggObject::release();
496 uno::Sequence
< uno::Type
> SAL_CALL
SvxUnoTextCursor::getTypes()
498 static const uno::Sequence
< uno::Type
> TYPES
{
499 cppu::UnoType
<text::XTextRange
>::get(),
500 cppu::UnoType
<text::XTextCursor
>::get(),
501 cppu::UnoType
<beans::XPropertySet
>::get(),
502 cppu::UnoType
<beans::XMultiPropertySet
>::get(),
503 cppu::UnoType
<beans::XMultiPropertyStates
>::get(),
504 cppu::UnoType
<beans::XPropertyState
>::get(),
505 cppu::UnoType
<text::XTextRangeCompare
>::get(),
506 cppu::UnoType
<lang::XServiceInfo
>::get(),
507 cppu::UnoType
<lang::XTypeProvider
>::get(),
508 cppu::UnoType
<lang::XUnoTunnel
>::get() };
512 uno::Sequence
< sal_Int8
> SAL_CALL
SvxUnoTextCursor::getImplementationId()
514 return css::uno::Sequence
<sal_Int8
>();
518 void SAL_CALL
SvxUnoTextCursor::collapseToStart()
520 SolarMutexGuard aGuard
;
524 void SAL_CALL
SvxUnoTextCursor::collapseToEnd()
526 SolarMutexGuard aGuard
;
530 sal_Bool SAL_CALL
SvxUnoTextCursor::isCollapsed()
532 SolarMutexGuard aGuard
;
533 return IsCollapsed();
536 sal_Bool SAL_CALL
SvxUnoTextCursor::goLeft( sal_Int16 nCount
, sal_Bool bExpand
)
538 SolarMutexGuard aGuard
;
539 return GoLeft( nCount
, bExpand
);
542 sal_Bool SAL_CALL
SvxUnoTextCursor::goRight( sal_Int16 nCount
, sal_Bool bExpand
)
544 SolarMutexGuard aGuard
;
545 return GoRight( nCount
, bExpand
);
548 void SAL_CALL
SvxUnoTextCursor::gotoStart( sal_Bool bExpand
)
550 SolarMutexGuard aGuard
;
551 GotoStart( bExpand
);
554 void SAL_CALL
SvxUnoTextCursor::gotoEnd( sal_Bool bExpand
)
556 SolarMutexGuard aGuard
;
560 void SAL_CALL
SvxUnoTextCursor::gotoRange( const uno::Reference
< text::XTextRange
>& xRange
, sal_Bool bExpand
)
565 SvxUnoTextRangeBase
* pRange
= comphelper::getFromUnoTunnel
<SvxUnoTextRangeBase
>( xRange
);
570 ESelection aNewSel
= pRange
->GetSelection();
574 const ESelection
& rOldSel
= GetSelection();
575 aNewSel
.start
= rOldSel
.start
;
578 SetSelection( aNewSel
);
581 // text::XTextRange (rest in SvxTextRange)
582 uno::Reference
< text::XText
> SAL_CALL
SvxUnoTextCursor::getText()
587 uno::Reference
< text::XTextRange
> SAL_CALL
SvxUnoTextCursor::getStart()
589 return SvxUnoTextRangeBase::getStart();
592 uno::Reference
< text::XTextRange
> SAL_CALL
SvxUnoTextCursor::getEnd()
594 return SvxUnoTextRangeBase::getEnd();
597 OUString SAL_CALL
SvxUnoTextCursor::getString()
599 return SvxUnoTextRangeBase::getString();
602 void SAL_CALL
SvxUnoTextCursor::setString( const OUString
& aString
)
604 SvxUnoTextRangeBase::setString(aString
);
606 // lang::XServiceInfo
607 OUString SAL_CALL
SvxUnoTextCursor::getImplementationName()
609 return u
"SvxUnoTextCursor"_ustr
;
612 sal_Bool SAL_CALL
SvxUnoTextCursor::supportsService( const OUString
& ServiceName
)
614 return cppu::supportsService( this, ServiceName
);
617 uno::Sequence
< OUString
> SAL_CALL
SvxUnoTextCursor::getSupportedServiceNames()
619 return comphelper::concatSequences(
620 SvxUnoTextRangeBase::getSupportedServiceNames(),
621 std::initializer_list
<std::u16string_view
>{ u
"com.sun.star.style.ParagraphProperties",
622 u
"com.sun.star.style.ParagraphPropertiesComplex",
623 u
"com.sun.star.style.ParagraphPropertiesAsian",
624 u
"com.sun.star.text.TextCursor" });
628 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */