Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / editeng / source / uno / unotext2.cxx
blob79706cad2d2e843abdaa3d2aecea0ab3fa2984cb
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 <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();
48 mnNextParagraph = 0;
50 if (!mpEditSource)
51 return;
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)
69 if (pContent)
70 break;
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();
101 else
102 return false;
105 uno::Any SvxUnoTextContentEnumeration::nextElement()
107 SolarMutexGuard aGuard;
109 if(!hasMoreElements())
110 throw container::NoSuchElementException();
112 uno::Reference< text::XTextContent > xRef( maContents.at(mnNextParagraph) );
113 mnNextParagraph++;
114 return uno::Any( xRef );
120 SvxUnoTextContent::SvxUnoTextContent( const SvxUnoTextBase& rText, sal_Int32 nPara ) noexcept
121 : SvxUnoTextRangeBase(rText)
122 , mnParagraph(nPara)
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
147 // uno::XInterface
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 );
163 else
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();
182 // XTypeProvider
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() };
198 return TYPES;
201 uno::Sequence< sal_Int8 > SAL_CALL SvxUnoTextContent::getImplementationId()
203 return css::uno::Sequence<sal_Int8>();
206 // text::XTextRange
208 uno::Reference< text::XText > SAL_CALL SvxUnoTextContent::getText()
210 return mxParentText;
213 // text::XTextContent
214 void SAL_CALL SvxUnoTextContent::attach( const uno::Reference< text::XTextRange >& )
218 uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextContent::getAnchor()
220 return mxParentText;
223 // XComponent
225 void SAL_CALL SvxUnoTextContent::dispose()
227 SolarMutexGuard aGuard;
229 if( mbDisposing )
230 return; // caught a recursion
232 mbDisposing = true;
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;
278 if( pForwarder )
280 std::vector<sal_Int32> aPortions;
281 pForwarder->GetPortions( mnParagraph, aPortions );
282 return !aPortions.empty();
284 else
286 return false;
290 // XPropertySet
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 );
302 // XMultiPropertySet
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) ),
369 mnNextPortion( 0 )
371 if (rParentText.GetEditSource())
372 mpEditSource = rParentText.GetEditSource()->Clone();
374 if( !(mpEditSource && mpEditSource->GetTextForwarder() && (nParagraph == rSel.nStartPara && nParagraph == rSel.nEndPara)) )
375 return;
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 )
385 continue;
386 sal_uInt16 nEndPos = aPortions.at( aPortionIndex );
387 if( nEndPos < rSel.nStartPos )
388 continue;
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)
398 if (pRange)
399 break;
400 SvxUnoTextRange* pIterRange = dynamic_cast< SvxUnoTextRange* >( elemRange );
401 if( pIterRange && pIterRange->mbPortion && (aSel == pIterRange->maSelection) )
402 pRange = pIterRange;
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);
434 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 );
473 else
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();
492 // XTypeProvider
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() };
506 return TYPES;
509 uno::Sequence< sal_Int8 > SAL_CALL SvxUnoTextCursor::getImplementationId()
511 return css::uno::Sequence<sal_Int8>();
514 // text::XTextCursor
515 void SAL_CALL SvxUnoTextCursor::collapseToStart()
517 SolarMutexGuard aGuard;
518 CollapseToStart();
521 void SAL_CALL SvxUnoTextCursor::collapseToEnd()
523 SolarMutexGuard aGuard;
524 CollapseToEnd();
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;
554 GotoEnd( bExpand );
557 void SAL_CALL SvxUnoTextCursor::gotoRange( const uno::Reference< text::XTextRange >& xRange, sal_Bool bExpand )
559 if( !xRange.is() )
560 return;
562 SvxUnoTextRangeBase* pRange = comphelper::getFromUnoTunnel<SvxUnoTextRangeBase>( xRange );
564 if( !pRange )
565 return;
567 ESelection aNewSel = pRange->GetSelection();
569 if( bExpand )
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()
582 return mxParentText;
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: */