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
.nEndPara
+ 1, pTextForwarder
->GetParagraphCount() );
56 for( sal_Int32 currentPara
= rSel
.nStartPara
; 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
.nStartPara
)
63 nStartPos
= std::max(nStartPos
, rSel
.nStartPos
);
64 if( currentPara
== rSel
.nEndPara
)
65 nEndPos
= std::min(nEndPos
, rSel
.nEndPos
);
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() )
242 mxParentText
->removeTextContent( this );
245 void SAL_CALL
SvxUnoTextContent::addEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
247 std::unique_lock
aGuard(maDisposeContainerMutex
);
248 maDisposeListeners
.addInterface(aGuard
, xListener
);
251 void SAL_CALL
SvxUnoTextContent::removeEventListener( const uno::Reference
< lang::XEventListener
>& aListener
)
253 std::unique_lock
aGuard(maDisposeContainerMutex
);
254 maDisposeListeners
.removeInterface(aGuard
, aListener
);
257 // XEnumerationAccess
259 uno::Reference
< container::XEnumeration
> SAL_CALL
SvxUnoTextContent::createEnumeration()
261 SolarMutexGuard aGuard
;
263 return new SvxUnoTextRangeEnumeration( mrParentText
, mnParagraph
, maSelection
);
266 // XElementAccess ( container::XEnumerationAccess )
268 uno::Type SAL_CALL
SvxUnoTextContent::getElementType()
270 return cppu::UnoType
<text::XTextRange
>::get();
273 sal_Bool SAL_CALL
SvxUnoTextContent::hasElements()
275 SolarMutexGuard aGuard
;
277 SvxTextForwarder
* pForwarder
= GetEditSource() ? GetEditSource()->GetTextForwarder() : nullptr;
280 std::vector
<sal_Int32
> aPortions
;
281 pForwarder
->GetPortions( mnParagraph
, aPortions
);
282 return !aPortions
.empty();
292 void SAL_CALL
SvxUnoTextContent::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& aValue
)
294 _setPropertyValue( aPropertyName
, aValue
, mnParagraph
);
297 uno::Any SAL_CALL
SvxUnoTextContent::getPropertyValue( const OUString
& PropertyName
)
299 return _getPropertyValue( PropertyName
, mnParagraph
);
303 void SAL_CALL
SvxUnoTextContent::setPropertyValues( const uno::Sequence
< OUString
>& aPropertyNames
, const uno::Sequence
< uno::Any
>& aValues
)
305 _setPropertyValues( aPropertyNames
, aValues
, mnParagraph
);
308 uno::Sequence
< uno::Any
> SAL_CALL
SvxUnoTextContent::getPropertyValues( const uno::Sequence
< OUString
>& aPropertyNames
)
310 return _getPropertyValues( aPropertyNames
, mnParagraph
);
313 /*// XTolerantMultiPropertySet
314 uno::Sequence< beans::SetPropertyTolerantFailed > SAL_CALL SvxUnoTextContent::setPropertyValuesTolerant( const uno::Sequence< OUString >& aPropertyNames, const uno::Sequence< uno::Any >& aValues ) throw (lang::IllegalArgumentException, uno::RuntimeException)
316 return _setPropertyValuesTolerant(aPropertyNames, aValues, mnParagraph);
319 uno::Sequence< beans::GetPropertyTolerantResult > SAL_CALL SvxUnoTextContent::getPropertyValuesTolerant( const uno::Sequence< OUString >& aPropertyNames ) throw (uno::RuntimeException)
321 return _getPropertyValuesTolerant(aPropertyNames, mnParagraph);
324 uno::Sequence< beans::GetDirectPropertyTolerantResult > SAL_CALL SvxUnoTextContent::getDirectPropertyValuesTolerant( const uno::Sequence< OUString >& aPropertyNames )
325 throw (uno::RuntimeException)
327 return _getDirectPropertyValuesTolerant(aPropertyNames, mnParagraph);
330 // beans::XPropertyState
331 beans::PropertyState SAL_CALL
SvxUnoTextContent::getPropertyState( const OUString
& PropertyName
)
333 return _getPropertyState( PropertyName
, mnParagraph
);
336 uno::Sequence
< beans::PropertyState
> SAL_CALL
SvxUnoTextContent::getPropertyStates( const uno::Sequence
< OUString
>& aPropertyName
)
338 return _getPropertyStates( aPropertyName
, mnParagraph
);
341 void SAL_CALL
SvxUnoTextContent::setPropertyToDefault( const OUString
& PropertyName
)
343 _setPropertyToDefault( PropertyName
, mnParagraph
);
346 // lang::XServiceInfo
348 OUString SAL_CALL
SvxUnoTextContent::getImplementationName()
350 return "SvxUnoTextContent";
353 uno::Sequence
< OUString
> SAL_CALL
SvxUnoTextContent::getSupportedServiceNames()
355 return comphelper::concatSequences(
356 SvxUnoTextRangeBase::getSupportedServiceNames(),
357 std::initializer_list
<std::u16string_view
>{ u
"com.sun.star.style.ParagraphProperties",
358 u
"com.sun.star.style.ParagraphPropertiesComplex",
359 u
"com.sun.star.style.ParagraphPropertiesAsian",
360 u
"com.sun.star.text.TextContent",
361 u
"com.sun.star.text.Paragraph" });
367 SvxUnoTextRangeEnumeration::SvxUnoTextRangeEnumeration(const SvxUnoTextBase
& rParentText
, sal_Int32 nParagraph
, const ESelection
& rSel
)
368 : mxParentText( const_cast<SvxUnoTextBase
*>(&rParentText
) ),
371 if (rParentText
.GetEditSource())
372 mpEditSource
= rParentText
.GetEditSource()->Clone();
374 if( !(mpEditSource
&& mpEditSource
->GetTextForwarder() && (nParagraph
== rSel
.nStartPara
&& nParagraph
== rSel
.nEndPara
)) )
377 std::vector
<sal_Int32
> aPortions
;
378 mpEditSource
->GetTextForwarder()->GetPortions( nParagraph
, aPortions
);
379 for( size_t aPortionIndex
= 0; aPortionIndex
< aPortions
.size(); aPortionIndex
++ )
381 sal_uInt16 nStartPos
= 0;
382 if ( aPortionIndex
> 0 )
383 nStartPos
= aPortions
.at( aPortionIndex
- 1 );
384 if( nStartPos
> rSel
.nEndPos
)
386 sal_uInt16 nEndPos
= aPortions
.at( aPortionIndex
);
387 if( nEndPos
< rSel
.nStartPos
)
390 nStartPos
= std::max
<int>(nStartPos
, rSel
.nStartPos
);
391 nEndPos
= std::min
<sal_uInt16
>(nEndPos
, rSel
.nEndPos
);
392 ESelection
aSel( nParagraph
, nStartPos
, nParagraph
, nEndPos
);
394 const SvxUnoTextRangeBaseVec
& rRanges( mpEditSource
->getRanges() );
395 rtl::Reference
<SvxUnoTextRange
> pRange
;
396 for (auto const& elemRange
: rRanges
)
400 SvxUnoTextRange
* pIterRange
= dynamic_cast< SvxUnoTextRange
* >( elemRange
);
401 if( pIterRange
&& pIterRange
->mbPortion
&& (aSel
== pIterRange
->maSelection
) )
404 if( pRange
== nullptr )
406 pRange
= new SvxUnoTextRange( rParentText
, true );
407 pRange
->SetSelection( aSel
);
409 maPortions
.emplace_back(pRange
);
413 SvxUnoTextRangeEnumeration::~SvxUnoTextRangeEnumeration() noexcept
417 // container::XEnumeration
419 sal_Bool SAL_CALL
SvxUnoTextRangeEnumeration::hasMoreElements()
421 SolarMutexGuard aGuard
;
423 return !maPortions
.empty() && mnNextPortion
< maPortions
.size();
426 uno::Any SAL_CALL
SvxUnoTextRangeEnumeration::nextElement()
428 SolarMutexGuard aGuard
;
430 if( maPortions
.empty() || mnNextPortion
>= maPortions
.size() )
431 throw container::NoSuchElementException();
433 uno::Reference
< text::XTextRange
> xRange
= maPortions
.at(mnNextPortion
);
435 return uno::Any( xRange
);
438 SvxUnoTextCursor::SvxUnoTextCursor( const SvxUnoTextBase
& rText
) noexcept
439 : SvxUnoTextRangeBase(rText
),
440 mxParentText( const_cast<SvxUnoTextBase
*>(&rText
) )
444 SvxUnoTextCursor::SvxUnoTextCursor( const SvxUnoTextCursor
& rCursor
) noexcept
445 : SvxUnoTextRangeBase(rCursor
)
446 , text::XTextCursor()
447 , lang::XTypeProvider()
448 , cppu::OWeakAggObject()
449 , mxParentText(rCursor
.mxParentText
)
453 SvxUnoTextCursor::~SvxUnoTextCursor() noexcept
457 // Comment out automatically - [getIdlClass(es) or queryInterface]
458 // Please use the XTypeProvider!
459 //sal_Bool SvxUnoTextCursor::queryInterface( uno::Uik aUIK, Reference< uno::XInterface > & xRef)
460 uno::Any SAL_CALL
SvxUnoTextCursor::queryAggregation( const uno::Type
& rType
)
462 if( rType
== cppu::UnoType
<text::XTextRange
>::get())
463 return uno::Any(uno::Reference
< text::XTextRange
>(static_cast<SvxUnoTextRangeBase
*>(this)));
464 else QUERYINT( text::XTextCursor
);
465 else QUERYINT( beans::XMultiPropertyStates
);
466 else QUERYINT( beans::XPropertySet
);
467 else QUERYINT( beans::XMultiPropertySet
);
468 else QUERYINT( beans::XPropertyState
);
469 else QUERYINT( text::XTextRangeCompare
);
470 else QUERYINT( lang::XServiceInfo
);
471 else QUERYINT( lang::XTypeProvider
);
472 else QUERYINT( lang::XUnoTunnel
);
474 return OWeakAggObject::queryAggregation( rType
);
477 uno::Any SAL_CALL
SvxUnoTextCursor::queryInterface( const uno::Type
& rType
)
479 return OWeakAggObject::queryInterface(rType
);
482 void SAL_CALL
SvxUnoTextCursor::acquire() noexcept
484 OWeakAggObject::acquire();
487 void SAL_CALL
SvxUnoTextCursor::release() noexcept
489 OWeakAggObject::release();
493 uno::Sequence
< uno::Type
> SAL_CALL
SvxUnoTextCursor::getTypes()
495 static const uno::Sequence
< uno::Type
> TYPES
{
496 cppu::UnoType
<text::XTextRange
>::get(),
497 cppu::UnoType
<text::XTextCursor
>::get(),
498 cppu::UnoType
<beans::XPropertySet
>::get(),
499 cppu::UnoType
<beans::XMultiPropertySet
>::get(),
500 cppu::UnoType
<beans::XMultiPropertyStates
>::get(),
501 cppu::UnoType
<beans::XPropertyState
>::get(),
502 cppu::UnoType
<text::XTextRangeCompare
>::get(),
503 cppu::UnoType
<lang::XServiceInfo
>::get(),
504 cppu::UnoType
<lang::XTypeProvider
>::get(),
505 cppu::UnoType
<lang::XUnoTunnel
>::get() };
509 uno::Sequence
< sal_Int8
> SAL_CALL
SvxUnoTextCursor::getImplementationId()
511 return css::uno::Sequence
<sal_Int8
>();
515 void SAL_CALL
SvxUnoTextCursor::collapseToStart()
517 SolarMutexGuard aGuard
;
521 void SAL_CALL
SvxUnoTextCursor::collapseToEnd()
523 SolarMutexGuard aGuard
;
527 sal_Bool SAL_CALL
SvxUnoTextCursor::isCollapsed()
529 SolarMutexGuard aGuard
;
530 return IsCollapsed();
533 sal_Bool SAL_CALL
SvxUnoTextCursor::goLeft( sal_Int16 nCount
, sal_Bool bExpand
)
535 SolarMutexGuard aGuard
;
536 return GoLeft( nCount
, bExpand
);
539 sal_Bool SAL_CALL
SvxUnoTextCursor::goRight( sal_Int16 nCount
, sal_Bool bExpand
)
541 SolarMutexGuard aGuard
;
542 return GoRight( nCount
, bExpand
);
545 void SAL_CALL
SvxUnoTextCursor::gotoStart( sal_Bool bExpand
)
547 SolarMutexGuard aGuard
;
548 GotoStart( bExpand
);
551 void SAL_CALL
SvxUnoTextCursor::gotoEnd( sal_Bool bExpand
)
553 SolarMutexGuard aGuard
;
557 void SAL_CALL
SvxUnoTextCursor::gotoRange( const uno::Reference
< text::XTextRange
>& xRange
, sal_Bool bExpand
)
562 SvxUnoTextRangeBase
* pRange
= comphelper::getFromUnoTunnel
<SvxUnoTextRangeBase
>( xRange
);
567 ESelection aNewSel
= pRange
->GetSelection();
571 const ESelection
& rOldSel
= GetSelection();
572 aNewSel
.nStartPara
= rOldSel
.nStartPara
;
573 aNewSel
.nStartPos
= rOldSel
.nStartPos
;
576 SetSelection( aNewSel
);
579 // text::XTextRange (rest in SvxTextRange)
580 uno::Reference
< text::XText
> SAL_CALL
SvxUnoTextCursor::getText()
585 uno::Reference
< text::XTextRange
> SAL_CALL
SvxUnoTextCursor::getStart()
587 return SvxUnoTextRangeBase::getStart();
590 uno::Reference
< text::XTextRange
> SAL_CALL
SvxUnoTextCursor::getEnd()
592 return SvxUnoTextRangeBase::getEnd();
595 OUString SAL_CALL
SvxUnoTextCursor::getString()
597 return SvxUnoTextRangeBase::getString();
600 void SAL_CALL
SvxUnoTextCursor::setString( const OUString
& aString
)
602 SvxUnoTextRangeBase::setString(aString
);
604 // lang::XServiceInfo
605 OUString SAL_CALL
SvxUnoTextCursor::getImplementationName()
607 return "SvxUnoTextCursor";
610 sal_Bool SAL_CALL
SvxUnoTextCursor::supportsService( const OUString
& ServiceName
)
612 return cppu::supportsService( this, ServiceName
);
615 uno::Sequence
< OUString
> SAL_CALL
SvxUnoTextCursor::getSupportedServiceNames()
617 return comphelper::concatSequences(
618 SvxUnoTextRangeBase::getSupportedServiceNames(),
619 std::initializer_list
<std::u16string_view
>{ u
"com.sun.star.style.ParagraphProperties",
620 u
"com.sun.star.style.ParagraphPropertiesComplex",
621 u
"com.sun.star.style.ParagraphPropertiesAsian",
622 u
"com.sun.star.text.TextCursor" });
626 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */