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 <vcl/svapp.hxx>
21 #include <rtl/instance.hxx>
23 #include <editeng/eeitem.hxx>
24 #include <editeng/flditem.hxx>
25 #include <editeng/unofield.hxx>
26 #include <editeng/unotext.hxx>
27 #include <comphelper/serviceinfohelper.hxx>
28 #include <cppuhelper/supportsservice.hxx>
30 using namespace ::cppu
;
31 using namespace ::com::sun::star
;
33 #define QUERYINT( xint ) \
34 if( rType == cppu::UnoType<xint>::get() ) \
35 return uno::makeAny(uno::Reference< xint >(this))
38 // SvxUnoTextContentEnumeration
41 SvxUnoTextContentEnumeration::SvxUnoTextContentEnumeration( const SvxUnoTextBase
& _rText
, const ESelection
& rSel
) throw()
44 mxParentText
= const_cast<SvxUnoTextBase
*>(&_rText
);
45 if( mrText
.GetEditSource() )
46 mpEditSource
= mrText
.GetEditSource()->Clone();
49 const SvxTextForwarder
* pTextForwarder
= mrText
.GetEditSource()->GetTextForwarder();
50 const sal_Int32 maxParaIndex
= std::min( rSel
.nEndPara
+ 1, pTextForwarder
->GetParagraphCount() );
52 for( sal_Int32 currentPara
= rSel
.nStartPara
; currentPara
< maxParaIndex
; currentPara
++ )
54 const SvxUnoTextRangeBaseVec
& rRanges( mpEditSource
->getRanges() );
55 SvxUnoTextContent
* pContent
= nullptr;
56 sal_Int32 nStartPos
= 0;
57 sal_Int32 nEndPos
= pTextForwarder
->GetTextLen( currentPara
);
58 if( currentPara
== rSel
.nStartPara
)
59 nStartPos
= std::max(nStartPos
, rSel
.nStartPos
);
60 if( currentPara
== rSel
.nEndPara
)
61 nEndPos
= std::min(nEndPos
, rSel
.nEndPos
);
62 ESelection
aCurrentParaSel( currentPara
, nStartPos
, currentPara
, nEndPos
);
63 for (auto const& elemRange
: rRanges
)
67 SvxUnoTextContent
* pIterContent
= dynamic_cast< SvxUnoTextContent
* >( elemRange
);
68 if( pIterContent
&& (pIterContent
->mnParagraph
== currentPara
) )
70 ESelection aIterSel
= pIterContent
->GetSelection();
71 if( aIterSel
== aCurrentParaSel
)
73 pContent
= pIterContent
;
74 maContents
.emplace_back(pContent
);
78 if( pContent
== nullptr )
80 pContent
= new SvxUnoTextContent( mrText
, currentPara
);
81 pContent
->SetSelection( aCurrentParaSel
);
82 maContents
.emplace_back(pContent
);
87 SvxUnoTextContentEnumeration::~SvxUnoTextContentEnumeration() throw()
91 // container::XEnumeration
92 sal_Bool SAL_CALL
SvxUnoTextContentEnumeration::hasMoreElements()
94 SolarMutexGuard aGuard
;
95 if( mpEditSource
&& !maContents
.empty() )
96 return static_cast<unsigned>(mnNextParagraph
) < maContents
.size();
101 uno::Any
SvxUnoTextContentEnumeration::nextElement()
103 SolarMutexGuard aGuard
;
105 if(!hasMoreElements())
106 throw container::NoSuchElementException();
108 uno::Reference
< text::XTextContent
> xRef( maContents
.at(mnNextParagraph
).get() );
110 return uno::makeAny( xRef
);
114 // class SvxUnoTextContent
117 SvxUnoTextContent::SvxUnoTextContent( const SvxUnoTextBase
& rText
, sal_Int32 nPara
) throw()
118 : SvxUnoTextRangeBase(rText
)
120 , mrParentText(rText
)
121 , maDisposeListeners(maDisposeContainerMutex
)
122 , mbDisposing( false )
124 mxParentText
= const_cast<SvxUnoTextBase
*>(&rText
);
127 SvxUnoTextContent::SvxUnoTextContent( const SvxUnoTextContent
& rContent
) throw()
128 : SvxUnoTextRangeBase(rContent
)
129 , text::XTextContent()
130 , container::XEnumerationAccess()
131 , lang::XTypeProvider()
132 , cppu::OWeakAggObject()
133 , mrParentText(rContent
.mrParentText
)
134 , maDisposeListeners(maDisposeContainerMutex
)
135 , mbDisposing( false )
137 mxParentText
= rContent
.mxParentText
;
138 mnParagraph
= rContent
.mnParagraph
;
139 SetSelection( rContent
.GetSelection() );
142 SvxUnoTextContent::~SvxUnoTextContent() throw()
147 uno::Any SAL_CALL
SvxUnoTextContent::queryAggregation( const uno::Type
& rType
)
149 QUERYINT( text::XTextRange
);
150 else QUERYINT( beans::XMultiPropertyStates
);
151 else QUERYINT( beans::XPropertySet
);
152 else QUERYINT( beans::XMultiPropertySet
);
153 else QUERYINT( beans::XPropertyState
);
154 else QUERYINT( text::XTextContent
);
155 else QUERYINT( text::XTextRangeCompare
);
156 else QUERYINT( lang::XComponent
);
157 else QUERYINT( container::XEnumerationAccess
);
158 else QUERYINT( container::XElementAccess
);
159 else QUERYINT( lang::XServiceInfo
);
160 else QUERYINT( lang::XTypeProvider
);
161 else QUERYINT( lang::XUnoTunnel
);
163 return OWeakAggObject::queryAggregation( rType
);
166 uno::Any SAL_CALL
SvxUnoTextContent::queryInterface( const uno::Type
& rType
)
168 return OWeakAggObject::queryInterface(rType
);
171 void SAL_CALL
SvxUnoTextContent::acquire() throw( )
173 OWeakAggObject::acquire();
176 void SAL_CALL
SvxUnoTextContent::release() throw( )
178 OWeakAggObject::release();
185 struct theSvxUnoTextContentTypes
:
186 public rtl::StaticWithInit
<uno::Sequence
<uno::Type
>, theSvxUnoTextContentTypes
>
188 uno::Sequence
<uno::Type
> operator () ()
190 uno::Sequence
< uno::Type
> aTypeSequence
;
192 aTypeSequence
.realloc( 11 ); // !DANGER! keep this updated
193 uno::Type
* pTypes
= aTypeSequence
.getArray();
195 *pTypes
++ = cppu::UnoType
<text::XTextRange
>::get();
196 *pTypes
++ = cppu::UnoType
<beans::XPropertySet
>::get();
197 *pTypes
++ = cppu::UnoType
<beans::XMultiPropertySet
>::get();
198 *pTypes
++ = cppu::UnoType
<beans::XMultiPropertyStates
>::get();
199 *pTypes
++ = cppu::UnoType
<beans::XPropertyState
>::get();
200 *pTypes
++ = cppu::UnoType
<text::XTextRangeCompare
>::get();
201 *pTypes
++ = cppu::UnoType
<text::XTextContent
>::get();
202 *pTypes
++ = cppu::UnoType
<container::XEnumerationAccess
>::get();
203 *pTypes
++ = cppu::UnoType
<lang::XServiceInfo
>::get();
204 *pTypes
++ = cppu::UnoType
<lang::XTypeProvider
>::get();
205 *pTypes
++ = cppu::UnoType
<lang::XUnoTunnel
>::get();
207 return aTypeSequence
;
212 uno::Sequence
< uno::Type
> SAL_CALL
SvxUnoTextContent::getTypes()
214 return theSvxUnoTextContentTypes::get();
217 uno::Sequence
< sal_Int8
> SAL_CALL
SvxUnoTextContent::getImplementationId()
219 return css::uno::Sequence
<sal_Int8
>();
224 uno::Reference
< text::XText
> SAL_CALL
SvxUnoTextContent::getText()
229 // text::XTextContent
230 void SAL_CALL
SvxUnoTextContent::attach( const uno::Reference
< text::XTextRange
>& )
234 uno::Reference
< text::XTextRange
> SAL_CALL
SvxUnoTextContent::getAnchor()
236 return uno::Reference
< text::XTextRange
>::query( mxParentText
);
241 void SAL_CALL
SvxUnoTextContent::dispose()
243 SolarMutexGuard aGuard
;
246 return; // caught a recursion
250 lang::EventObject aEvt
;
251 aEvt
.Source
= *static_cast<OWeakAggObject
*>(this);
252 maDisposeListeners
.disposeAndClear(aEvt
);
254 if( mxParentText
.is() )
255 mxParentText
->removeTextContent( this );
258 void SAL_CALL
SvxUnoTextContent::addEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
260 maDisposeListeners
.addInterface(xListener
);
263 void SAL_CALL
SvxUnoTextContent::removeEventListener( const uno::Reference
< lang::XEventListener
>& aListener
)
265 maDisposeListeners
.removeInterface(aListener
);
268 // XEnumerationAccess
270 uno::Reference
< container::XEnumeration
> SAL_CALL
SvxUnoTextContent::createEnumeration()
272 SolarMutexGuard aGuard
;
274 return new SvxUnoTextRangeEnumeration( mrParentText
, mnParagraph
, maSelection
);
277 // XElementAccess ( container::XEnumerationAccess )
279 uno::Type SAL_CALL
SvxUnoTextContent::getElementType()
281 return cppu::UnoType
<text::XTextRange
>::get();
284 sal_Bool SAL_CALL
SvxUnoTextContent::hasElements()
286 SolarMutexGuard aGuard
;
288 SvxTextForwarder
* pForwarder
= GetEditSource() ? GetEditSource()->GetTextForwarder() : nullptr;
291 std::vector
<sal_Int32
> aPortions
;
292 pForwarder
->GetPortions( mnParagraph
, aPortions
);
293 return !aPortions
.empty();
303 void SAL_CALL
SvxUnoTextContent::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& aValue
)
305 _setPropertyValue( aPropertyName
, aValue
, mnParagraph
);
308 uno::Any SAL_CALL
SvxUnoTextContent::getPropertyValue( const OUString
& PropertyName
)
310 return _getPropertyValue( PropertyName
, mnParagraph
);
314 void SAL_CALL
SvxUnoTextContent::setPropertyValues( const uno::Sequence
< OUString
>& aPropertyNames
, const uno::Sequence
< uno::Any
>& aValues
)
316 _setPropertyValues( aPropertyNames
, aValues
, mnParagraph
);
319 uno::Sequence
< uno::Any
> SAL_CALL
SvxUnoTextContent::getPropertyValues( const uno::Sequence
< OUString
>& aPropertyNames
)
321 return _getPropertyValues( aPropertyNames
, mnParagraph
);
324 /*// XTolerantMultiPropertySet
325 uno::Sequence< beans::SetPropertyTolerantFailed > SAL_CALL SvxUnoTextContent::setPropertyValuesTolerant( const uno::Sequence< OUString >& aPropertyNames, const uno::Sequence< uno::Any >& aValues ) throw (lang::IllegalArgumentException, uno::RuntimeException)
327 return _setPropertyValuesTolerant(aPropertyNames, aValues, mnParagraph);
330 uno::Sequence< beans::GetPropertyTolerantResult > SAL_CALL SvxUnoTextContent::getPropertyValuesTolerant( const uno::Sequence< OUString >& aPropertyNames ) throw (uno::RuntimeException)
332 return _getPropertyValuesTolerant(aPropertyNames, mnParagraph);
335 uno::Sequence< beans::GetDirectPropertyTolerantResult > SAL_CALL SvxUnoTextContent::getDirectPropertyValuesTolerant( const uno::Sequence< OUString >& aPropertyNames )
336 throw (uno::RuntimeException)
338 return _getDirectPropertyValuesTolerant(aPropertyNames, mnParagraph);
341 // beans::XPropertyState
342 beans::PropertyState SAL_CALL
SvxUnoTextContent::getPropertyState( const OUString
& PropertyName
)
344 return _getPropertyState( PropertyName
, mnParagraph
);
347 uno::Sequence
< beans::PropertyState
> SAL_CALL
SvxUnoTextContent::getPropertyStates( const uno::Sequence
< OUString
>& aPropertyName
)
349 return _getPropertyStates( aPropertyName
, mnParagraph
);
352 void SAL_CALL
SvxUnoTextContent::setPropertyToDefault( const OUString
& PropertyName
)
354 _setPropertyToDefault( PropertyName
, mnParagraph
);
357 // lang::XServiceInfo
359 OUString SAL_CALL
SvxUnoTextContent::getImplementationName()
361 return "SvxUnoTextContent";
364 uno::Sequence
< OUString
> SAL_CALL
SvxUnoTextContent::getSupportedServiceNames()
366 uno::Sequence
< OUString
> aSeq( SvxUnoTextRangeBase::getSupportedServiceNames() );
367 comphelper::ServiceInfoHelper::addToSequence( aSeq
, {"com.sun.star.style.ParagraphProperties",
368 "com.sun.star.style.ParagraphPropertiesComplex",
369 "com.sun.star.style.ParagraphPropertiesAsian",
370 "com.sun.star.text.TextContent",
371 "com.sun.star.text.Paragraph"});
376 // class SvxUnoTextRangeEnumeration
379 SvxUnoTextRangeEnumeration::SvxUnoTextRangeEnumeration(const SvxUnoTextBase
& rParentText
, sal_Int32 nPara
, const ESelection
& rSel
)
380 : mxParentText( const_cast<SvxUnoTextBase
*>(&rParentText
) ),
381 mnParagraph( nPara
),
384 if (rParentText
.GetEditSource())
385 mpEditSource
= rParentText
.GetEditSource()->Clone();
387 if( mpEditSource
&& mpEditSource
->GetTextForwarder() && (mnParagraph
== rSel
.nStartPara
&& mnParagraph
== rSel
.nEndPara
) )
389 std::vector
<sal_Int32
> aPortions
;
390 mpEditSource
->GetTextForwarder()->GetPortions( nPara
, aPortions
);
391 for( size_t aPortionIndex
= 0; aPortionIndex
< aPortions
.size(); aPortionIndex
++ )
393 sal_uInt16 nStartPos
= 0;
394 if ( aPortionIndex
> 0 )
395 nStartPos
= aPortions
.at( aPortionIndex
- 1 );
396 if( nStartPos
> rSel
.nEndPos
)
398 sal_uInt16 nEndPos
= aPortions
.at( aPortionIndex
);
399 if( nEndPos
< rSel
.nStartPos
)
402 nStartPos
= std::max
<int>(nStartPos
, rSel
.nStartPos
);
403 nEndPos
= std::min
<sal_uInt16
>(nEndPos
, rSel
.nEndPos
);
404 ESelection
aSel( mnParagraph
, nStartPos
, mnParagraph
, nEndPos
);
406 const SvxUnoTextRangeBaseVec
& rRanges( mpEditSource
->getRanges() );
407 SvxUnoTextRange
* pRange
= nullptr;
408 for (auto const& elemRange
: rRanges
)
412 SvxUnoTextRange
* pIterRange
= dynamic_cast< SvxUnoTextRange
* >( elemRange
);
413 if( pIterRange
&& pIterRange
->mbPortion
&& (aSel
== pIterRange
->maSelection
) )
416 if( pRange
== nullptr )
418 pRange
= new SvxUnoTextRange( rParentText
, true );
419 pRange
->SetSelection( aSel
);
421 maPortions
.emplace_back(pRange
);
426 SvxUnoTextRangeEnumeration::~SvxUnoTextRangeEnumeration() throw()
430 // container::XEnumeration
432 sal_Bool SAL_CALL
SvxUnoTextRangeEnumeration::hasMoreElements()
434 SolarMutexGuard aGuard
;
436 return !maPortions
.empty() && mnNextPortion
< maPortions
.size();
439 uno::Any SAL_CALL
SvxUnoTextRangeEnumeration::nextElement()
441 SolarMutexGuard aGuard
;
443 if( maPortions
.empty() || mnNextPortion
>= maPortions
.size() )
444 throw container::NoSuchElementException();
446 uno::Reference
< text::XTextRange
> xRange
= maPortions
.at(mnNextPortion
).get();
448 return uno::makeAny( xRange
);
451 SvxUnoTextCursor::SvxUnoTextCursor( const SvxUnoTextBase
& rText
) throw()
452 : SvxUnoTextRangeBase(rText
),
453 mxParentText( const_cast<SvxUnoTextBase
*>(&rText
) )
457 SvxUnoTextCursor::SvxUnoTextCursor( const SvxUnoTextCursor
& rCursor
) throw()
458 : SvxUnoTextRangeBase(rCursor
)
459 , text::XTextCursor()
460 , lang::XTypeProvider()
461 , cppu::OWeakAggObject()
462 , mxParentText(rCursor
.mxParentText
)
466 SvxUnoTextCursor::~SvxUnoTextCursor() throw()
470 // Comment out automatically - [getIdlClass(es) or queryInterface]
471 // Please use the XTypeProvider!
472 //sal_Bool SvxUnoTextCursor::queryInterface( uno::Uik aUIK, Reference< uno::XInterface > & xRef)
473 uno::Any SAL_CALL
SvxUnoTextCursor::queryAggregation( const uno::Type
& rType
)
475 if( rType
== cppu::UnoType
<text::XTextRange
>::get())
476 return uno::makeAny(uno::Reference
< text::XTextRange
>(static_cast<SvxUnoTextRangeBase
*>(this)));
477 else QUERYINT( text::XTextCursor
);
478 else QUERYINT( beans::XMultiPropertyStates
);
479 else QUERYINT( beans::XPropertySet
);
480 else QUERYINT( beans::XMultiPropertySet
);
481 else QUERYINT( beans::XPropertyState
);
482 else QUERYINT( text::XTextRangeCompare
);
483 else QUERYINT( lang::XServiceInfo
);
484 else QUERYINT( lang::XTypeProvider
);
485 else QUERYINT( lang::XUnoTunnel
);
487 return OWeakAggObject::queryAggregation( rType
);
490 uno::Any SAL_CALL
SvxUnoTextCursor::queryInterface( const uno::Type
& rType
)
492 return OWeakAggObject::queryInterface(rType
);
495 void SAL_CALL
SvxUnoTextCursor::acquire() throw ( )
497 OWeakAggObject::acquire();
500 void SAL_CALL
SvxUnoTextCursor::release() throw ( )
502 OWeakAggObject::release();
507 struct theSvxUnoTextCursorTypes
:
508 public rtl::StaticWithInit
<uno::Sequence
<uno::Type
>, theSvxUnoTextCursorTypes
>
510 uno::Sequence
<uno::Type
> operator () ()
512 uno::Sequence
< uno::Type
> aTypeSequence
;
514 aTypeSequence
.realloc( 10 ); // !DANGER! keep this updated
515 uno::Type
* pTypes
= aTypeSequence
.getArray();
517 *pTypes
++ = cppu::UnoType
<text::XTextRange
>::get();
518 *pTypes
++ = cppu::UnoType
<text::XTextCursor
>::get();
519 *pTypes
++ = cppu::UnoType
<beans::XPropertySet
>::get();
520 *pTypes
++ = cppu::UnoType
<beans::XMultiPropertySet
>::get();
521 *pTypes
++ = cppu::UnoType
<beans::XMultiPropertyStates
>::get();
522 *pTypes
++ = cppu::UnoType
<beans::XPropertyState
>::get();
523 *pTypes
++ = cppu::UnoType
<text::XTextRangeCompare
>::get();
524 *pTypes
++ = cppu::UnoType
<lang::XServiceInfo
>::get();
525 *pTypes
++ = cppu::UnoType
<lang::XTypeProvider
>::get();
526 *pTypes
++ = cppu::UnoType
<lang::XUnoTunnel
>::get();
528 return aTypeSequence
;
534 uno::Sequence
< uno::Type
> SAL_CALL
SvxUnoTextCursor::getTypes()
536 return theSvxUnoTextCursorTypes::get();
539 uno::Sequence
< sal_Int8
> SAL_CALL
SvxUnoTextCursor::getImplementationId()
541 return css::uno::Sequence
<sal_Int8
>();
545 void SAL_CALL
SvxUnoTextCursor::collapseToStart()
547 SolarMutexGuard aGuard
;
551 void SAL_CALL
SvxUnoTextCursor::collapseToEnd()
553 SolarMutexGuard aGuard
;
557 sal_Bool SAL_CALL
SvxUnoTextCursor::isCollapsed()
559 SolarMutexGuard aGuard
;
560 return IsCollapsed();
563 sal_Bool SAL_CALL
SvxUnoTextCursor::goLeft( sal_Int16 nCount
, sal_Bool bExpand
)
565 SolarMutexGuard aGuard
;
566 return GoLeft( nCount
, bExpand
);
569 sal_Bool SAL_CALL
SvxUnoTextCursor::goRight( sal_Int16 nCount
, sal_Bool bExpand
)
571 SolarMutexGuard aGuard
;
572 return GoRight( nCount
, bExpand
);
575 void SAL_CALL
SvxUnoTextCursor::gotoStart( sal_Bool bExpand
)
577 SolarMutexGuard aGuard
;
578 GotoStart( bExpand
);
581 void SAL_CALL
SvxUnoTextCursor::gotoEnd( sal_Bool bExpand
)
583 SolarMutexGuard aGuard
;
587 void SAL_CALL
SvxUnoTextCursor::gotoRange( const uno::Reference
< text::XTextRange
>& xRange
, sal_Bool bExpand
)
592 SvxUnoTextRangeBase
* pRange
= comphelper::getUnoTunnelImplementation
<SvxUnoTextRangeBase
>( xRange
);
596 ESelection aNewSel
= pRange
->GetSelection();
600 const ESelection
& rOldSel
= GetSelection();
601 aNewSel
.nStartPara
= rOldSel
.nStartPara
;
602 aNewSel
.nStartPos
= rOldSel
.nStartPos
;
605 SetSelection( aNewSel
);
609 // text::XTextRange (rest in SvxTextRange)
610 uno::Reference
< text::XText
> SAL_CALL
SvxUnoTextCursor::getText()
615 uno::Reference
< text::XTextRange
> SAL_CALL
SvxUnoTextCursor::getStart()
617 return SvxUnoTextRangeBase::getStart();
620 uno::Reference
< text::XTextRange
> SAL_CALL
SvxUnoTextCursor::getEnd()
622 return SvxUnoTextRangeBase::getEnd();
625 OUString SAL_CALL
SvxUnoTextCursor::getString()
627 return SvxUnoTextRangeBase::getString();
630 void SAL_CALL
SvxUnoTextCursor::setString( const OUString
& aString
)
632 SvxUnoTextRangeBase::setString(aString
);
634 // lang::XServiceInfo
635 OUString SAL_CALL
SvxUnoTextCursor::getImplementationName()
637 return "SvxUnoTextCursor";
640 sal_Bool SAL_CALL
SvxUnoTextCursor::supportsService( const OUString
& ServiceName
)
642 return cppu::supportsService( this, ServiceName
);
645 uno::Sequence
< OUString
> SAL_CALL
SvxUnoTextCursor::getSupportedServiceNames()
647 uno::Sequence
< OUString
> aSeq( SvxUnoTextRangeBase::getSupportedServiceNames() );
648 comphelper::ServiceInfoHelper::addToSequence( aSeq
, {"com.sun.star.style.ParagraphProperties",
649 "com.sun.star.style.ParagraphPropertiesComplex",
650 "com.sun.star.style.ParagraphPropertiesAsian",
651 "com.sun.star.text.TextCursor"});
656 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */