LibreOffice Module sw (master) 1
unoportenum.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21#include <sal/log.hxx>
22
23#include <utility>
24
25#include <unoport.hxx>
26#include <IMark.hxx>
27#include <crossrefbookmark.hxx>
28#include <annotationmark.hxx>
29#include <doc.hxx>
31#include <txatbase.hxx>
32#include <txtatr.hxx>
33#include <ndhints.hxx>
34#include <ndtxt.hxx>
35#include <unocrsr.hxx>
36#include <docary.hxx>
37#include <textboxhelper.hxx>
38#include <tox.hxx>
39#include <unoparaframeenum.hxx>
40#include <unocrsrhelper.hxx>
41#include <unorefmark.hxx>
42#include <unobookmark.hxx>
43#include <unofield.hxx>
44#include <unometa.hxx>
45#include <unolinebreak.hxx>
46#include <unocontentcontrol.hxx>
47#include <fmtfld.hxx>
48#include <fldbas.hxx>
49#include <fmtmeta.hxx>
50#include <fmtanchr.hxx>
51#include <fmtrfmrk.hxx>
52#include <frmfmt.hxx>
53#include <fmtflcnt.hxx>
54#include <unoidx.hxx>
55#include <unocoll.hxx>
56#include <redline.hxx>
57#include <txtannotationfld.hxx>
58#include <vcl/svapp.hxx>
59#include <comphelper/string.hxx>
62#include <com/sun/star/container/XEnumeration.hpp>
63#include <algorithm>
64#include <memory>
65#include <set>
66#include <stack>
67
68using namespace ::com::sun::star;
69using namespace ::com::sun::star::uno;
70using namespace ::com::sun::star::text;
71using namespace ::std;
72
73typedef std::pair< TextRangeList_t * const, SwTextAttr const * const > PortionList_t;
74typedef std::stack< PortionList_t > PortionStack_t;
75
76static void lcl_CreatePortions(
77 TextRangeList_t & i_rPortions,
78 uno::Reference< text::XText > const& i_xParentText,
79 SwUnoCursor* pUnoCursor,
80 FrameClientSortList_t & i_rFrames,
81 const sal_Int32 i_nStartPos, const sal_Int32 i_nEndPos, bool bOnlyTextFields );
82
83namespace
84{
85 enum class BkmType {
86 Start, End, StartEnd
87 };
88
89 struct SwXBookmarkPortion_Impl
90 {
91 Reference<XTextContent> xBookmark;
92 BkmType nBkmType;
93 const SwPosition aPosition;
94
95 SwXBookmarkPortion_Impl(uno::Reference<text::XTextContent> xMark,
96 const BkmType nType, SwPosition _aPosition)
97 : xBookmark (std::move( xMark ))
98 , nBkmType ( nType )
99 , aPosition (std::move( _aPosition ))
100 {
101 }
102 sal_Int32 getIndex () const
103 {
104 return aPosition.GetContentIndex();
105 }
106 };
107 typedef std::shared_ptr < SwXBookmarkPortion_Impl > SwXBookmarkPortion_ImplSharedPtr;
108 struct BookmarkCompareStruct
109 {
110 bool operator () ( const SwXBookmarkPortion_ImplSharedPtr &r1,
111 const SwXBookmarkPortion_ImplSharedPtr &r2 ) const
112 {
113 // #i16896# for bookmark portions at the same position, the start should
114 // always precede the end. Hence compare positions, and use bookmark type
115 // as tie-breaker for same position.
116 // return ( r1->nIndex == r2->nIndex )
117 // ? ( r1->nBkmType < r2->nBkmType )
118 // : ( r1->nIndex < r2->nIndex );
119
120 // Note that the above code does not correctly handle
121 // the case when one bookmark ends, and another begins in the same
122 // position. When this occurs, the above code will return the
123 // start of the 2nd bookmark BEFORE the end of the first bookmark
124 // See bug #i58438# for more details. The below code is correct and
125 // fixes both #i58438 and #i16896#
126 return r1->aPosition < r2->aPosition;
127 }
128 };
129 typedef std::multiset < SwXBookmarkPortion_ImplSharedPtr, BookmarkCompareStruct > SwXBookmarkPortion_ImplList;
130
132 void lcl_FillBookmark(sw::mark::IMark* const pBkmk, const SwNode& rOwnNode, SwDoc& rDoc, SwXBookmarkPortion_ImplList& rBkmArr)
133 {
134 bool const hasOther = pBkmk->IsExpanded();
135
136 const SwPosition& rStartPos = pBkmk->GetMarkStart();
137 if(rStartPos.GetNode() == rOwnNode)
138 {
139 // #i109272#: cross reference marks: need special handling!
140 ::sw::mark::CrossRefBookmark *const pCrossRefMark(dynamic_cast< ::sw::mark::CrossRefBookmark*>(pBkmk));
141 BkmType const nType = (hasOther || pCrossRefMark)
142 ? BkmType::Start : BkmType::StartEnd;
143 rBkmArr.insert(std::make_shared<SwXBookmarkPortion_Impl>(
144 SwXBookmark::CreateXBookmark(rDoc, pBkmk),
145 nType, rStartPos));
146 }
147
148 const SwPosition& rEndPos = pBkmk->GetMarkEnd();
149 if(rEndPos.GetNode() != rOwnNode)
150 return;
151
152 std::optional<SwPosition> oCrossRefEndPos;
153 const SwPosition* pEndPos = nullptr;
154 ::sw::mark::CrossRefBookmark *const pCrossRefMark(dynamic_cast< ::sw::mark::CrossRefBookmark*>(pBkmk));
155 if(hasOther)
156 {
157 pEndPos = &rEndPos;
158 }
159 else if (pCrossRefMark)
160 {
161 // Crossrefbookmarks only remember the start position but have to span the whole paragraph
162 SwTextNode& rEndNd = *rEndPos.GetNode().GetTextNode();
163 oCrossRefEndPos.emplace(rEndNd, rEndNd.Len());
164 pEndPos = &*oCrossRefEndPos;
165 }
166 if(pEndPos)
167 {
168 rBkmArr.insert(std::make_shared<SwXBookmarkPortion_Impl>(
169 SwXBookmark::CreateXBookmark(rDoc, pBkmk),
170 BkmType::End, *pEndPos));
171 }
172 }
173
174 void lcl_FillBookmarkArray(SwDoc& rDoc, SwUnoCursor& rUnoCursor, SwXBookmarkPortion_ImplList& rBkmArr)
175 {
176 IDocumentMarkAccess* const pMarkAccess = rDoc.getIDocumentMarkAccess();
177 if(!pMarkAccess->getBookmarksCount())
178 return;
179
180 SwTextNode* pTextNode = rUnoCursor.GetPoint()->GetNode().GetTextNode();
181 assert(pTextNode);
182 // A text node already knows its marks via its SwIndexes.
184 for (const SwContentIndex* pIndex = pTextNode->GetFirstIndex(); pIndex; pIndex = pIndex->GetNext())
185 {
186 // Need a non-cost mark here, as we'll create a UNO wrapper around it.
187 sw::mark::IMark* pBkmk = const_cast<sw::mark::IMark*>(pIndex->GetMark());
188 if (!pBkmk)
189 continue;
191 // These are the types stored in the container otherwise accessible via getBookmarks*()
194 continue;
195 // Only handle bookmarks once, if they start and end at this node as well.
196 if (!aSeenMarks.insert(pBkmk).second)
197 continue;
198 lcl_FillBookmark(pBkmk, *pTextNode, rDoc, rBkmArr);
199 }
200 }
201
202 struct SwAnnotationStartPortion_Impl
203 {
204
205 uno::Reference< text::XTextField > mxAnnotationField;
207
208 SwAnnotationStartPortion_Impl(
209 uno::Reference< text::XTextField > xAnnotationField,
210 SwPosition aPosition)
211 : mxAnnotationField (std::move( xAnnotationField ))
212 , maPosition (std::move( aPosition ))
213 {
214 }
215
216 sal_Int32 getIndex () const
217 {
218 return maPosition.GetContentIndex();
219 }
220 };
221 typedef std::shared_ptr < SwAnnotationStartPortion_Impl > SwAnnotationStartPortion_ImplSharedPtr;
222 struct AnnotationStartCompareStruct
223 {
224 bool operator () ( const SwAnnotationStartPortion_ImplSharedPtr &r1,
225 const SwAnnotationStartPortion_ImplSharedPtr &r2 )
226 const
227 {
228 return r1->maPosition < r2->maPosition;
229 }
230 };
231 typedef std::multiset < SwAnnotationStartPortion_ImplSharedPtr, AnnotationStartCompareStruct > SwAnnotationStartPortion_ImplList;
232
233 void lcl_FillAnnotationStartArray(
234 SwDoc& rDoc,
235 SwUnoCursor& rUnoCursor,
236 SwAnnotationStartPortion_ImplList& rAnnotationStartArr )
237 {
238 IDocumentMarkAccess* const pMarkAccess = rDoc.getIDocumentMarkAccess();
239 if ( pMarkAccess->getAnnotationMarksCount() == 0 )
240 {
241 return;
242 }
243
244 // no need to consider annotation marks starting after aEndOfPara
245 SwContentNode& rPtNd = *rUnoCursor.GetPoint()->GetNode().GetContentNode();
246 SwPosition aEndOfPara( rPtNd, rPtNd.Len() );
247 const IDocumentMarkAccess::const_iterator_t pCandidatesEnd =
248 pMarkAccess->findFirstAnnotationStartsAfter(aEndOfPara);
249
250 // search for all annotation marks that have its start position in this paragraph
251 const SwNode& rOwnNode = rUnoCursor.GetPoint()->GetNode();
253 ppMark != pCandidatesEnd;
254 ++ppMark )
255 {
256 ::sw::mark::AnnotationMark* const pAnnotationMark =
257 dynamic_cast< ::sw::mark::AnnotationMark* >(*ppMark);
258
259 if (!pAnnotationMark)
260 continue;
261
262 const SwPosition& rStartPos = pAnnotationMark->GetMarkStart();
263 if (rStartPos.GetNode() != rOwnNode)
264 continue;
265
266 const SwFormatField* pAnnotationFormatField = pAnnotationMark->GetAnnotationFormatField();
267 if (!pAnnotationFormatField)
268 {
269 SAL_WARN("sw.core", "missing annotation format field");
270 continue;
271 }
272
273 rAnnotationStartArr.insert(
274 std::make_shared<SwAnnotationStartPortion_Impl>(
276 pAnnotationFormatField),
277 rStartPos));
278 }
279 }
280}
281
282const uno::Sequence< sal_Int8 > & SwXTextPortionEnumeration::getUnoTunnelId()
283{
284 static const comphelper::UnoIdInit theSwXTextPortionEnumerationUnoTunnelId;
285 return theSwXTextPortionEnumerationUnoTunnelId.getSeq();
286}
287
289 const uno::Sequence< sal_Int8 >& rId )
290{
291 return comphelper::getSomethingImpl(rId, this);
292}
293
295{
296 return "SwXTextPortionEnumeration";
297}
298
301{
302 return cppu::supportsService(this, rServiceName);
303}
304
306{
307 return { "com.sun.star.text.TextPortionEnumeration" };
308}
309
311 SwPaM& rParaCursor,
312 uno::Reference< XText > const & xParentText,
313 const sal_Int32 nStart,
314 const sal_Int32 nEnd,
315 bool bOnlyTextFields)
316{
317 m_pUnoCursor = rParaCursor.GetDoc().CreateUnoCursor(*rParaCursor.GetPoint());
318
319 OSL_ENSURE(nEnd == -1 || (nStart <= nEnd &&
320 nEnd <= m_pUnoCursor->Start()->GetNode().GetTextNode()->GetText().getLength()),
321 "start or end value invalid!");
322
323 // find all frames, graphics and OLEs that are bound AT character in para
326 lcl_CreatePortions(m_Portions, xParentText, &*m_pUnoCursor, frames, nStart, nEnd, bOnlyTextFields);
327}
328
330 SwPaM& rParaCursor,
331 TextRangeList_t && rPortions )
332 : m_Portions( std::move(rPortions) )
333{
334 m_pUnoCursor = rParaCursor.GetDoc().CreateUnoCursor(*rParaCursor.GetPoint());
335}
336
338{
339 SolarMutexGuard aGuard;
340 if( m_pUnoCursor )
341 {
343 m_pUnoCursor.reset(nullptr);
344 }
345}
346
348{
349 SolarMutexGuard aGuard;
350
351 return !m_Portions.empty();
352}
353
355{
356 SolarMutexGuard aGuard;
357
358 if (m_Portions.empty())
359 throw container::NoSuchElementException();
360
361 Any any;
362 any <<= m_Portions.front();
363 m_Portions.pop_front();
364 return any;
365}
366
367static void
368lcl_FillFieldMarkArray(std::deque<sal_Int32> & rFieldMarks, SwUnoCursor const & rUnoCursor,
369 const sal_Int32 i_nStartPos)
370{
371 const SwTextNode * const pTextNode =
372 rUnoCursor.GetPoint()->GetNode().GetTextNode();
373 if (!pTextNode) return;
374
375 const sal_Unicode fld[] = {
377 sal_Int32 pos = std::max(static_cast<sal_Int32>(0), i_nStartPos);
378 while ((pos = ::comphelper::string::indexOfAny(pTextNode->GetText(), fld, pos)) != -1)
379 {
380 rFieldMarks.push_back(pos);
381 ++pos;
382 }
383}
384
385static uno::Reference<text::XTextRange>
387 uno::Reference< text::XText > const & i_xParentText,
388 SwUnoCursor * const pUnoCursor,
389 const SwTextNode * const pTextNode )
390{
391 uno::Reference<text::XTextRange> xRef;
392 SwDoc& rDoc = pUnoCursor->GetDoc();
393 // maybe it's a good idea to add a special hint to the hints array and rely on the hint segmentation...
394 const sal_Int32 start = pUnoCursor->Start()->GetContentIndex();
395 OSL_ENSURE(pUnoCursor->End()->GetContentIndex() == start,
396 "hmm --- why is this different");
397
398 pUnoCursor->Right(1);
399 if ( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
400 {
401 OSL_FAIL("cannot move cursor?");
402 return nullptr;
403 }
404
405 const sal_Unicode Char = pTextNode->GetText()[start];
407 {
408 ::sw::mark::IFieldmark* pFieldmark = nullptr;
409 pFieldmark = rDoc.getIDocumentMarkAccess()->
410 getFieldmarkAt(*pUnoCursor->GetMark());
412 pUnoCursor, i_xParentText, PORTION_FIELD_START);
413 xRef = pPortion;
414 if (pFieldmark)
415 {
416 pPortion->SetBookmark(
417 SwXFieldmark::CreateXFieldmark(rDoc, pFieldmark));
418 }
419 }
420 else if (CH_TXT_ATR_FIELDSEP == Char)
421 {
422 // TODO how to get the field?
423 xRef = new SwXTextPortion(
424 pUnoCursor, i_xParentText, PORTION_FIELD_SEP);
425 }
426 else if (CH_TXT_ATR_FIELDEND == Char)
427 {
428 ::sw::mark::IFieldmark* pFieldmark = nullptr;
429 pFieldmark = rDoc.getIDocumentMarkAccess()->
430 getFieldmarkAt(*pUnoCursor->GetMark());
432 pUnoCursor, i_xParentText, PORTION_FIELD_END);
433 xRef = pPortion;
434 if (pFieldmark)
435 {
436 pPortion->SetBookmark(
437 SwXFieldmark::CreateXFieldmark(rDoc, pFieldmark));
438 }
439 }
440 else if (CH_TXT_ATR_FORMELEMENT == Char)
441 {
442 ::sw::mark::IFieldmark* pFieldmark =
443 rDoc.getIDocumentMarkAccess()->getFieldmarkAt(*pUnoCursor->GetMark());
445 pUnoCursor, i_xParentText, PORTION_FIELD_START_END);
446 xRef = pPortion;
447 if (pFieldmark)
448 {
449 pPortion->SetBookmark(
450 SwXFieldmark::CreateXFieldmark(rDoc, pFieldmark));
451 }
452 }
453 else
454 {
455 OSL_FAIL("no fieldmark found?");
456 }
457 return xRef;
458}
459
460static Reference<XTextRange>
462 Reference<XText> const& xParent,
463 const SwUnoCursor * const pUnoCursor,
464 const SwTextAttr & rAttr, const bool bEnd)
465{
466 SwDoc& rDoc = pUnoCursor->GetDoc();
467 SwFormatRefMark& rRefMark = const_cast<SwFormatRefMark&>(
468 static_cast<const SwFormatRefMark&>(rAttr.GetAttr()));
469 Reference<XTextContent> xContent;
470 if (!xContent.is())
471 {
472 xContent = SwXReferenceMark::CreateXReferenceMark(rDoc, &rRefMark);
473 }
474
476 if (!bEnd)
477 {
478 pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_REFMARK_START);
479 pPortion->SetRefMark(xContent);
480 pPortion->SetCollapsed(rAttr.End() == nullptr);
481 }
482 else
483 {
484 pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_REFMARK_END);
485 pPortion->SetRefMark(xContent);
486 }
487 return pPortion;
488}
489
490static void
492 TextRangeList_t & rPortions,
493 Reference<XText> const& xParent,
494 const SwUnoCursor * const pUnoCursor,
495 const SwTextAttr & rAttr, const bool bEnd)
496{
497 rtl::Reference<SwXTextPortion> pPortion = new SwXTextPortion(pUnoCursor,
498 static_txtattr_cast<const SwTextRuby&>(rAttr), xParent, bEnd);
499 rPortions.emplace_back(pPortion);
500 pPortion->SetCollapsed(rAttr.End() == nullptr);
501}
502
503static Reference<XTextRange>
505 Reference<XText> const& xParent,
506 const SwUnoCursor * const pUnoCursor,
507 SwTextAttr & rAttr, const bool bEnd)
508{
509 SwDoc& rDoc = pUnoCursor->GetDoc();
510 SwTOXMark & rTOXMark = static_cast<SwTOXMark&>(rAttr.GetAttr());
511
512 const Reference<XTextContent> xContent =
514
516 if (!bEnd)
517 {
518 pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_TOXMARK_START);
519 pPortion->SetTOXMark(xContent);
520 pPortion->SetCollapsed(rAttr.GetEnd() == nullptr);
521 }
522 else
523 {
524 pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_TOXMARK_END);
525 pPortion->SetTOXMark(xContent);
526 }
527 return pPortion;
528}
529
530static uno::Reference<text::XTextRange>
532 uno::Reference<text::XText> const& xParent,
533 const SwUnoCursor * const pUnoCursor,
534 SwTextAttr & rAttr, std::unique_ptr<TextRangeList_t const> && pPortions)
535{
536 const uno::Reference<rdf::XMetadatable> xMeta( SwXMeta::CreateXMeta(
537 *static_cast<SwFormatMeta &>(rAttr.GetAttr()).GetMeta(),
538 xParent, std::move(pPortions)));
540 if (RES_TXTATR_META == rAttr.Which())
541 {
542 const uno::Reference<text::XTextContent> xContent(xMeta,
543 uno::UNO_QUERY);
544 pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_META);
545 pPortion->SetMeta(xContent);
546 }
547 else
548 {
549 const uno::Reference<text::XTextField> xField(xMeta, uno::UNO_QUERY);
550 pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_FIELD);
551 pPortion->SetTextField(xField);
552 }
553 return pPortion;
554}
555
557static uno::Reference<text::XTextRange>
558lcl_CreateContentControlPortion(const uno::Reference<text::XText>& xParent,
559 const SwUnoCursor* pUnoCursor, SwTextAttr& rAttr,
560 std::unique_ptr<const TextRangeList_t>&& pPortions)
561{
562 uno::Reference<text::XTextContent> xContentControl = SwXContentControl::CreateXContentControl(
563 *static_cast<SwFormatContentControl&>(rAttr.GetAttr()).GetContentControl(), xParent,
564 std::move(pPortions));
566 pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_CONTENT_CONTROL);
567 pPortion->SetContentControl(xContentControl);
568 return pPortion;
569}
570
586 TextRangeList_t & rPortions,
587 Reference<XText> const& xParent,
588 const SwUnoCursor * const pUnoCursor,
589 SwXBookmarkPortion_ImplList& rBkmArr,
590 const sal_Int32 nIndex,
591 const o3tl::sorted_vector<sal_Int32>& rFramePositions,
592 bool bOnlyFrameStarts)
593{
594 for ( SwXBookmarkPortion_ImplList::iterator aIter = rBkmArr.begin(), aEnd = rBkmArr.end(); aIter != aEnd; )
595 {
596 const SwXBookmarkPortion_ImplSharedPtr& pPtr = *aIter;
597 if ( nIndex > pPtr->getIndex() )
598 {
599 if (bOnlyFrameStarts)
600 ++aIter;
601 else
602 aIter = rBkmArr.erase(aIter);
603 continue;
604 }
605 if ( nIndex < pPtr->getIndex() )
606 break;
607
608 if ((BkmType::Start == pPtr->nBkmType && bOnlyFrameStarts) ||
609 (BkmType::StartEnd == pPtr->nBkmType))
610 {
611 bool bFrameStart = rFramePositions.find(nIndex) != rFramePositions.end();
612 bool bEnd = pPtr->nBkmType == BkmType::StartEnd && bFrameStart && !bOnlyFrameStarts;
613 if (pPtr->nBkmType == BkmType::Start || bFrameStart || !bOnlyFrameStarts)
614 {
615 // At this we create a text portion, due to one of these
616 // reasons:
617 // - this is the real start of a non-collapsed bookmark
618 // - this is the real position of a collapsed bookmark
619 // - this is the start or end (depending on bOnlyFrameStarts)
620 // of a collapsed bookmark at the same position as an at-char
621 // anchored frame
623 new SwXTextPortion(pUnoCursor, xParent, bEnd ? PORTION_BOOKMARK_END : PORTION_BOOKMARK_START);
624 rPortions.emplace_back(pPortion);
625 pPortion->SetBookmark(pPtr->xBookmark);
626 pPortion->SetCollapsed( BkmType::StartEnd == pPtr->nBkmType && !bFrameStart );
627 }
628 }
629 else if (BkmType::End == pPtr->nBkmType && !bOnlyFrameStarts)
630 {
632 new SwXTextPortion(pUnoCursor, xParent, PORTION_BOOKMARK_END);
633 rPortions.emplace_back(pPortion);
634 pPortion->SetBookmark(pPtr->xBookmark);
635 }
636
637 // next bookmark
638 if (bOnlyFrameStarts)
639 ++aIter;
640 else
641 aIter = rBkmArr.erase(aIter);
642 }
643}
644
646 TextRangeList_t & rPortions,
647 Reference<XText> const& xParent,
648 const SwUnoCursor * const pUnoCursor,
649 SwSoftPageBreakList& rBreakArr,
650 const sal_Int32 nIndex)
651{
652 for ( auto aIter = rBreakArr.begin(); aIter != rBreakArr.end(); )
653 {
654 if ( nIndex > *aIter )
655 {
656 aIter = rBreakArr.erase(aIter);
657 continue;
658 }
659 if ( nIndex < *aIter )
660 break;
661
662 rPortions.push_back(
663 new SwXTextPortion(pUnoCursor, xParent, PORTION_SOFT_PAGEBREAK) );
664 aIter = rBreakArr.erase(aIter);
665 }
666}
667
668namespace {
669
670struct SwXRedlinePortion_Impl
671{
672 const SwRangeRedline* m_pRedline;
673 const bool m_bStart;
674
675 SwXRedlinePortion_Impl ( const SwRangeRedline* pRed, const bool bIsStart )
676 : m_pRedline(pRed)
677 , m_bStart(bIsStart)
678 {
679 }
680
681 sal_Int32 getRealIndex () const
682 {
683 return m_bStart ? m_pRedline->Start()->GetContentIndex()
684 : m_pRedline->End() ->GetContentIndex();
685 }
686};
687
688}
689
690typedef std::shared_ptr < SwXRedlinePortion_Impl >
692
693namespace {
694
695struct RedlineCompareStruct
696{
697 static const SwPosition& getPosition ( const SwXRedlinePortion_ImplSharedPtr &r )
698 {
699 return *(r->m_bStart ? r->m_pRedline->Start() : r->m_pRedline->End());
700 }
701
702 bool operator () ( const SwXRedlinePortion_ImplSharedPtr &r1,
703 const SwXRedlinePortion_ImplSharedPtr &r2 ) const
704 {
705 return getPosition ( r1 ) < getPosition ( r2 );
706 }
707};
708
709}
710
711typedef std::multiset < SwXRedlinePortion_ImplSharedPtr, RedlineCompareStruct >
713
714static Reference<XTextRange>
716 PortionStack_t & rPortionStack,
717 const Reference<XText> & xParent,
718 SwUnoCursor * const pUnoCursor,
719 SwpHints const * const pHints,
720 const sal_Int32 i_nStartPos,
721 const sal_Int32 i_nEndPos,
722 const sal_Int32 nCurrentIndex,
723 const bool bRightMoveForbidden,
724 bool & o_rbCursorMoved,
725 sal_Int32 & o_rNextAttrPosition)
726{
727 // if the attribute has a dummy character, then xRef is set (except META and CONTENT_CONTROL)
728 // otherwise, the portion for the attribute is inserted into rPortions!
729 Reference<XTextRange> xRef;
730 SwDoc& rDoc = pUnoCursor->GetDoc();
731 //search for special text attributes - first some ends
732 size_t nEndIndex = 0;
733 sal_Int32 nNextEnd = 0;
734 const auto nHintsCount = pHints->Count();
735 while(nEndIndex < nHintsCount &&
736 (!pHints->GetSortedByEnd(nEndIndex)->GetEnd() ||
737 nCurrentIndex >= (nNextEnd = (*pHints->GetSortedByEnd(nEndIndex)->GetEnd()))))
738 {
739 if(pHints->GetSortedByEnd(nEndIndex)->GetEnd())
740 {
741 SwTextAttr * const pAttr = pHints->GetSortedByEnd(nEndIndex);
742 if (nNextEnd == nCurrentIndex)
743 {
744 const sal_uInt16 nWhich( pAttr->Which() );
745 switch (nWhich)
746 {
748 {
749 Reference<XTextRange> xTmp = lcl_CreateTOXMarkPortion(
750 xParent, pUnoCursor, *pAttr, true);
751 rPortionStack.top().first->push_back(xTmp);
752 }
753 break;
755 {
756 Reference<XTextRange> xTmp = lcl_CreateRefMarkPortion(
757 xParent, pUnoCursor, *pAttr, true);
758 rPortionStack.top().first->push_back(xTmp);
759 }
760 break;
762 //#i91534# GetEnd() == 0 mixes the order of ruby start/end
763 if( *pAttr->GetEnd() == pAttr->GetStart())
764 {
765 lcl_InsertRubyPortion( *rPortionStack.top().first,
766 xParent, pUnoCursor, *pAttr, false);
767 }
768 lcl_InsertRubyPortion( *rPortionStack.top().first,
769 xParent, pUnoCursor, *pAttr, true);
770 break;
771 case RES_TXTATR_META:
773 {
774 OSL_ENSURE(pAttr->GetStart() != *pAttr->GetEnd(),
775 "empty meta?");
776 if ((i_nStartPos > 0) &&
777 (pAttr->GetStart() < i_nStartPos))
778 {
779 // force skip pAttr and rest of attribute ends
780 // at nCurrentIndex
781 // because they are not contained in the meta pAttr
782 // and the meta pAttr itself is outside selection!
783 // (necessary for SwXMeta::createEnumeration)
784 if (pAttr->GetStart() + 1 == i_nStartPos)
785 {
786 nEndIndex = pHints->Count() - 1;
787 }
788 break;
789 }
790 PortionList_t Top = rPortionStack.top();
791 if (Top.second != pAttr)
792 {
793 OSL_FAIL("ExportHints: stack error" );
794 }
795 else
796 {
797 std::unique_ptr<const TextRangeList_t>
798 pCurrentPortions(Top.first);
799 rPortionStack.pop();
800 const uno::Reference<text::XTextRange> xPortion(
801 lcl_CreateMetaPortion(xParent, pUnoCursor,
802 *pAttr, std::move(pCurrentPortions)));
803 rPortionStack.top().first->push_back(xPortion);
804 }
805 }
806 break;
808 {
809 if (pAttr->GetStart() == *pAttr->GetEnd())
810 {
811 SAL_WARN("sw.core", "lcl_ExportHints: empty content control");
812 }
813 if ((i_nStartPos > 0) && (pAttr->GetStart() < i_nStartPos))
814 {
815 // If the start pos is the start of the content of the content control,
816 // skip it: it'll be handled in SwXContentControl::createEnumeration().
817 if (pAttr->GetStart() + 1 == i_nStartPos)
818 {
819 nEndIndex = pHints->Count() - 1;
820 }
821 break;
822 }
823 PortionList_t Top = rPortionStack.top();
824 if (Top.second != pAttr)
825 {
826 SAL_WARN("sw.core", "lcl_ExportHints: content control is not at the "
827 "top of the portion stack");
828 }
829 else
830 {
831 std::unique_ptr<const TextRangeList_t> pCurrentPortions(Top.first);
832 rPortionStack.pop();
833 uno::Reference<text::XTextRange> xPortion(
834 lcl_CreateContentControlPortion(xParent, pUnoCursor, *pAttr,
835 std::move(pCurrentPortions)));
836 rPortionStack.top().first->push_back(xPortion);
837 }
838 }
839 break;
840 }
841 }
842 }
843 nEndIndex++;
844 }
845
846 // then some starts
847 size_t nStartIndex = 0;
848 sal_Int32 nNextStart = 0;
849 while(nStartIndex < nHintsCount &&
850 nCurrentIndex >= (nNextStart = pHints->Get(nStartIndex)->GetStart()))
851 {
852 SwTextAttr * const pAttr = pHints->Get(nStartIndex);
853 sal_uInt16 nAttrWhich = pAttr->Which();
854 if (nNextStart == nCurrentIndex)
855 {
856 switch( nAttrWhich )
857 {
858 case RES_TXTATR_FIELD:
859 if(!bRightMoveForbidden)
860 {
861 pUnoCursor->Right(1);
862 if( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
863 break;
865 new SwXTextPortion(
866 pUnoCursor, xParent, PORTION_FIELD);
867 xRef = pPortion;
868 Reference<XTextField> const xField =
870 &pAttr->GetFormatField());
871 pPortion->SetTextField(xField);
872 }
873 break;
874
876 if(!bRightMoveForbidden)
877 {
878 pUnoCursor->Right(1);
879 if( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
880 break;
881
882 const SwTextAnnotationField* pTextAnnotationField = dynamic_cast<const SwTextAnnotationField*>( pAttr );
883 ::sw::mark::IMark* pAnnotationMark = pTextAnnotationField ? pTextAnnotationField->GetAnnotationMark() : nullptr;
884 if ( pAnnotationMark != nullptr )
885 {
886 rtl::Reference<SwXTextPortion> pPortion = new SwXTextPortion( pUnoCursor, xParent, PORTION_ANNOTATION_END );
887 pPortion->SetBookmark(SwXBookmark::CreateXBookmark(
888 rDoc, pAnnotationMark));
889 xRef = pPortion;
890 }
891 else
892 {
893 rtl::Reference<SwXTextPortion> pPortion = new SwXTextPortion( pUnoCursor, xParent, PORTION_ANNOTATION );
894 Reference<XTextField> xField =
896 &pAttr->GetFormatField());
897 pPortion->SetTextField(xField);
898 xRef = pPortion;
899 }
900 }
901 break;
902
904 if(!bRightMoveForbidden)
905 {
906
907 pUnoCursor->Right(
908 pAttr->GetFormatField().GetField()->ExpandField(true, nullptr).getLength() + 2 );
909 if( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
910 break;
912 new SwXTextPortion( pUnoCursor, xParent, PORTION_FIELD);
913 xRef = pPortion;
914 Reference<XTextField> xField =
916 &pAttr->GetFormatField());
917 pPortion->SetTextField(xField);
918 }
919 break;
920
922 if(!bRightMoveForbidden)
923 {
924 pUnoCursor->Right(1);
925 if( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
926 break; // Robust #i81708# content in covered cells
927
928 // Do not expose inline anchored textboxes.
930 break;
931
932 pUnoCursor->Exchange();
933 xRef = new SwXTextPortion( pUnoCursor, xParent, PORTION_FRAME);
934 }
935 break;
936
937 case RES_TXTATR_FTN:
938 {
939 if(!bRightMoveForbidden)
940 {
941 pUnoCursor->Right(1);
942 if( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
943 break;
945 pUnoCursor, xParent, PORTION_FOOTNOTE);
946 xRef = pPortion;
947 Reference<XFootnote> xContent =
948 SwXFootnotes::GetObject(rDoc, pAttr->GetFootnote());
949 pPortion->SetFootnote(xContent);
950 }
951 }
952 break;
953
956 {
957 bool bIsPoint = !(pAttr->GetEnd());
958 if (!bRightMoveForbidden || !bIsPoint)
959 {
960 if (bIsPoint)
961 {
962 pUnoCursor->Right(1);
963 }
964 Reference<XTextRange> xTmp =
965 (RES_TXTATR_REFMARK == nAttrWhich)
967 xParent, pUnoCursor, *pAttr, false)
969 xParent, pUnoCursor, *pAttr, false);
970 if (bIsPoint) // consume CH_TXTATR!
971 {
972 pUnoCursor->Normalize(false);
973 pUnoCursor->DeleteMark();
974 xRef = xTmp;
975 }
976 else // just insert it
977 {
978 rPortionStack.top().first->push_back(xTmp);
979 }
980 }
981 }
982 break;
984 //#i91534# GetEnd() == 0 mixes the order of ruby start/end
985 if(pAttr->GetEnd() && (*pAttr->GetEnd() != pAttr->GetStart()))
986 {
987 lcl_InsertRubyPortion( *rPortionStack.top().first,
988 xParent, pUnoCursor, *pAttr, false);
989 }
990 break;
991 case RES_TXTATR_META:
994 if (pAttr->GetStart() != *pAttr->GetEnd())
995 {
996 if (!bRightMoveForbidden)
997 {
998 pUnoCursor->Right(1);
999 o_rbCursorMoved = true;
1000 // only if the end is included in selection!
1001 if ((i_nEndPos < 0) ||
1002 (*pAttr->GetEnd() <= i_nEndPos))
1003 {
1004 rPortionStack.push( std::make_pair(
1005 new TextRangeList_t, pAttr ));
1006 }
1007 }
1008 }
1009 break;
1011 if (!bRightMoveForbidden)
1012 {
1013 pUnoCursor->Right(1);
1014 if (*pUnoCursor->GetMark() == *pUnoCursor->GetPoint())
1015 break;
1017 = new SwXTextPortion(pUnoCursor, xParent, PORTION_LINEBREAK);
1018 xRef = pPortion;
1019 uno::Reference<text::XTextContent> xLineBreak
1021 &const_cast<SwFormatLineBreak&>(pAttr->GetLineBreak()));
1022 pPortion->SetLineBreak(xLineBreak);
1023 }
1024 break;
1025 case RES_TXTATR_AUTOFMT:
1026 case RES_TXTATR_INETFMT:
1027 case RES_TXTATR_CHARFMT:
1028 break; // these are handled as properties of a "Text" portion
1029 default:
1030 OSL_FAIL("unknown attribute");
1031 break;
1032 }
1033 }
1034 nStartIndex++;
1035 }
1036
1037 if (xRef.is()) // implies that we have moved the cursor
1038 {
1039 o_rbCursorMoved = true;
1040 }
1041 if (!o_rbCursorMoved)
1042 {
1043 // search for attribute changes behind the current cursor position
1044 // break up at frames, bookmarks, redlines
1045
1046 nStartIndex = 0;
1047 nNextStart = 0;
1048 while(nStartIndex < pHints->Count() &&
1049 nCurrentIndex >= (nNextStart = pHints->Get(nStartIndex)->GetStart()))
1050 nStartIndex++;
1051
1052 nEndIndex = 0;
1053 nNextEnd = 0;
1054 while(nEndIndex < pHints->Count() &&
1055 nCurrentIndex >= (nNextEnd = pHints->GetSortedByEnd(nEndIndex)->GetAnyEnd()))
1056 nEndIndex++;
1057
1058 sal_Int32 nNextPos =
1059 ((nNextStart > nCurrentIndex) && (nNextStart < nNextEnd))
1060 ? nNextStart : nNextEnd;
1061 if (nNextPos > nCurrentIndex)
1062 {
1063 o_rNextAttrPosition = nNextPos;
1064 }
1065 }
1066 return xRef;
1067}
1068
1069static void lcl_MoveCursor( SwUnoCursor * const pUnoCursor,
1070 const sal_Int32 nCurrentIndex,
1071 const sal_Int32 nNextFrameIndex,
1072 const sal_Int32 nNextPortionIndex,
1073 const sal_Int32 nNextAttrIndex,
1074 const sal_Int32 nNextMarkIndex,
1075 const sal_Int32 nEndPos )
1076{
1077 sal_Int32 nMovePos = pUnoCursor->GetPointContentNode()->Len();
1078
1079 if ((nEndPos >= 0) && (nEndPos < nMovePos))
1080 {
1081 nMovePos = nEndPos;
1082 }
1083
1084 if ((nNextFrameIndex >= 0) && (nNextFrameIndex < nMovePos))
1085 {
1086 nMovePos = nNextFrameIndex;
1087 }
1088
1089 if ((nNextPortionIndex >= 0) && (nNextPortionIndex < nMovePos))
1090 {
1091 nMovePos = nNextPortionIndex;
1092 }
1093
1094 if ((nNextAttrIndex >= 0) && (nNextAttrIndex < nMovePos))
1095 {
1096 nMovePos = nNextAttrIndex;
1097 }
1098
1099 if ((nNextMarkIndex >= 0) && (nNextMarkIndex < nMovePos))
1100 {
1101 nMovePos = nNextMarkIndex;
1102 }
1103
1104 if (nMovePos > nCurrentIndex)
1105 {
1106 pUnoCursor->GetPoint()->SetContent( nMovePos );
1107 }
1108}
1109
1111 SwDoc const & rDoc,
1112 SwUnoCursor const & rUnoCursor,
1114{
1115 const SwRedlineTable& rRedTable = rDoc.getIDocumentRedlineAccess().GetRedlineTable();
1116 const size_t nRedTableCount = rRedTable.size();
1117
1118 if ( nRedTableCount <= 0 )
1119 return;
1120
1121 const SwPosition* pStart = rUnoCursor.GetPoint();
1122 const SwNode& rOwnNode = pStart->GetNode();
1123
1124 SwRedlineTable::size_type nRed = rDoc.getIDocumentRedlineAccess().GetRedlinePos(rOwnNode, RedlineType::Any);
1125 for(; nRed < nRedTableCount; ++nRed)
1126 {
1127 const SwRangeRedline* pRedline = rRedTable[nRed];
1128 auto [pRedStart, pRedEnd]= pRedline->StartEnd();
1129 if ( rOwnNode == pRedStart->GetNode() )
1130 rRedArr.insert( std::make_shared<SwXRedlinePortion_Impl>(
1131 pRedline, true ) );
1132 if( pRedline->HasMark() && pRedEnd->GetNode() == rOwnNode )
1133 rRedArr.insert( std::make_shared<SwXRedlinePortion_Impl>(
1134 pRedline, false ) );
1135 }
1136}
1137
1139 SwUnoCursor const & rUnoCursor,
1140 SwSoftPageBreakList& rBreakArr )
1141{
1142 const SwTextNode *pTextNode =
1143 rUnoCursor.GetPoint()->GetNode().GetTextNode();
1144 if( pTextNode )
1145 pTextNode->fillSoftPageBreakList( rBreakArr );
1146}
1147
1149 TextRangeList_t & rPortions,
1150 Reference<XText> const& xParent,
1151 const SwUnoCursor * const pUnoCursor,
1152 SwXRedlinePortion_ImplList& rRedlineArr,
1153 const sal_Int32 nIndex)
1154{
1155
1156 // We want this loop to iterate over all red lines in this
1157 // array. We will only insert the ones with index matches
1158 for ( SwXRedlinePortion_ImplList::iterator aIter = rRedlineArr.begin(), aEnd = rRedlineArr.end();
1159 aIter != aEnd; )
1160 {
1161 SwXRedlinePortion_ImplSharedPtr pPtr = *aIter;
1162 sal_Int32 nRealIndex = pPtr->getRealIndex();
1163 // If there are elements before nIndex, remove them
1164 if ( nIndex > nRealIndex )
1165 aIter = rRedlineArr.erase(aIter);
1166 // If the elements match, and them to the list
1167 else if ( nIndex == nRealIndex )
1168 {
1169 rPortions.push_back( new SwXRedlinePortion(
1170 *pPtr->m_pRedline, pUnoCursor, xParent, pPtr->m_bStart));
1171 aIter = rRedlineArr.erase(aIter);
1172 }
1173 // If we've iterated past nIndex, exit the loop
1174 else
1175 break;
1176 }
1177}
1178
1180 TextRangeList_t & rPortions,
1181 Reference<XText> const & xParent,
1182 const SwUnoCursor * const pUnoCursor,
1183 SwXBookmarkPortion_ImplList& rBkmArr,
1184 SwXRedlinePortion_ImplList& rRedlineArr,
1185 SwSoftPageBreakList& rBreakArr,
1186 const sal_Int32 nIndex,
1187 const o3tl::sorted_vector<sal_Int32>& rFramePositions,
1188 bool bOnlyFrameBookmarkStarts)
1189{
1190 if (!rBkmArr.empty())
1191 lcl_ExportBookmark(rPortions, xParent, pUnoCursor, rBkmArr, nIndex, rFramePositions,
1192 bOnlyFrameBookmarkStarts);
1193
1194 if (bOnlyFrameBookmarkStarts)
1195 // Only exporting the start of some collapsed bookmarks: no export of
1196 // other arrays.
1197 return;
1198
1199 if (!rRedlineArr.empty())
1200 lcl_ExportRedline(rPortions, xParent, pUnoCursor, rRedlineArr, nIndex);
1201
1202 if (!rBreakArr.empty())
1203 lcl_ExportSoftPageBreak(rPortions, xParent, pUnoCursor, rBreakArr, nIndex);
1204}
1205
1218 TextRangeList_t & rPortions,
1219 Reference<XText> const & xParent,
1220 const SwUnoCursor * const pUnoCursor,
1221 SwAnnotationStartPortion_ImplList& rAnnotationStartArr,
1222 const sal_Int32 nIndex,
1223 const o3tl::sorted_vector<sal_Int32>& rFramePositions,
1224 bool bOnlyFrame)
1225{
1226 for ( SwAnnotationStartPortion_ImplList::iterator aIter = rAnnotationStartArr.begin(), aEnd = rAnnotationStartArr.end();
1227 aIter != aEnd; )
1228 {
1229 SwAnnotationStartPortion_ImplSharedPtr pPtr = *aIter;
1230 if ( nIndex > pPtr->getIndex() )
1231 {
1232 aIter = rAnnotationStartArr.erase(aIter);
1233 continue;
1234 }
1235 if ( pPtr->getIndex() > nIndex )
1236 {
1237 break;
1238 }
1239
1240 bool bFrameStart = rFramePositions.find(nIndex) != rFramePositions.end();
1241 if (bFrameStart || !bOnlyFrame)
1242 {
1244 new SwXTextPortion( pUnoCursor, xParent, PORTION_ANNOTATION );
1245 pPortion->SetTextField( pPtr->mxAnnotationField );
1246 rPortions.emplace_back(pPortion);
1247
1248 aIter = rAnnotationStartArr.erase(aIter);
1249 }
1250 else
1251 ++aIter;
1252 }
1253}
1254
1256static void lcl_ExtractFramePositions(FrameClientSortList_t& rFrames, sal_Int32 nCurrentIndex,
1257 o3tl::sorted_vector<sal_Int32>& rFramePositions)
1258{
1259 for (const auto& rFrame : rFrames)
1260 {
1261 if (rFrame.nIndex < nCurrentIndex)
1262 continue;
1263
1264 if (rFrame.nIndex > nCurrentIndex)
1265 break;
1266
1267 const auto pFrame = static_cast<const SwFrameFormat*>(rFrame.pFrameClient->GetRegisteredIn());
1268 if (!pFrame)
1269 continue;
1270
1271 auto& rFormat = *const_cast<SwFrameFormat*>(pFrame);
1272 const SwFormatAnchor& rAnchor = rFormat.GetAnchor();
1273 if (!rAnchor.GetAnchorNode())
1274 continue;
1275
1276 rFramePositions.insert(rAnchor.GetAnchorContentOffset());
1277 }
1278}
1279
1286static sal_Int32 lcl_ExportFrames(
1287 TextRangeList_t & rPortions,
1288 Reference<XText> const & i_xParent,
1289 SwUnoCursor const * const i_pUnoCursor,
1290 FrameClientSortList_t & i_rFrames,
1291 sal_Int32 const i_nCurrentIndex)
1292{
1293 // Ignore frames which are not exported, as we are exporting a selection
1294 // and they are anchored before the start of the selection.
1295 while (!i_rFrames.empty() && i_rFrames.front().nIndex < i_nCurrentIndex)
1296 i_rFrames.pop_front();
1297
1298 // find first Frame in (sorted) i_rFrames at current position
1299 while (!i_rFrames.empty() && (i_rFrames.front().nIndex == i_nCurrentIndex))
1300 // do not check for i_nEnd here; this is done implicitly by lcl_MoveCursor
1301 {
1302 auto pFrame = static_cast<SwFrameFormat*>(i_rFrames.front().pFrameClient->GetRegisteredIn());
1303 if (pFrame) // Frame could be disposed
1304 {
1305 rtl::Reference<SwXTextPortion> pPortion = new SwXTextPortion(i_pUnoCursor, i_xParent, *pFrame );
1306 rPortions.emplace_back(pPortion);
1307 }
1308 i_rFrames.pop_front();
1309 }
1310
1311 return !i_rFrames.empty() ? i_rFrames.front().nIndex : -1;
1312}
1313
1314static sal_Int32 lcl_GetNextIndex(
1315 SwXBookmarkPortion_ImplList const & rBkmArr,
1316 SwXRedlinePortion_ImplList const & rRedlineArr,
1317 SwSoftPageBreakList const & rBreakArr )
1318{
1319 sal_Int32 nRet = -1;
1320 if(!rBkmArr.empty())
1321 {
1322 SwXBookmarkPortion_ImplSharedPtr pPtr = *rBkmArr.begin();
1323 nRet = pPtr->getIndex();
1324 }
1325 if(!rRedlineArr.empty())
1326 {
1327 SwXRedlinePortion_ImplSharedPtr pPtr = *rRedlineArr.begin();
1328 sal_Int32 nTmp = pPtr->getRealIndex();
1329 if(nRet < 0 || nTmp < nRet)
1330 nRet = nTmp;
1331 }
1332 if(!rBreakArr.empty())
1333 {
1334 if(nRet < 0 || *rBreakArr.begin() < nRet)
1335 nRet = *rBreakArr.begin();
1336 }
1337 return nRet;
1338};
1339
1341 TextRangeList_t & i_rPortions,
1342 uno::Reference< text::XText > const & i_xParentText,
1343 SwUnoCursor * const pUnoCursor,
1344 FrameClientSortList_t & i_rFrames,
1345 const sal_Int32 i_nStartPos,
1346 const sal_Int32 i_nEndPos,
1347 bool bOnlyTextFields )
1348{
1349 if (!pUnoCursor)
1350 return;
1351
1352 // set the start if a selection should be exported
1353 if ((i_nStartPos > 0) &&
1354 (pUnoCursor->Start()->GetContentIndex() != i_nStartPos))
1355 {
1356 pUnoCursor->DeleteMark();
1357 OSL_ENSURE(pUnoCursor->Start()->GetNode().GetTextNode() &&
1358 (i_nStartPos <= pUnoCursor->Start()->GetNode().GetTextNode()->
1359 GetText().getLength()), "Incorrect start position" );
1360 // ??? should this be i_nStartPos - current position ?
1361 pUnoCursor->Right(i_nStartPos);
1362 }
1363
1364 SwDoc& rDoc = pUnoCursor->GetDoc();
1365
1366 std::deque<sal_Int32> FieldMarks;
1367 if (!bOnlyTextFields)
1368 lcl_FillFieldMarkArray(FieldMarks, *pUnoCursor, i_nStartPos);
1369
1370 SwXBookmarkPortion_ImplList Bookmarks;
1371 if (!bOnlyTextFields)
1372 lcl_FillBookmarkArray(rDoc, *pUnoCursor, Bookmarks);
1373
1375 if (!bOnlyTextFields)
1376 lcl_FillRedlineArray(rDoc, *pUnoCursor, Redlines);
1377
1378 SwSoftPageBreakList SoftPageBreaks;
1379 if (!bOnlyTextFields)
1380 lcl_FillSoftPageBreakArray(*pUnoCursor, SoftPageBreaks);
1381
1382 SwAnnotationStartPortion_ImplList AnnotationStarts;
1383 if (!bOnlyTextFields)
1384 lcl_FillAnnotationStartArray( rDoc, *pUnoCursor, AnnotationStarts );
1385
1386 PortionStack_t PortionStack;
1387 PortionStack.push( PortionList_t(&i_rPortions, nullptr) );
1388
1389 bool bAtEnd( false );
1390 while (!bAtEnd) // every iteration consumes at least current character!
1391 {
1392 if (pUnoCursor->HasMark())
1393 {
1394 pUnoCursor->Normalize(false);
1395 pUnoCursor->DeleteMark();
1396 }
1397
1398 SwTextNode * const pTextNode = pUnoCursor->GetPointNode().GetTextNode();
1399 if (!pTextNode)
1400 {
1401 OSL_FAIL("lcl_CreatePortions: no TextNode - what now ?");
1402 return;
1403 }
1404
1405 SwpHints * const pHints = pTextNode->GetpSwpHints();
1406 const sal_Int32 nCurrentIndex =
1407 pUnoCursor->GetPoint()->GetContentIndex();
1408 // this contains the portion which consumes the character in the
1409 // text at nCurrentIndex; i.e. it must be set _once_ per iteration
1410 uno::Reference< XTextRange > xRef;
1411
1412 SwUnoCursorHelper::SelectPam(*pUnoCursor, true); // set mark
1413
1414 // First remember the frame positions.
1415 o3tl::sorted_vector<sal_Int32> aFramePositions;
1416 lcl_ExtractFramePositions(i_rFrames, nCurrentIndex, aFramePositions);
1417
1418 // Then export start of collapsed bookmarks which "cover" at-char
1419 // anchored frames.
1420 lcl_ExportBkmAndRedline( *PortionStack.top().first, i_xParentText,
1421 pUnoCursor, Bookmarks, Redlines, SoftPageBreaks, nCurrentIndex, aFramePositions, /*bOnlyFrameBookmarkStarts=*/true );
1422
1424 *PortionStack.top().first,
1425 i_xParentText,
1426 pUnoCursor,
1427 AnnotationStarts,
1428 nCurrentIndex,
1429 aFramePositions,
1430 /*bOnlyFrame=*/true );
1431
1432 const sal_Int32 nFirstFrameIndex =
1433 lcl_ExportFrames( *PortionStack.top().first,
1434 i_xParentText, pUnoCursor, i_rFrames, nCurrentIndex);
1435
1436 // Export ends of the previously started collapsed bookmarks + all
1437 // other bookmarks, redlines, etc.
1438 lcl_ExportBkmAndRedline( *PortionStack.top().first, i_xParentText,
1439 pUnoCursor, Bookmarks, Redlines, SoftPageBreaks, nCurrentIndex, aFramePositions, /*bOnlyFrameBookmarkStarts=*/false );
1440
1442 *PortionStack.top().first,
1443 i_xParentText,
1444 pUnoCursor,
1445 AnnotationStarts,
1446 nCurrentIndex,
1447 aFramePositions,
1448 /*bOnlyFrame=*/false );
1449
1450 bool bCursorMoved( false );
1451 sal_Int32 nNextAttrIndex = -1;
1452 // #111716# the cursor must not move right at the
1453 // end position of a selection!
1454 bAtEnd = ((i_nEndPos >= 0) && (nCurrentIndex >= i_nEndPos))
1455 || (nCurrentIndex >= pTextNode->Len());
1456 if (pHints)
1457 {
1458 // N.B.: side-effects nNextAttrIndex, bCursorMoved; may move cursor
1459 xRef = lcl_ExportHints(PortionStack, i_xParentText, pUnoCursor,
1460 pHints, i_nStartPos, i_nEndPos, nCurrentIndex, bAtEnd,
1461 bCursorMoved, nNextAttrIndex);
1462 if (PortionStack.empty())
1463 {
1464 OSL_FAIL("CreatePortions: stack underflow");
1465 return;
1466 }
1467 }
1468
1469 if (!xRef.is() && !bCursorMoved)
1470 {
1471 if (!bAtEnd &&
1472 !FieldMarks.empty() && (FieldMarks.front() == nCurrentIndex))
1473 {
1474 // moves cursor
1475 xRef = lcl_ExportFieldMark(i_xParentText, pUnoCursor, pTextNode);
1476 FieldMarks.pop_front();
1477 }
1478 }
1479 else
1480 {
1481 OSL_ENSURE(FieldMarks.empty() ||
1482 (FieldMarks.front() != nCurrentIndex),
1483 "fieldmark and hint with CH_TXTATR at same pos?");
1484 }
1485
1486 if (!bAtEnd && !xRef.is() && !bCursorMoved)
1487 {
1488 const sal_Int32 nNextPortionIndex =
1489 lcl_GetNextIndex(Bookmarks, Redlines, SoftPageBreaks);
1490
1491 sal_Int32 nNextMarkIndex = ( !FieldMarks.empty() ? FieldMarks.front() : -1 );
1492 if ( !AnnotationStarts.empty()
1493 && ( nNextMarkIndex == -1
1494 || (*AnnotationStarts.begin())->getIndex() < nNextMarkIndex ) )
1495 {
1496 nNextMarkIndex = (*AnnotationStarts.begin())->getIndex();
1497 }
1498
1500 pUnoCursor,
1501 nCurrentIndex,
1502 nFirstFrameIndex,
1503 nNextPortionIndex,
1504 nNextAttrIndex,
1505 nNextMarkIndex,
1506 i_nEndPos );
1507
1508 xRef = new SwXTextPortion(pUnoCursor, i_xParentText, PORTION_TEXT);
1509 }
1510 else if (bAtEnd && !xRef.is() && !pTextNode->Len())
1511 {
1512 // special case: for an empty paragraph, we better put out a
1513 // text portion because there may be a hyperlink attribute
1514 xRef = new SwXTextPortion(pUnoCursor, i_xParentText, PORTION_TEXT);
1515 }
1516
1517 if (xRef.is())
1518 {
1519 PortionStack.top().first->push_back(xRef);
1520 }
1521 }
1522
1523 OSL_ENSURE((PortionStack.size() == 1) && !PortionStack.top().second,
1524 "CreatePortions: stack error" );
1525}
1526
1527/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
geometry::RealPoint2D maPosition
const Any & any
wrapper iterator: wraps iterator of implementation while hiding MarkBase class; only IMark instances ...
Provides access to the marks of a document.
virtual const_iterator_t getAnnotationMarksBegin() const =0
virtual ::sw::mark::IFieldmark * getFieldmarkAt(const SwPosition &rPos) const =0
get Fieldmark for CH_TXT_ATR_FIELDSTART/CH_TXT_ATR_FIELDEND at rPos
virtual sal_Int32 getAnnotationMarksCount() const =0
virtual const_iterator_t findFirstAnnotationStartsAfter(const SwPosition &rPos) const =0
Finds the first mark that is starting after.
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:476
virtual sal_Int32 getBookmarksCount() const =0
returns the number of IBookmarks.
virtual SwRedlineTable::size_type GetRedlinePos(const SwNode &rNode, RedlineType nType) const =0
virtual const SwRedlineTable & GetRedlineTable() const =0
Marks a character position inside a document model content node (SwContentNode)
virtual sal_Int32 Len() const
Definition: node.cxx:1263
bool Right(sal_uInt16 nCnt)
Definition: swcrsr.hxx:173
Definition: doc.hxx:194
void cleanupUnoCursorTable() const
Definition: doc.hxx:1662
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:341
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1814
std::shared_ptr< SwUnoCursor > CreateUnoCursor(const SwPosition &rPos, bool bTableCursor=false)
Definition: doc.cxx:1779
OUString ExpandField(bool bCached, SwRootFrame const *pLayout) const
expand the field.
Definition: fldbas.cxx:484
FlyAnchors.
Definition: fmtanchr.hxx:37
sal_Int32 GetAnchorContentOffset() const
Definition: atrfrm.cxx:1623
SwNode * GetAnchorNode() const
Definition: atrfrm.cxx:1606
SfxPoolItem subclass that wraps an SwContentControl.
const std::shared_ptr< SwContentControl > & GetContentControl() const
const SwField * GetField() const
Definition: fmtfld.hxx:130
SwFrameFormat * GetFrameFormat() const
Definition: fmtflcnt.hxx:45
SfxPoolItem subclass that wraps an SwLineBreakClear.
::sw::Meta * GetMeta()
Definition: fmtmeta.hxx:122
Style of a layout element.
Definition: frmfmt.hxx:62
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:897
SwContentNode * GetContentNode()
Definition: node.hxx:664
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
const SwPosition * GetMark() const
Definition: pam.hxx:263
SwNode & GetPointNode() const
Definition: pam.hxx:283
void Exchange()
Definition: pam.cxx:656
void Normalize(bool bPointFirst=true)
Normalizes PaM, i.e.
Definition: pam.cxx:700
std::pair< const SwPosition *, const SwPosition * > StartEnd() const
Because sometimes the cost of the operator<= can add up.
Definition: pam.hxx:277
SwContentNode * GetPointContentNode() const
Definition: pam.hxx:287
const SwPosition * End() const
Definition: pam.hxx:271
SwDoc & GetDoc() const
Definition: pam.hxx:299
void DeleteMark()
Definition: pam.hxx:231
const SwPosition * GetPoint() const
Definition: pam.hxx:261
const SwPosition * Start() const
Definition: pam.hxx:266
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:259
size_type size() const
Definition: docary.hxx:267
vector_type::size_type size_type
Definition: docary.hxx:222
::sw::mark::IMark * GetAnnotationMark() const
Definition: atrfld.cxx:758
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
const SfxPoolItem & GetAttr() const
Definition: txatbase.hxx:167
sal_Int32 GetAnyEnd() const
end (if available), else start
Definition: txatbase.hxx:161
virtual const sal_Int32 * GetEnd() const
end position
Definition: txatbase.cxx:48
const sal_Int32 * End() const
Definition: txatbase.hxx:156
const SwFormatFlyCnt & GetFlyCnt() const
Definition: txatbase.hxx:226
const SwFormatLineBreak & GetLineBreak() const
Definition: txatbase.hxx:214
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:208
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
sal_uInt16 Which() const
Definition: txatbase.hxx:116
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:199
static bool isTextBox(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
Is the frame format a text box?
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:111
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:290
void fillSoftPageBreakList(SwSoftPageBreakList &rBreak) const
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:250
const OUString & GetText() const
Definition: ndtxt.hxx:242
static rtl::Reference< SwXBookmark > CreateXBookmark(SwDoc &rDoc, ::sw::mark::IMark *pBookmark)
Definition: unobkm.cxx:157
static rtl::Reference< SwXContentControl > CreateXContentControl(SwContentControl &rContentControl, const css::uno::Reference< css::text::XText > &xParentText=nullptr, std::unique_ptr< const TextRangeList_t > &&pPortions=std::unique_ptr< const TextRangeList_t >())
static rtl::Reference< SwXDocumentIndexMark > CreateXDocumentIndexMark(SwDoc &rDoc, SwTOXMark *pMark, TOXTypes eType=TOX_INDEX)
Definition: unoidx.cxx:1614
static rtl::Reference< SwXBookmark > CreateXFieldmark(SwDoc &rDoc, ::sw::mark::IMark *pMark, bool isReplacementObject=false)
Definition: unobkm.cxx:689
static css::uno::Reference< css::text::XFootnote > GetObject(SwDoc &rDoc, const SwFormatFootnote &rFormat)
Definition: unocoll.cxx:1825
static rtl::Reference< SwXLineBreak > CreateXLineBreak(SwFormatLineBreak *pLineBreakFormat)
static rtl::Reference< SwXMeta > CreateXMeta(::sw::Meta &rMeta, css::uno::Reference< css::text::XText > const &xParentText=nullptr, std::unique_ptr< TextRangeList_t const > &&pPortions=std::unique_ptr< TextRangeList_t const >())
static rtl::Reference< SwXReferenceMark > CreateXReferenceMark(SwDoc &rDoc, SwFormatRefMark *pMarkFormat)
Definition: unorefmk.cxx:126
static rtl::Reference< SwXTextField > CreateXTextField(SwDoc *pDoc, SwFormatField const *pFormat, SwServiceType nServiceId=SwServiceType::Invalid)
Definition: unofield.cxx:1216
virtual sal_Int64 SAL_CALL getSomething(const css::uno::Sequence< sal_Int8 > &aIdentifier) override
virtual OUString SAL_CALL getImplementationName() override
virtual css::uno::Any SAL_CALL nextElement() override
SwXTextPortionEnumeration(SwPaM &rParaCursor, css::uno::Reference< css::text::XText > const &xParent, const sal_Int32 nStart, const sal_Int32 nEnd, bool bOnlyTextFields=false)
TextRangeList_t m_Portions
Definition: unoport.hxx:254
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
virtual sal_Bool SAL_CALL hasMoreElements() override
virtual ~SwXTextPortionEnumeration() override
sw::UnoCursorPointer m_pUnoCursor
Definition: unoport.hxx:255
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
An SwTextAttr container, stores all directly formatted text portions for a text node.
Definition: ndhints.hxx:68
SwTextAttr * Get(size_t nPos) const
Definition: ndhints.hxx:144
size_t Count() const
Definition: ndhints.hxx:142
SwTextAttr * GetSortedByEnd(size_t nPos) const
Definition: ndhints.hxx:158
const css::uno::Sequence< sal_Int8 > & getSeq() const
const_iterator begin() const
const_iterator find(const Value &x) const
size_type erase(const Value &x)
bool empty() const
const_iterator end() const
std::pair< const_iterator, bool > insert(Value &&x)
void reset(std::shared_ptr< SwUnoCursor > pNew)
Definition: unocrsr.hxx:158
const SwFormatField * GetAnnotationFormatField() const
virtual bool IsExpanded() const =0
virtual const SwPosition & GetMarkEnd() const =0
virtual const SwPosition & GetMarkStart() const =0
SwPosition & GetMarkStart() const override
DocumentType eType
#define CH_TXT_ATR_FIELDSEP
Definition: hintids.hxx:180
#define CH_TXT_ATR_FORMELEMENT
Definition: hintids.hxx:177
constexpr TypedWhichId< SwFormatFootnote > RES_TXTATR_FTN(59)
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(156)
constexpr TypedWhichId< SwFormatAutoFormat > RES_TXTATR_AUTOFMT(50)
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_ANNOTATION(60)
constexpr TypedWhichId< SwFormatContentControl > RES_TXTATR_CONTENTCONTROL(56)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
constexpr TypedWhichId< SwFormatCharFormat > RES_TXTATR_CHARFMT(52)
constexpr TypedWhichId< SwFormatFlyCnt > RES_TXTATR_FLYCNT(58)
constexpr TypedWhichId< SwFormatLineBreak > RES_TXTATR_LINEBREAK(61)
constexpr TypedWhichId< SwFormatMeta > RES_TXTATR_METAFIELD(49)
constexpr TypedWhichId< SwFormatRefMark > RES_TXTATR_REFMARK(RES_TXTATR_WITHEND_BEGIN)
constexpr TypedWhichId< SwFormatMeta > RES_TXTATR_META(48)
constexpr TypedWhichId< SwTOXMark > RES_TXTATR_TOXMARK(47)
constexpr TypedWhichId< SwFormatRuby > RES_TXTATR_CJK_RUBY(53)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_INPUTFIELD(55)
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:181
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:179
sal_Int32 nIndex
#define SAL_WARN(area, stream)
void SelectPam(SwPaM &rPam, const bool bExpand)
Definition: unoobj.cxx:116
double getLength(const B2DPolygon &rCandidate)
sal_Int64 getSomethingImpl(const css::uno::Sequence< sal_Int8 > &rId, T *pThis, FallbackToGetSomethingOf< Base >={})
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Count
SwContentNode * GetNode(SwPaM &rPam, bool &rbFirst, SwMoveFnCollection const &fnMove, bool const bInReadOnly, SwRootFrame const *const i_pLayout)
This function returns the next node in direction of search.
Definition: pam.cxx:1019
QPRO_FUNC_TYPE nType
Marks a position in the document model.
Definition: pam.hxx:37
SwNode & GetNode() const
Definition: pam.hxx:80
void SetContent(sal_Int32 nContentIndex)
Set content index, only valid to call this if the position points to a SwContentNode subclass.
Definition: pam.cxx:266
sal_Int32 GetContentIndex() const
Definition: pam.hxx:84
unsigned char sal_Bool
sal_uInt16 sal_Unicode
std::deque< css::uno::Reference< css::text::XTextRange > > TextRangeList_t
std::deque< FrameClientSortListEntry > FrameClientSortList_t
void CollectFrameAtNode(const SwNode &rNd, FrameClientSortList_t &rFrames, const bool bAtCharAnchoredObjs)
Definition: unoobj2.cxx:136
@ PORTION_TOXMARK_END
Definition: unoport.hxx:63
@ PORTION_TEXT
Definition: unoport.hxx:56
@ PORTION_FIELD_SEP
Definition: unoport.hxx:73
@ PORTION_ANNOTATION
Definition: unoport.hxx:76
@ PORTION_BOOKMARK_START
Definition: unoport.hxx:64
@ PORTION_CONTENT_CONTROL
Definition: unoport.hxx:79
@ PORTION_FIELD_END
Definition: unoport.hxx:74
@ PORTION_META
Definition: unoport.hxx:71
@ PORTION_REFMARK_START
Definition: unoport.hxx:60
@ PORTION_BOOKMARK_END
Definition: unoport.hxx:65
@ PORTION_FIELD
Definition: unoport.hxx:57
@ PORTION_TOXMARK_START
Definition: unoport.hxx:62
@ PORTION_SOFT_PAGEBREAK
Definition: unoport.hxx:70
@ PORTION_FIELD_START_END
Definition: unoport.hxx:75
@ PORTION_ANNOTATION_END
Definition: unoport.hxx:77
@ PORTION_FRAME
Definition: unoport.hxx:58
@ PORTION_LINEBREAK
Definition: unoport.hxx:78
@ PORTION_FOOTNOTE
Definition: unoport.hxx:59
@ PORTION_REFMARK_END
Definition: unoport.hxx:61
@ PORTION_FIELD_START
Definition: unoport.hxx:72
static void lcl_FillSoftPageBreakArray(SwUnoCursor const &rUnoCursor, SwSoftPageBreakList &rBreakArr)
static void lcl_MoveCursor(SwUnoCursor *const pUnoCursor, const sal_Int32 nCurrentIndex, const sal_Int32 nNextFrameIndex, const sal_Int32 nNextPortionIndex, const sal_Int32 nNextAttrIndex, const sal_Int32 nNextMarkIndex, const sal_Int32 nEndPos)
std::multiset< SwXRedlinePortion_ImplSharedPtr, RedlineCompareStruct > SwXRedlinePortion_ImplList
static void lcl_FillRedlineArray(SwDoc const &rDoc, SwUnoCursor const &rUnoCursor, SwXRedlinePortion_ImplList &rRedArr)
static Reference< XTextRange > lcl_CreateTOXMarkPortion(Reference< XText > const &xParent, const SwUnoCursor *const pUnoCursor, SwTextAttr &rAttr, const bool bEnd)
static uno::Reference< text::XTextRange > lcl_CreateContentControlPortion(const uno::Reference< text::XText > &xParent, const SwUnoCursor *pUnoCursor, SwTextAttr &rAttr, std::unique_ptr< const TextRangeList_t > &&pPortions)
Creates a text portion that has a non-empty ContentControl property.
static void lcl_ExtractFramePositions(FrameClientSortList_t &rFrames, sal_Int32 nCurrentIndex, o3tl::sorted_vector< sal_Int32 > &rFramePositions)
Fills character positions from rFrames into rFramePositions.
static void lcl_FillFieldMarkArray(std::deque< sal_Int32 > &rFieldMarks, SwUnoCursor const &rUnoCursor, const sal_Int32 i_nStartPos)
static uno::Reference< text::XTextRange > lcl_ExportFieldMark(uno::Reference< text::XText > const &i_xParentText, SwUnoCursor *const pUnoCursor, const SwTextNode *const pTextNode)
std::pair< TextRangeList_t *const, SwTextAttr const *const > PortionList_t
Definition: unoportenum.cxx:73
static void lcl_ExportAnnotationStarts(TextRangeList_t &rPortions, Reference< XText > const &xParent, const SwUnoCursor *const pUnoCursor, SwAnnotationStartPortion_ImplList &rAnnotationStartArr, const sal_Int32 nIndex, const o3tl::sorted_vector< sal_Int32 > &rFramePositions, bool bOnlyFrame)
Exports all start annotation marks from rAnnotationStartArr into rPortions that have the same start p...
static Reference< XTextRange > lcl_CreateRefMarkPortion(Reference< XText > const &xParent, const SwUnoCursor *const pUnoCursor, const SwTextAttr &rAttr, const bool bEnd)
static Reference< XTextRange > lcl_ExportHints(PortionStack_t &rPortionStack, const Reference< XText > &xParent, SwUnoCursor *const pUnoCursor, SwpHints const *const pHints, const sal_Int32 i_nStartPos, const sal_Int32 i_nEndPos, const sal_Int32 nCurrentIndex, const bool bRightMoveForbidden, bool &o_rbCursorMoved, sal_Int32 &o_rNextAttrPosition)
static void lcl_ExportRedline(TextRangeList_t &rPortions, Reference< XText > const &xParent, const SwUnoCursor *const pUnoCursor, SwXRedlinePortion_ImplList &rRedlineArr, const sal_Int32 nIndex)
static void lcl_ExportSoftPageBreak(TextRangeList_t &rPortions, Reference< XText > const &xParent, const SwUnoCursor *const pUnoCursor, SwSoftPageBreakList &rBreakArr, const sal_Int32 nIndex)
static void lcl_ExportBookmark(TextRangeList_t &rPortions, Reference< XText > const &xParent, const SwUnoCursor *const pUnoCursor, SwXBookmarkPortion_ImplList &rBkmArr, const sal_Int32 nIndex, const o3tl::sorted_vector< sal_Int32 > &rFramePositions, bool bOnlyFrameStarts)
Exports all bookmarks from rBkmArr into rPortions that have the same start or end position as nIndex.
static sal_Int32 lcl_GetNextIndex(SwXBookmarkPortion_ImplList const &rBkmArr, SwXRedlinePortion_ImplList const &rRedlineArr, SwSoftPageBreakList const &rBreakArr)
static void lcl_InsertRubyPortion(TextRangeList_t &rPortions, Reference< XText > const &xParent, const SwUnoCursor *const pUnoCursor, const SwTextAttr &rAttr, const bool bEnd)
std::shared_ptr< SwXRedlinePortion_Impl > SwXRedlinePortion_ImplSharedPtr
static uno::Reference< text::XTextRange > lcl_CreateMetaPortion(uno::Reference< text::XText > const &xParent, const SwUnoCursor *const pUnoCursor, SwTextAttr &rAttr, std::unique_ptr< TextRangeList_t const > &&pPortions)
std::stack< PortionList_t > PortionStack_t
Definition: unoportenum.cxx:74
static void lcl_ExportBkmAndRedline(TextRangeList_t &rPortions, Reference< XText > const &xParent, const SwUnoCursor *const pUnoCursor, SwXBookmarkPortion_ImplList &rBkmArr, SwXRedlinePortion_ImplList &rRedlineArr, SwSoftPageBreakList &rBreakArr, const sal_Int32 nIndex, const o3tl::sorted_vector< sal_Int32 > &rFramePositions, bool bOnlyFrameBookmarkStarts)
static sal_Int32 lcl_ExportFrames(TextRangeList_t &rPortions, Reference< XText > const &i_xParent, SwUnoCursor const *const i_pUnoCursor, FrameClientSortList_t &i_rFrames, sal_Int32 const i_nCurrentIndex)
Exports at-char anchored frames.
static void lcl_CreatePortions(TextRangeList_t &i_rPortions, uno::Reference< text::XText > const &i_xParentText, SwUnoCursor *pUnoCursor, FrameClientSortList_t &i_rFrames, const sal_Int32 i_nStartPos, const sal_Int32 i_nEndPos, bool bOnlyTextFields)
size_t pos