LibreOffice Module sw (master)  1
unotext.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 <stdlib.h>
21 
22 #include <memory>
23 #include <set>
24 
25 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
26 #include <com/sun/star/text/ControlCharacter.hpp>
27 #include <com/sun/star/text/TableColumnSeparator.hpp>
28 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
29 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
30 
31 #include <svl/listener.hxx>
32 #include <vcl/svapp.hxx>
34 #include <comphelper/sequence.hxx>
36 #include <cppuhelper/exc_hlp.hxx>
38 #include <sal/log.hxx>
39 #include <tools/diagnose_ex.h>
40 
41 #include <cmdid.h>
42 #include <unotextbodyhf.hxx>
43 #include <unotext.hxx>
44 #include <unotextrange.hxx>
45 #include <unotextcursor.hxx>
46 #include <unosection.hxx>
47 #include <unobookmark.hxx>
48 #include <unorefmark.hxx>
49 #include <unoport.hxx>
50 #include <unotbl.hxx>
51 #include <unoidx.hxx>
52 #include <unocoll.hxx>
53 #include <unoframe.hxx>
54 #include <unofield.hxx>
55 #include <unometa.hxx>
56 #include <unomap.hxx>
57 #include <unoprnms.hxx>
58 #include <unoparagraph.hxx>
59 #include <unocrsrhelper.hxx>
60 #include <docary.hxx>
61 #include <doc.hxx>
63 #include <IDocumentUndoRedo.hxx>
64 #include <redline.hxx>
65 #include <swundo.hxx>
66 #include <section.hxx>
67 #include <fmtanchr.hxx>
68 #include <fmtcntnt.hxx>
69 #include <ndtxt.hxx>
70 #include <SwRewriter.hxx>
71 #include <strings.hrc>
72 #include <frameformats.hxx>
73 
74 using namespace ::com::sun::star;
75 
76 constexpr OUStringLiteral cInvalidObject = u"this object is invalid";
77 
79 {
80 
81 public:
86  bool m_bIsValid;
87 
88  Impl( SwXText & rThis,
89  SwDoc *const pDoc, const CursorType eType)
90  : m_rThis(rThis)
91  , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT))
92  , m_eType(eType)
93  , m_pDoc(pDoc)
94  , m_bIsValid(nullptr != pDoc)
95  {
96  }
97 
100  uno::Reference< text::XTextRange >
102  const uno::Sequence< beans::PropertyValue >&
103  rCharacterAndParagraphProperties,
104  const uno::Reference< text::XTextRange >& xInsertPosition);
105 
108  sal_Int16 ComparePositions(
109  const uno::Reference<text::XTextRange>& xPos1,
110  const uno::Reference<text::XTextRange>& xPos2);
111 
114  bool CheckForOwnMember(const SwPaM & rPaM);
115 
116  void ConvertCell(
117  const uno::Sequence< uno::Reference< text::XTextRange > > & rCell,
118  std::vector<SwNodeRange> & rRowNodes,
119  SwNodeRange *const pLastCell);
120 
121 };
122 
123 SwXText::SwXText(SwDoc *const pDoc, const CursorType eType)
124  : m_pImpl( new SwXText::Impl(*this, pDoc, eType) )
125 {
126 }
127 
129 {
130 }
131 
132 const SwDoc * SwXText::GetDoc() const
133 {
134  return m_pImpl->m_pDoc;
135 }
136 
138 {
139  return m_pImpl->m_pDoc;
140 }
141 
142 bool SwXText::IsValid() const
143 {
144  return m_pImpl->m_bIsValid;
145 }
146 
148 {
149  m_pImpl->m_bIsValid = false;
150 }
151 
152 void SwXText::SetDoc(SwDoc *const pDoc)
153 {
154  OSL_ENSURE(!m_pImpl->m_pDoc || !pDoc,
155  "SwXText::SetDoc: already have a doc?");
156  m_pImpl->m_pDoc = pDoc;
157  m_pImpl->m_bIsValid = (nullptr != pDoc);
158 }
159 
160 void
161 SwXText::PrepareForAttach(uno::Reference< text::XTextRange > &, const SwPaM &)
162 {
163 }
164 
165 bool SwXText::CheckForOwnMemberMeta(const SwPaM &, const bool)
166 {
167  OSL_ENSURE(CursorType::Meta != m_pImpl->m_eType, "should not be called!");
168  return false;
169 }
170 
172 {
174 }
175 
176 uno::Reference< text::XTextCursor >
178 {
179  uno::Reference< text::XTextCursor > xRet;
180  if(IsValid())
181  {
182  SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
183  SwPosition aPos(rNode);
184  xRet = static_cast<text::XWordCursor*>(
185  new SwXTextCursor(*GetDoc(), this, m_pImpl->m_eType, aPos));
186  xRet->gotoStart(false);
187  }
188  return xRet;
189 }
190 
191 uno::Any SAL_CALL
193 {
194  uno::Any aRet;
195  if (rType == cppu::UnoType<text::XText>::get())
196  {
197  aRet <<= uno::Reference< text::XText >(this);
198  }
199  else if (rType == cppu::UnoType<text::XSimpleText>::get())
200  {
201  aRet <<= uno::Reference< text::XSimpleText >(this);
202  }
203  else if (rType == cppu::UnoType<text::XTextRange>::get())
204  {
205  aRet <<= uno::Reference< text::XTextRange>(this);
206  }
208  {
209  aRet <<= uno::Reference< text::XTextRangeCompare >(this);
210  }
211  else if (rType == cppu::UnoType<lang::XTypeProvider>::get())
212  {
213  aRet <<= uno::Reference< lang::XTypeProvider >(this);
214  }
216  {
217  aRet <<= uno::Reference< text::XRelativeTextContentInsert >(this);
218  }
220  {
221  aRet <<= uno::Reference< text::XRelativeTextContentRemove >(this);
222  }
223  else if (rType == cppu::UnoType<beans::XPropertySet>::get())
224  {
225  aRet <<= uno::Reference< beans::XPropertySet >(this);
226  }
227  else if (rType == cppu::UnoType<lang::XUnoTunnel>::get())
228  {
229  aRet <<= uno::Reference< lang::XUnoTunnel >(this);
230  }
232  {
233  aRet <<= uno::Reference< text::XTextAppendAndConvert >(this);
234  }
235  else if (rType == cppu::UnoType<text::XTextAppend>::get())
236  {
237  aRet <<= uno::Reference< text::XTextAppend >(this);
238  }
240  {
241  aRet <<= uno::Reference< text::XTextPortionAppend >(this);
242  }
243  else if (rType == cppu::UnoType<text::XParagraphAppend>::get())
244  {
245  aRet <<= uno::Reference< text::XParagraphAppend >(this);
246  }
247  else if (rType == cppu::UnoType<text::XTextConvert>::get() )
248  {
249  aRet <<= uno::Reference< text::XTextConvert >(this);
250  }
252  {
253  aRet <<= uno::Reference< text::XTextContentAppend >(this);
254  }
255  else if(rType == cppu::UnoType<text::XTextCopy>::get())
256  {
257  aRet <<= uno::Reference< text::XTextCopy >( this );
258  }
259  return aRet;
260 }
261 
262 uno::Sequence< uno::Type > SAL_CALL
264 {
265  static const uno::Sequence< uno::Type > aTypes {
278  };
279  return aTypes;
280 }
281 
282 // belongs the range in the text ? insert it then.
283 void SAL_CALL
284 SwXText::insertString(const uno::Reference< text::XTextRange >& xTextRange,
285  const OUString& rString, sal_Bool bAbsorb)
286 {
287  SolarMutexGuard aGuard;
288  comphelper::ProfileZone aZone("SwXText::insertString");
289 
290  if (!xTextRange.is())
291  {
292  throw uno::RuntimeException();
293  }
294  if (!GetDoc())
295  {
296  throw uno::RuntimeException();
297  }
298  const uno::Reference<lang::XUnoTunnel> xRangeTunnel(xTextRange,
299  uno::UNO_QUERY);
300  SwXTextRange *const pRange =
301  comphelper::getFromUnoTunnel<SwXTextRange>(xRangeTunnel);
302  OTextCursorHelper *const pCursor =
303  comphelper::getFromUnoTunnel<OTextCursorHelper>(xRangeTunnel);
304  if ((!pRange || &pRange ->GetDoc() != GetDoc()) &&
305  (!pCursor || pCursor->GetDoc() != GetDoc()))
306  {
307  throw uno::RuntimeException();
308  }
309 
310  const SwStartNode *const pOwnStartNode = GetStartNode();
311  SwPaM aPam(GetDoc()->GetNodes());
312  const SwPaM * pPam(nullptr);
313  if (pCursor)
314  {
315  pPam = pCursor->GetPaM();
316  }
317  else // pRange
318  {
319  if (pRange->GetPositions(aPam))
320  {
321  pPam = &aPam;
322  }
323  }
324  if (!pPam)
325  {
326  throw uno::RuntimeException();
327  }
328 
329  const SwStartNode* pTmp(pPam->GetNode().StartOfSectionNode());
330  while (pTmp && pTmp->IsSectionNode())
331  {
332  pTmp = pTmp->StartOfSectionNode();
333  }
334  if (!pOwnStartNode || (pOwnStartNode != pTmp))
335  {
336  throw uno::RuntimeException();
337  }
338 
339  bool bForceExpandHints( false );
340  if (CursorType::Meta == m_pImpl->m_eType)
341  {
342  try
343  {
344  bForceExpandHints = CheckForOwnMemberMeta(*pPam, bAbsorb);
345  }
346  catch (const lang::IllegalArgumentException& iae)
347  {
348  // stupid method not allowed to throw iae
349  css::uno::Any anyEx = cppu::getCaughtException();
350  throw lang::WrappedTargetRuntimeException( iae.Message,
351  uno::Reference< uno::XInterface >(), anyEx );
352  }
353  }
354  if (bAbsorb)
355  {
359  if (pCursor)
360  {
361  SwXTextCursor * const pTextCursor(
362  dynamic_cast<SwXTextCursor*>(pCursor) );
363  if (pTextCursor)
364  {
365  pTextCursor->DeleteAndInsert(rString, bForceExpandHints);
366  }
367  else
368  {
369  xTextRange->setString(rString);
370  }
371  }
372  else
373  {
374  pRange->DeleteAndInsert(rString, bForceExpandHints);
375  }
376  }
377  else
378  {
379  // create a PaM positioned before the parameter PaM,
380  // so the text is inserted before
381  UnoActionContext aContext(GetDoc());
382  SwPaM aInsertPam(*pPam->Start());
383  ::sw::GroupUndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
385  *GetDoc(), aInsertPam, rString, bForceExpandHints );
386  }
387 }
388 
389 void SAL_CALL
391  const uno::Reference< text::XTextRange > & xTextRange,
392  sal_Int16 nControlCharacter, sal_Bool bAbsorb)
393 {
394  SolarMutexGuard aGuard;
395 
396  if (!xTextRange.is())
397  {
398  throw lang::IllegalArgumentException();
399  }
400  if (!GetDoc())
401  {
402  throw uno::RuntimeException();
403  }
404 
405  SwUnoInternalPaM aPam(*GetDoc());
406  if (!::sw::XTextRangeToSwPaM(aPam, xTextRange))
407  {
408  throw uno::RuntimeException();
409  }
410  const bool bForceExpandHints(CheckForOwnMemberMeta(aPam, bAbsorb));
411 
412  const SwInsertFlags nInsertFlags =
413  bForceExpandHints
416 
417  if (bAbsorb && aPam.HasMark())
418  {
419  m_pImpl->m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aPam);
420  aPam.DeleteMark();
421  }
422 
423  sal_Unicode cIns = 0;
424  switch (nControlCharacter)
425  {
426  case text::ControlCharacter::PARAGRAPH_BREAK :
427  // a table cell now becomes an ordinary text cell!
428  m_pImpl->m_pDoc->ClearBoxNumAttrs(aPam.GetPoint()->nNode);
429  m_pImpl->m_pDoc->getIDocumentContentOperations().SplitNode(*aPam.GetPoint(), false);
430  break;
431  case text::ControlCharacter::APPEND_PARAGRAPH:
432  {
433  m_pImpl->m_pDoc->ClearBoxNumAttrs(aPam.GetPoint()->nNode);
434  m_pImpl->m_pDoc->getIDocumentContentOperations().AppendTextNode(*aPam.GetPoint());
435 
436  const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
437  xTextRange, uno::UNO_QUERY);
438  SwXTextRange *const pRange =
439  comphelper::getFromUnoTunnel<SwXTextRange>(xRangeTunnel);
440  OTextCursorHelper *const pCursor =
441  comphelper::getFromUnoTunnel<OTextCursorHelper>(
442  xRangeTunnel);
443  if (pRange)
444  {
445  pRange->SetPositions(aPam);
446  }
447  else if (pCursor)
448  {
449  SwPaM *const pCursorPam = pCursor->GetPaM();
450  *pCursorPam->GetPoint() = *aPam.GetPoint();
451  pCursorPam->DeleteMark();
452  }
453  }
454  break;
455  case text::ControlCharacter::LINE_BREAK: cIns = 10; break;
456  case text::ControlCharacter::SOFT_HYPHEN: cIns = CHAR_SOFTHYPHEN; break;
457  case text::ControlCharacter::HARD_HYPHEN: cIns = CHAR_HARDHYPHEN; break;
458  case text::ControlCharacter::HARD_SPACE: cIns = CHAR_HARDBLANK; break;
459  }
460  if (cIns)
461  {
462  m_pImpl->m_pDoc->getIDocumentContentOperations().InsertString(
463  aPam, OUString(cIns), nInsertFlags);
464  }
465 
466  if (!bAbsorb)
467  return;
468 
469  const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
470  xTextRange, uno::UNO_QUERY);
471  SwXTextRange *const pRange =
472  comphelper::getFromUnoTunnel<SwXTextRange>(xRangeTunnel);
473  OTextCursorHelper *const pCursor =
474  comphelper::getFromUnoTunnel<OTextCursorHelper>(xRangeTunnel);
475 
476  SwCursor aCursor(*aPam.GetPoint(), nullptr);
477  SwUnoCursorHelper::SelectPam(aCursor, true);
478  aCursor.Left(1);
479  // here, the PaM needs to be moved:
480  if (pRange)
481  {
482  pRange->SetPositions(aCursor);
483  }
484  else
485  {
486  SwPaM *const pUnoCursor = pCursor->GetPaM();
487  *pUnoCursor->GetPoint() = *aCursor.GetPoint();
488  if (aCursor.HasMark())
489  {
490  pUnoCursor->SetMark();
491  *pUnoCursor->GetMark() = *aCursor.GetMark();
492  }
493  else
494  {
495  pUnoCursor->DeleteMark();
496  }
497  }
498 }
499 
500 void SAL_CALL
502  const uno::Reference< text::XTextRange > & xRange,
503  const uno::Reference< text::XTextContent > & xContent,
504  sal_Bool bAbsorb)
505 {
506  SolarMutexGuard aGuard;
507  comphelper::ProfileZone aZone("SwXText::insertTextContent");
508 
509  if (!xRange.is())
510  {
511  lang::IllegalArgumentException aIllegal;
512  aIllegal.Message = "first parameter invalid;";
513  throw aIllegal;
514  }
515  if (!xContent.is())
516  {
517  lang::IllegalArgumentException aIllegal;
518  aIllegal.Message = "second parameter invalid";
519  throw aIllegal;
520  }
521  if(!GetDoc())
522  {
523  uno::RuntimeException aRuntime;
524  aRuntime.Message = cInvalidObject;
525  throw aRuntime;
526  }
527 
528  SwUnoInternalPaM aPam(*GetDoc());
529  if (!::sw::XTextRangeToSwPaM(aPam, xRange))
530  {
531  lang::IllegalArgumentException aIllegal;
532  aIllegal.Message = "first parameter invalid";
533  throw aIllegal;
534  }
535 
536  // first test if the range is at the right position, then call
537  // xContent->attach
538  const SwStartNode* pOwnStartNode = GetStartNode();
539  SwStartNodeType eSearchNodeType = SwNormalStartNode;
540  switch (m_pImpl->m_eType)
541  {
542  case CursorType::Frame: eSearchNodeType = SwFlyStartNode; break;
543  case CursorType::TableText: eSearchNodeType = SwTableBoxStartNode; break;
544  case CursorType::Footnote: eSearchNodeType = SwFootnoteStartNode; break;
545  case CursorType::Header: eSearchNodeType = SwHeaderStartNode; break;
546  case CursorType::Footer: eSearchNodeType = SwFooterStartNode; break;
547  //case CURSOR_INVALID:
548  //case CursorType::Body:
549  default:
550  break;
551  }
552 
553  const SwStartNode* pTmp =
554  aPam.GetNode().FindSttNodeByType(eSearchNodeType);
555 
556  // ignore SectionNodes
557  while (pTmp && pTmp->IsSectionNode())
558  {
559  pTmp = pTmp->StartOfSectionNode();
560  }
561  // if the document starts with a section
562  while (pOwnStartNode && pOwnStartNode->IsSectionNode())
563  {
564  pOwnStartNode = pOwnStartNode->StartOfSectionNode();
565  }
566  // this checks if (this) and xRange are in the same text::XText interface
567  if (pOwnStartNode != pTmp)
568  {
569  uno::RuntimeException aRunException;
570  aRunException.Message = "text interface and cursor not related";
571  throw aRunException;
572  }
573 
574  const bool bForceExpandHints(CheckForOwnMemberMeta(aPam, bAbsorb));
575 
576  // special treatment for Contents that do not replace the range, but
577  // instead are "overlaid"
578  const uno::Reference<lang::XUnoTunnel> xContentTunnel(xContent,
579  uno::UNO_QUERY);
580  if (!xContentTunnel.is())
581  {
582  lang::IllegalArgumentException aArgException;
583  aArgException.Message = "text content does not support lang::XUnoTunnel";
584  throw aArgException;
585  }
586  SwXDocumentIndexMark *const pDocumentIndexMark =
587  comphelper::getFromUnoTunnel<SwXDocumentIndexMark>(xContentTunnel);
588  SwXTextSection *const pSection =
589  comphelper::getFromUnoTunnel<SwXTextSection>(xContentTunnel);
590  SwXBookmark *const pBookmark =
591  comphelper::getFromUnoTunnel<SwXBookmark>(xContentTunnel);
592  SwXReferenceMark *const pReferenceMark =
593  comphelper::getFromUnoTunnel<SwXReferenceMark>(xContentTunnel);
594  SwXMeta *const pMeta =
595  comphelper::getFromUnoTunnel<SwXMeta>(xContentTunnel);
596  SwXTextField* pTextField =
597  comphelper::getFromUnoTunnel<SwXTextField>(xContentTunnel);
598  if (pTextField && pTextField->GetServiceId() != SwServiceType::FieldTypeAnnotation)
599  pTextField = nullptr;
600 
601  const bool bAttribute = pBookmark || pDocumentIndexMark
602  || pSection || pReferenceMark || pMeta || pTextField;
603 
604  if (bAbsorb && !bAttribute)
605  {
606  xRange->setString(OUString());
607  }
608  uno::Reference< text::XTextRange > xTempRange =
609  (bAttribute && bAbsorb) ? xRange : xRange->getStart();
610  if (bForceExpandHints)
611  {
612  // if necessary, replace xTempRange with a new SwXTextCursor
613  PrepareForAttach(xTempRange, aPam);
614  }
615  xContent->attach(xTempRange);
616 }
617 
618 void SAL_CALL
620  const uno::Reference< text::XTextContent>& xNewContent,
621  const uno::Reference< text::XTextContent>& xSuccessor)
622 {
623  SolarMutexGuard aGuard;
624 
625  if(!GetDoc())
626  {
627  uno::RuntimeException aRuntime;
628  aRuntime.Message = cInvalidObject;
629  throw aRuntime;
630  }
631 
632  SwXParagraph *const pPara =
633  comphelper::getFromUnoTunnel<SwXParagraph>(xNewContent);
634  if (!pPara || !pPara->IsDescriptor() || !xSuccessor.is())
635  {
636  throw lang::IllegalArgumentException();
637  }
638 
639  bool bRet = false;
640  const uno::Reference<lang::XUnoTunnel> xSuccTunnel(xSuccessor,
641  uno::UNO_QUERY);
642  SwXTextSection *const pXSection =
643  comphelper::getFromUnoTunnel<SwXTextSection>(xSuccTunnel);
644  SwXTextTable *const pXTable =
645  comphelper::getFromUnoTunnel<SwXTextTable>(xSuccTunnel);
646  SwFrameFormat *const pTableFormat = pXTable ? pXTable->GetFrameFormat() : nullptr;
647  SwTextNode * pTextNode = nullptr;
648  if(pTableFormat && pTableFormat->GetDoc() == GetDoc())
649  {
650  SwTable *const pTable = SwTable::FindTable( pTableFormat );
651  SwTableNode *const pTableNode = pTable->GetTableNode();
652 
653  const SwNodeIndex aTableIdx( *pTableNode, -1 );
654  SwPosition aBefore(aTableIdx);
655  bRet = GetDoc()->getIDocumentContentOperations().AppendTextNode( aBefore );
656  pTextNode = aBefore.nNode.GetNode().GetTextNode();
657  }
658  else if (pXSection && pXSection->GetFormat() &&
659  pXSection->GetFormat()->GetDoc() == GetDoc())
660  {
661  SwSectionFormat *const pSectFormat = pXSection->GetFormat();
662  SwSectionNode *const pSectNode = pSectFormat->GetSectionNode();
663 
664  const SwNodeIndex aSectIdx( *pSectNode, -1 );
665  SwPosition aBefore(aSectIdx);
666  bRet = GetDoc()->getIDocumentContentOperations().AppendTextNode( aBefore );
667  pTextNode = aBefore.nNode.GetNode().GetTextNode();
668  }
669  if (!bRet || !pTextNode)
670  {
671  throw lang::IllegalArgumentException();
672  }
673  pPara->attachToText(*this, *pTextNode);
674 }
675 
676 void SAL_CALL
678  const uno::Reference< text::XTextContent>& xNewContent,
679  const uno::Reference< text::XTextContent>& xPredecessor)
680 {
681  SolarMutexGuard aGuard;
682 
683  if(!GetDoc())
684  {
685  throw uno::RuntimeException();
686  }
687 
688  SwXParagraph *const pPara =
689  comphelper::getFromUnoTunnel<SwXParagraph>(xNewContent);
690  if(!pPara || !pPara->IsDescriptor() || !xPredecessor.is())
691  {
692  throw lang::IllegalArgumentException();
693  }
694 
695  const uno::Reference<lang::XUnoTunnel> xPredTunnel(xPredecessor,
696  uno::UNO_QUERY);
697  SwXTextSection *const pXSection =
698  comphelper::getFromUnoTunnel<SwXTextSection>(xPredTunnel);
699  SwXTextTable *const pXTable =
700  comphelper::getFromUnoTunnel<SwXTextTable>(xPredTunnel);
701  SwFrameFormat *const pTableFormat = pXTable ? pXTable->GetFrameFormat() : nullptr;
702  bool bRet = false;
703  SwTextNode * pTextNode = nullptr;
704  if(pTableFormat && pTableFormat->GetDoc() == GetDoc())
705  {
706  SwTable *const pTable = SwTable::FindTable( pTableFormat );
707  SwTableNode *const pTableNode = pTable->GetTableNode();
708 
709  SwEndNode *const pTableEnd = pTableNode->EndOfSectionNode();
710  SwPosition aTableEnd(*pTableEnd);
711  bRet = GetDoc()->getIDocumentContentOperations().AppendTextNode( aTableEnd );
712  pTextNode = aTableEnd.nNode.GetNode().GetTextNode();
713  }
714  else if (pXSection && pXSection->GetFormat() &&
715  pXSection->GetFormat()->GetDoc() == GetDoc())
716  {
717  SwSectionFormat *const pSectFormat = pXSection->GetFormat();
718  SwSectionNode *const pSectNode = pSectFormat->GetSectionNode();
719  SwEndNode *const pEnd = pSectNode->EndOfSectionNode();
720  SwPosition aEnd(*pEnd);
722  pTextNode = aEnd.nNode.GetNode().GetTextNode();
723  }
724  if (!bRet || !pTextNode)
725  {
726  throw lang::IllegalArgumentException();
727  }
728  pPara->attachToText(*this, *pTextNode);
729 }
730 
731 void SAL_CALL
733  const uno::Reference< text::XTextContent>& xSuccessor)
734 {
735  SolarMutexGuard aGuard;
736 
737  if(!GetDoc())
738  {
739  uno::RuntimeException aRuntime;
740  aRuntime.Message = cInvalidObject;
741  throw aRuntime;
742  }
743 
744  bool bRet = false;
745  const uno::Reference<lang::XUnoTunnel> xSuccTunnel(xSuccessor,
746  uno::UNO_QUERY);
747  SwXTextSection *const pXSection =
748  comphelper::getFromUnoTunnel<SwXTextSection>(xSuccTunnel);
749  SwXTextTable *const pXTable =
750  comphelper::getFromUnoTunnel<SwXTextTable>(xSuccTunnel);
751  SwFrameFormat *const pTableFormat = pXTable ? pXTable->GetFrameFormat() : nullptr;
752  if(pTableFormat && pTableFormat->GetDoc() == GetDoc())
753  {
754  SwTable *const pTable = SwTable::FindTable( pTableFormat );
755  SwTableNode *const pTableNode = pTable->GetTableNode();
756 
757  const SwNodeIndex aTableIdx( *pTableNode, -1 );
758  if(aTableIdx.GetNode().IsTextNode())
759  {
760  SwPaM aBefore(aTableIdx);
761  bRet = GetDoc()->getIDocumentContentOperations().DelFullPara( aBefore );
762  }
763  }
764  else if (pXSection && pXSection->GetFormat() &&
765  pXSection->GetFormat()->GetDoc() == GetDoc())
766  {
767  SwSectionFormat *const pSectFormat = pXSection->GetFormat();
768  SwSectionNode *const pSectNode = pSectFormat->GetSectionNode();
769 
770  const SwNodeIndex aSectIdx( *pSectNode, -1 );
771  if(aSectIdx.GetNode().IsTextNode())
772  {
773  SwPaM aBefore(aSectIdx);
774  bRet = GetDoc()->getIDocumentContentOperations().DelFullPara( aBefore );
775  }
776  }
777  if(!bRet)
778  {
779  throw lang::IllegalArgumentException();
780  }
781 }
782 
783 void SAL_CALL
785  const uno::Reference< text::XTextContent>& xPredecessor)
786 {
787  SolarMutexGuard aGuard;
788 
789  if(!GetDoc())
790  {
791  uno::RuntimeException aRuntime;
792  aRuntime.Message = cInvalidObject;
793  throw aRuntime;
794  }
795 
796  bool bRet = false;
797  const uno::Reference<lang::XUnoTunnel> xPredTunnel(xPredecessor,
798  uno::UNO_QUERY);
799  SwXTextSection *const pXSection =
800  comphelper::getFromUnoTunnel<SwXTextSection>(xPredTunnel);
801  SwXTextTable *const pXTable =
802  comphelper::getFromUnoTunnel<SwXTextTable>(xPredTunnel);
803  SwFrameFormat *const pTableFormat = pXTable ? pXTable->GetFrameFormat() : nullptr;
804  if(pTableFormat && pTableFormat->GetDoc() == GetDoc())
805  {
806  SwTable *const pTable = SwTable::FindTable( pTableFormat );
807  SwTableNode *const pTableNode = pTable->GetTableNode();
808  SwEndNode *const pTableEnd = pTableNode->EndOfSectionNode();
809 
810  const SwNodeIndex aTableIdx( *pTableEnd, 1 );
811  if(aTableIdx.GetNode().IsTextNode())
812  {
813  SwPaM aPaM(aTableIdx);
815  }
816  }
817  else if (pXSection && pXSection->GetFormat() &&
818  pXSection->GetFormat()->GetDoc() == GetDoc())
819  {
820  SwSectionFormat *const pSectFormat = pXSection->GetFormat();
821  SwSectionNode *const pSectNode = pSectFormat->GetSectionNode();
822  SwEndNode *const pEnd = pSectNode->EndOfSectionNode();
823  const SwNodeIndex aSectIdx( *pEnd, 1 );
824  if(aSectIdx.GetNode().IsTextNode())
825  {
826  SwPaM aAfter(aSectIdx);
827  bRet = GetDoc()->getIDocumentContentOperations().DelFullPara( aAfter );
828  }
829  }
830  if(!bRet)
831  {
832  throw lang::IllegalArgumentException();
833  }
834 }
835 
836 void SAL_CALL
838  const uno::Reference< text::XTextContent > & xContent)
839 {
840  // forward: need no solar mutex here
841  if(!xContent.is())
842  {
843  uno::RuntimeException aRuntime;
844  aRuntime.Message = "first parameter invalid";
845  throw aRuntime;
846  }
847  xContent->dispose();
848 }
849 
850 uno::Reference< text::XText > SAL_CALL
852 {
853  SolarMutexGuard aGuard;
854  comphelper::ProfileZone aZone("SwXText::getText");
855 
856  const uno::Reference< text::XText > xRet(this);
857  return xRet;
858 }
859 
860 uno::Reference< text::XTextRange > SAL_CALL
862 {
863  SolarMutexGuard aGuard;
864 
865  const uno::Reference< text::XTextCursor > xRef = CreateCursor();
866  if(!xRef.is())
867  {
868  uno::RuntimeException aRuntime;
869  aRuntime.Message = cInvalidObject;
870  throw aRuntime;
871  }
872  xRef->gotoStart(false);
873  return xRef;
874 }
875 
876 uno::Reference< text::XTextRange > SAL_CALL
878 {
879  SolarMutexGuard aGuard;
880 
881  const uno::Reference< text::XTextCursor > xRef = CreateCursor();
882  if(!xRef.is())
883  {
884  uno::RuntimeException aRuntime;
885  aRuntime.Message = cInvalidObject;
886  throw aRuntime;
887  }
888  xRef->gotoEnd(false);
889  return xRef;
890 }
891 
892 OUString SAL_CALL SwXText::getString()
893 {
894  SolarMutexGuard aGuard;
895 
896  const uno::Reference< text::XTextCursor > xRet = CreateCursor();
897  if(!xRet.is())
898  {
899  SAL_WARN("sw.uno", "cursor was not created in getString() call. Returning empty string.");
900  return OUString();
901  }
902  xRet->gotoEnd(true);
903  return xRet->getString();
904 }
905 
906 void SAL_CALL
907 SwXText::setString(const OUString& rString)
908 {
909  SolarMutexGuard aGuard;
910 
911  if (!GetDoc())
912  {
913  uno::RuntimeException aRuntime;
914  aRuntime.Message = cInvalidObject;
915  throw aRuntime;
916  }
917 
918  const SwStartNode* pStartNode = GetStartNode();
919  if (!pStartNode)
920  {
921  throw uno::RuntimeException();
922  }
923 
925  //insert an empty paragraph at the start and at the end to ensure that
926  //all tables and sections can be removed by the selecting text::XTextCursor
927  if (CursorType::Meta != m_pImpl->m_eType)
928  {
929  SwPosition aStartPos(*pStartNode);
930  const SwEndNode* pEnd = pStartNode->EndOfSectionNode();
931  SwNodeIndex aEndIdx(*pEnd);
932  --aEndIdx;
933  //the inserting of nodes should only be done if really necessary
934  //to prevent #97924# (removes paragraph attributes when setting the text
935  //e.g. of a table cell
936  bool bInsertNodes = false;
937  SwNodeIndex aStartIdx(*pStartNode);
938  do
939  {
940  ++aStartIdx;
941  SwNode& rCurrentNode = aStartIdx.GetNode();
942  if(rCurrentNode.GetNodeType() == SwNodeType::Section
943  ||rCurrentNode.GetNodeType() == SwNodeType::Table)
944  {
945  bInsertNodes = true;
946  break;
947  }
948  }
949  while(aStartIdx < aEndIdx);
950  if(bInsertNodes)
951  {
953  SwPosition aEndPos(aEndIdx.GetNode());
954  SwPaM aPam(aEndPos);
956  }
957  }
958 
959  const uno::Reference< text::XTextCursor > xRet = CreateCursor();
960  if(!xRet.is())
961  {
963  uno::RuntimeException aRuntime;
964  aRuntime.Message = cInvalidObject;
965  throw aRuntime;
966  }
967  xRet->gotoEnd(true);
968  xRet->setString(rString);
970 }
971 
972 //FIXME why is CheckForOwnMember duplicated in some insert methods?
973 // Description: Checks if pRange/pCursor are member of the same text interface.
974 // Only one of the pointers has to be set!
976  const SwPaM & rPaM)
977 {
978  const uno::Reference<text::XTextCursor> xOwnCursor(m_rThis.CreateCursor());
979 
980  OTextCursorHelper *const pOwnCursor =
981  comphelper::getFromUnoTunnel<OTextCursorHelper>(xOwnCursor);
982  OSL_ENSURE(pOwnCursor, "OTextCursorHelper::getUnoTunnelId() ??? ");
983  const SwStartNode* pOwnStartNode =
984  pOwnCursor->GetPaM()->GetNode().StartOfSectionNode();
985  SwStartNodeType eSearchNodeType = SwNormalStartNode;
986  switch (m_eType)
987  {
988  case CursorType::Frame: eSearchNodeType = SwFlyStartNode; break;
989  case CursorType::TableText: eSearchNodeType = SwTableBoxStartNode; break;
990  case CursorType::Footnote: eSearchNodeType = SwFootnoteStartNode; break;
991  case CursorType::Header: eSearchNodeType = SwHeaderStartNode; break;
992  case CursorType::Footer: eSearchNodeType = SwFooterStartNode; break;
993  //case CURSOR_INVALID:
994  //case CursorType::Body:
995  default:
996  ;
997  }
998 
999  const SwNode& rSrcNode = rPaM.GetNode();
1000  const SwStartNode* pTmp = rSrcNode.FindSttNodeByType(eSearchNodeType);
1001 
1002  // skip SectionNodes / TableNodes to be able to compare across table/section boundaries
1003  while (pTmp
1004  && (pTmp->IsSectionNode() || pTmp->IsTableNode()
1006  && pTmp->GetStartNodeType() == SwTableBoxStartNode)))
1007  {
1008  pTmp = pTmp->StartOfSectionNode();
1009  }
1010 
1011  while (pOwnStartNode->IsSectionNode() || pOwnStartNode->IsTableNode()
1013  && pOwnStartNode->GetStartNodeType() == SwTableBoxStartNode))
1014  {
1015  pOwnStartNode = pOwnStartNode->StartOfSectionNode();
1016  }
1017 
1018  //this checks if (this) and xRange are in the same text::XText interface
1019  return (pOwnStartNode == pTmp);
1020 }
1021 
1022 sal_Int16
1024  const uno::Reference<text::XTextRange>& xPos1,
1025  const uno::Reference<text::XTextRange>& xPos2)
1026 {
1027  SwUnoInternalPaM aPam1(*m_pDoc);
1028  SwUnoInternalPaM aPam2(*m_pDoc);
1029 
1030  if (!::sw::XTextRangeToSwPaM(aPam1, xPos1) ||
1031  !::sw::XTextRangeToSwPaM(aPam2, xPos2))
1032  {
1033  throw lang::IllegalArgumentException();
1034  }
1035  if (!CheckForOwnMember(aPam1) || !CheckForOwnMember(aPam2))
1036  {
1037  throw lang::IllegalArgumentException();
1038  }
1039 
1040  sal_Int16 nCompare = 0;
1041  SwPosition const*const pStart1 = aPam1.Start();
1042  SwPosition const*const pStart2 = aPam2.Start();
1043  if (*pStart1 < *pStart2)
1044  {
1045  nCompare = 1;
1046  }
1047  else if (*pStart1 > *pStart2)
1048  {
1049  nCompare = -1;
1050  }
1051  else
1052  {
1053  OSL_ENSURE(*pStart1 == *pStart2,
1054  "SwPositions should be equal here");
1055  nCompare = 0;
1056  }
1057 
1058  return nCompare;
1059 }
1060 
1061 sal_Int16 SAL_CALL
1063  const uno::Reference<text::XTextRange>& xRange1,
1064  const uno::Reference<text::XTextRange>& xRange2)
1065 {
1066  SolarMutexGuard aGuard;
1067 
1068  if (!xRange1.is() || !xRange2.is())
1069  {
1070  throw lang::IllegalArgumentException();
1071  }
1072  const uno::Reference<text::XTextRange> xStart1 = xRange1->getStart();
1073  const uno::Reference<text::XTextRange> xStart2 = xRange2->getStart();
1074 
1075  return m_pImpl->ComparePositions(xStart1, xStart2);
1076 }
1077 
1078 sal_Int16 SAL_CALL
1080  const uno::Reference<text::XTextRange>& xRange1,
1081  const uno::Reference<text::XTextRange>& xRange2)
1082 {
1083  SolarMutexGuard aGuard;
1084 
1085  if (!xRange1.is() || !xRange2.is())
1086  {
1087  throw lang::IllegalArgumentException();
1088  }
1089  uno::Reference<text::XTextRange> xEnd1 = xRange1->getEnd();
1090  uno::Reference<text::XTextRange> xEnd2 = xRange2->getEnd();
1091 
1092  return m_pImpl->ComparePositions(xEnd1, xEnd2);
1093 }
1094 
1095 uno::Reference< beans::XPropertySetInfo > SAL_CALL
1097 {
1098  SolarMutexGuard g;
1099 
1100  static uno::Reference< beans::XPropertySetInfo > xInfo =
1101  m_pImpl->m_rPropSet.getPropertySetInfo();
1102  return xInfo;
1103 }
1104 
1105 void SAL_CALL
1106 SwXText::setPropertyValue(const OUString& /*aPropertyName*/,
1107  const uno::Any& /*aValue*/)
1108 {
1109  throw lang::IllegalArgumentException();
1110 }
1111 
1112 uno::Any SAL_CALL
1114  const OUString& rPropertyName)
1115 {
1116  SolarMutexGuard aGuard;
1117 
1118  if(!IsValid())
1119  {
1120  throw uno::RuntimeException();
1121  }
1122 
1123  SfxItemPropertyMapEntry const*const pEntry =
1124  m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
1125  if (!pEntry)
1126  {
1127  beans::UnknownPropertyException aExcept;
1128  aExcept.Message = "Unknown property: " + rPropertyName;
1129  throw aExcept;
1130  }
1131 
1132  uno::Any aRet;
1133  switch (pEntry->nWID)
1134  {
1135 // no code necessary - the redline is always located at the end node
1136 // case FN_UNO_REDLINE_NODE_START:
1137 // break;
1139  {
1141  const size_t nRedTableCount = rRedTable.size();
1142  if (nRedTableCount > 0)
1143  {
1144  SwStartNode const*const pStartNode = GetStartNode();
1145  const SwNodeOffset nOwnIndex = pStartNode->EndOfSectionIndex();
1146  for (size_t nRed = 0; nRed < nRedTableCount; ++nRed)
1147  {
1148  SwRangeRedline const*const pRedline = rRedTable[nRed];
1149  SwPosition const*const pRedStart = pRedline->Start();
1150  const SwNodeIndex nRedNode = pRedStart->nNode;
1151  if (nOwnIndex == nRedNode.GetIndex())
1152  {
1154  *pRedline, true);
1155  break;
1156  }
1157  }
1158  }
1159  }
1160  break;
1161  }
1162  return aRet;
1163 }
1164 
1165 void SAL_CALL
1167  const OUString& /*rPropertyName*/,
1168  const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1169 {
1170  OSL_FAIL("SwXText::addPropertyChangeListener(): not implemented");
1171 }
1172 
1173 void SAL_CALL
1175  const OUString& /*rPropertyName*/,
1176  const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1177 {
1178  OSL_FAIL("SwXText::removePropertyChangeListener(): not implemented");
1179 }
1180 
1181 void SAL_CALL
1183  const OUString& /*rPropertyName*/,
1184  const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1185 {
1186  OSL_FAIL("SwXText::addVetoableChangeListener(): not implemented");
1187 }
1188 
1189 void SAL_CALL
1191  const OUString& /*rPropertyName*/,
1192  const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1193 {
1194  OSL_FAIL("SwXText::removeVetoableChangeListener(): not implemented");
1195 }
1196 
1197 namespace
1198 {
1199 }
1200 
1201 const uno::Sequence< sal_Int8 > & SwXText::getUnoTunnelId()
1202 {
1203  static const comphelper::UnoIdInit theSwXTextUnoTunnelId;
1204  return theSwXTextUnoTunnelId.getSeq();
1205 }
1206 
1207 sal_Int64 SAL_CALL
1208 SwXText::getSomething(const uno::Sequence< sal_Int8 >& rId)
1209 {
1210  return comphelper::getSomethingImpl<SwXText>(rId, this);
1211 }
1212 
1213 uno::Reference< text::XTextRange > SAL_CALL
1215  const uno::Sequence< beans::PropertyValue > & rProperties)
1216 {
1217  SolarMutexGuard g;
1218 
1219  return m_pImpl->finishOrAppendParagraph(rProperties, uno::Reference< text::XTextRange >());
1220 }
1221 
1222 uno::Reference< text::XTextRange > SAL_CALL
1224  const uno::Sequence< beans::PropertyValue > & rProperties,
1225  const uno::Reference< text::XTextRange >& xInsertPosition)
1226 {
1227  SolarMutexGuard g;
1228 
1229  return m_pImpl->finishOrAppendParagraph(rProperties, xInsertPosition);
1230 }
1231 
1232 uno::Reference< text::XTextRange >
1234  const uno::Sequence< beans::PropertyValue > & rProperties,
1235  const uno::Reference< text::XTextRange >& xInsertPosition)
1236 {
1237  if (!m_bIsValid)
1238  {
1239  throw uno::RuntimeException();
1240  }
1241 
1242  const SwStartNode* pStartNode = m_rThis.GetStartNode();
1243  if(!pStartNode)
1244  {
1245  throw uno::RuntimeException();
1246  }
1247 
1248  uno::Reference< text::XTextRange > xRet;
1249  bool bIllegalException = false;
1250  bool bRuntimeException = false;
1251  OUString sMessage;
1252  m_pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::START , nullptr);
1253  // find end node, go backward - don't skip tables because the new
1254  // paragraph has to be the last node
1255  //aPam.Move( fnMoveBackward, GoInNode );
1256  SwPosition aInsertPosition(
1257  SwNodeIndex( *pStartNode->EndOfSectionNode(), -1 ) );
1258  SwPaM aPam(aInsertPosition);
1259  // If we got a position reference, then the insert point is not the end of
1260  // the document.
1261  if (xInsertPosition.is())
1262  {
1263  SwUnoInternalPaM aStartPam(*m_rThis.GetDoc());
1264  ::sw::XTextRangeToSwPaM(aStartPam, xInsertPosition);
1265  aPam = aStartPam;
1266  aPam.SetMark();
1267  }
1268  m_pDoc->getIDocumentContentOperations().AppendTextNode( *aPam.GetPoint() );
1269  // remove attributes from the previous paragraph
1270  m_pDoc->ResetAttrs(aPam);
1271  // in case of finishParagraph the PaM needs to be moved to the
1272  // previous paragraph
1273  aPam.Move( fnMoveBackward, GoInNode );
1274 
1275  try
1276  {
1277  SfxItemPropertySet const*const pParaPropSet =
1279 
1280  SwUnoCursorHelper::SetPropertyValues(aPam, *pParaPropSet, rProperties);
1281 
1282  // tdf#127616 keep direct character formatting of empty paragraphs,
1283  // if character style of the paragraph sets also the same attributes
1284  if (aPam.Start()->nNode.GetNode().GetTextNode()->Len() == 0)
1285  {
1286  auto itCharStyle = std::find_if(rProperties.begin(), rProperties.end(), [](const beans::PropertyValue& rValue)
1287  {
1288  return rValue.Name == "CharStyleName";
1289  });
1290  if ( itCharStyle != rProperties.end() )
1291  {
1292  for (const auto& rValue : rProperties)
1293  {
1294  if ( rValue != *itCharStyle && rValue.Name.startsWith("Char") )
1295  {
1296  SwUnoCursorHelper::SetPropertyValue(aPam, *pParaPropSet, rValue.Name, rValue.Value);
1297  }
1298  }
1299  }
1300  }
1301  }
1302  catch (const lang::IllegalArgumentException& rIllegal)
1303  {
1304  sMessage = rIllegal.Message;
1305  bIllegalException = true;
1306  }
1307  catch (const uno::RuntimeException& rRuntime)
1308  {
1309  sMessage = rRuntime.Message;
1310  bRuntimeException = true;
1311  }
1312  catch (const uno::Exception& rEx)
1313  {
1314  sMessage = rEx.Message;
1315  bRuntimeException = true;
1316  }
1317 
1318  m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::END, nullptr);
1319  if (bIllegalException || bRuntimeException)
1320  {
1321  m_pDoc->GetIDocumentUndoRedo().Undo();
1322  if (bIllegalException)
1323  {
1324  lang::IllegalArgumentException aEx;
1325  aEx.Message = sMessage;
1326  throw aEx;
1327  }
1328  else
1329  {
1330  uno::RuntimeException aEx;
1331  aEx.Message = sMessage;
1332  throw aEx;
1333  }
1334  }
1335  SwTextNode *const pTextNode( aPam.Start()->nNode.GetNode().GetTextNode() );
1336  OSL_ENSURE(pTextNode, "no SwTextNode?");
1337  if (pTextNode)
1338  {
1339  xRet.set(SwXParagraph::CreateXParagraph(*m_pDoc, pTextNode, &m_rThis),
1340  uno::UNO_QUERY);
1341  }
1342 
1343  return xRet;
1344 }
1345 
1346 uno::Reference< text::XTextRange > SAL_CALL
1348  const OUString& rText,
1349  const uno::Sequence< beans::PropertyValue > &
1350  rCharacterAndParagraphProperties,
1351  const uno::Reference<text::XTextRange>& xInsertPosition)
1352 {
1353  SolarMutexGuard aGuard;
1354 
1355  if(!IsValid())
1356  {
1357  throw uno::RuntimeException();
1358  }
1359  uno::Reference< text::XTextRange > xRet;
1360  const uno::Reference<text::XTextCursor> xTextCursor = createTextCursorByRange(xInsertPosition);
1361 
1362  const uno::Reference< lang::XUnoTunnel > xRangeTunnel(
1363  xTextCursor, uno::UNO_QUERY_THROW );
1364  SwXTextCursor *const pTextCursor =
1365  comphelper::getFromUnoTunnel<SwXTextCursor>(xRangeTunnel);
1366 
1367  bool bIllegalException = false;
1368  bool bRuntimeException = false;
1369  OUString sMessage;
1370  m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
1371 
1372  auto& rCursor(pTextCursor->GetCursor());
1373  m_pImpl->m_pDoc->DontExpandFormat( *rCursor.Start() );
1374 
1375  if (!rText.isEmpty())
1376  {
1377  SwNodeIndex const nodeIndex(rCursor.GetPoint()->nNode, -1);
1378  const sal_Int32 nContentPos = rCursor.GetPoint()->nContent.GetIndex();
1380  *m_pImpl->m_pDoc, rCursor, rText, false);
1381  SwUnoCursorHelper::SelectPam(rCursor, true);
1382  rCursor.GetPoint()->nNode.Assign(nodeIndex.GetNode(), +1);
1383  rCursor.GetPoint()->nContent = nContentPos;
1384  }
1385 
1386  try
1387  {
1388  SfxItemPropertySet const*const pCursorPropSet =
1390  SwUnoCursorHelper::SetPropertyValues(rCursor, *pCursorPropSet,
1391  rCharacterAndParagraphProperties,
1393  }
1394  catch (const lang::IllegalArgumentException& rIllegal)
1395  {
1396  sMessage = rIllegal.Message;
1397  bIllegalException = true;
1398  }
1399  catch (const uno::RuntimeException& rRuntime)
1400  {
1401  sMessage = rRuntime.Message;
1402  bRuntimeException = true;
1403  }
1404  m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr);
1405  if (bIllegalException || bRuntimeException)
1406  {
1407  m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
1408  if (bIllegalException)
1409  {
1410  lang::IllegalArgumentException aEx;
1411  aEx.Message = sMessage;
1412  throw aEx;
1413  }
1414  else
1415  {
1416  uno::RuntimeException aEx;
1417  aEx.Message = sMessage;
1418  throw aEx;
1419  }
1420  }
1421  xRet = new SwXTextRange(rCursor, this);
1422  return xRet;
1423 }
1424 
1425 // Append text portions at the end of the last paragraph of the text interface.
1426 // Support of import filters.
1427 uno::Reference< text::XTextRange > SAL_CALL
1429  const OUString& rText,
1430  const uno::Sequence< beans::PropertyValue > &
1431  rCharacterAndParagraphProperties)
1432 {
1433  // Right now this doesn't need a guard, as it's just calling the insert
1434  // version, that has it already.
1435  uno::Reference<text::XTextRange> xInsertPosition = getEnd();
1436  return insertTextPortion(rText, rCharacterAndParagraphProperties, xInsertPosition);
1437 }
1438 
1439 // enable inserting/appending text contents like graphic objects, shapes and so on to
1440 // support import filters
1441 uno::Reference< text::XTextRange > SAL_CALL
1443  const uno::Reference< text::XTextContent >& xTextContent,
1444  const uno::Sequence< beans::PropertyValue >&
1445  rCharacterAndParagraphProperties,
1446  const uno::Reference< text::XTextRange >& xInsertPosition)
1447 {
1448  SolarMutexGuard aGuard;
1449 
1450  if (!IsValid())
1451  {
1452  throw uno::RuntimeException();
1453  }
1454 
1455  SwUnoInternalPaM aPam(*GetDoc());
1456  if (!::sw::XTextRangeToSwPaM(aPam, xInsertPosition))
1457  {
1458  throw lang::IllegalArgumentException("invalid position", nullptr, 2);
1459  }
1460 
1461  SwRewriter aRewriter;
1462  aRewriter.AddRule(UndoArg1, SwResId(STR_UNDO_INSERT_TEXTBOX));
1463 
1464  m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, &aRewriter);
1465 
1466  // Any direct formatting ending at the insert position (xRange) should not
1467  // be expanded to cover the inserted content (xContent)
1468  // (insertTextContent() shouldn't do this, only ...WithProperties()!)
1469  GetDoc()->DontExpandFormat( *aPam.Start() );
1470 
1471  // now attach the text content here
1472  insertTextContent( xInsertPosition, xTextContent, false );
1473  // now apply the properties to the anchor
1474  if (rCharacterAndParagraphProperties.hasElements())
1475  {
1476  try
1477  {
1478  const uno::Reference< beans::XPropertySet > xAnchor(
1479  xTextContent->getAnchor(), uno::UNO_QUERY);
1480  if (xAnchor.is())
1481  {
1482  for (const auto& rProperty : rCharacterAndParagraphProperties)
1483  {
1484  xAnchor->setPropertyValue(rProperty.Name, rProperty.Value);
1485  }
1486  }
1487  }
1488  catch (const uno::Exception& e)
1489  {
1490  css::uno::Any anyEx = cppu::getCaughtException();
1491  m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, &aRewriter);
1492  throw lang::WrappedTargetRuntimeException( e.Message,
1493  uno::Reference< uno::XInterface >(), anyEx );
1494  }
1495  }
1496  m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, &aRewriter);
1497  return xInsertPosition;
1498 }
1499 
1500 uno::Reference< text::XTextRange > SAL_CALL
1502  const uno::Reference< text::XTextContent >& xTextContent,
1503  const uno::Sequence< beans::PropertyValue >& rCharacterAndParagraphProperties
1504  )
1505 {
1506  // Right now this doesn't need a guard, as it's just calling the insert
1507  // version, that has it already.
1508  uno::Reference<text::XTextRange> xInsertPosition = getEnd();
1509  return insertTextContentWithProperties(xTextContent, rCharacterAndParagraphProperties, xInsertPosition);
1510 }
1511 
1512 // determine whether SwFrameFormat is a graphic node
1513 static bool isGraphicNode(const SwFrameFormat* pFrameFormat)
1514 {
1515  // safety
1516  if( !pFrameFormat->GetContent().GetContentIdx() )
1517  {
1518  return false;
1519  }
1520  auto index = *pFrameFormat->GetContent().GetContentIdx();
1521  // consider the next node -> there is the graphic stored
1522  index++;
1523  return index.GetNode().IsGrfNode();
1524 }
1525 
1526 // move previously appended paragraphs into a text frames
1527 // to support import filters
1528 uno::Reference< text::XTextContent > SAL_CALL
1530  const uno::Reference< text::XTextRange >& xStart,
1531  const uno::Reference< text::XTextRange >& xEnd,
1532  const uno::Sequence< beans::PropertyValue >& rFrameProperties)
1533 {
1534  SolarMutexGuard aGuard;
1535 
1536  if(!IsValid())
1537  {
1538  throw uno::RuntimeException();
1539  }
1540  // tdf#143384 recognize dummy property, that was set to make createTextCursor
1541  // to not ignore tables.
1542  // It is enough to use this hack only for the range start,
1543  // because as far as I know, the range cannot end with table when this property is set.
1544  ::sw::TextRangeMode eMode = ::sw::TextRangeMode::RequireTextNode;
1545  for (const auto& rCellProperty : rFrameProperties)
1546  {
1547  if (rCellProperty.Name == "CursorNotIgnoreTables")
1548  {
1549  bool bAllowNonTextNode = false;
1550  rCellProperty.Value >>= bAllowNonTextNode;
1551  if (bAllowNonTextNode)
1552  eMode = ::sw::TextRangeMode::AllowTableNode;
1553  break;
1554  }
1555  }
1556  uno::Reference< text::XTextContent > xRet;
1557  std::optional<SwUnoInternalPaM> pTempStartPam(*GetDoc());
1558  std::optional<SwUnoInternalPaM> pEndPam(*GetDoc());
1559  if (!::sw::XTextRangeToSwPaM(*pTempStartPam, xStart, eMode)
1560  || !::sw::XTextRangeToSwPaM(*pEndPam, xEnd))
1561  {
1562  throw lang::IllegalArgumentException();
1563  }
1564 
1565  auto pStartPam(GetDoc()->CreateUnoCursor(*pTempStartPam->GetPoint()));
1566  if (pTempStartPam->HasMark())
1567  {
1568  pStartPam->SetMark();
1569  *pStartPam->GetMark() = *pTempStartPam->GetMark();
1570  }
1571  pTempStartPam.reset();
1572 
1573  SwXTextRange *const pStartRange =
1574  comphelper::getFromUnoTunnel<SwXTextRange>(xStart);
1575  SwXTextRange *const pEndRange =
1576  comphelper::getFromUnoTunnel<SwXTextRange>(xEnd);
1577  // bookmarks have to be removed before the referenced text node
1578  // is deleted in DelFullPara
1579  if (pStartRange)
1580  {
1581  pStartRange->Invalidate();
1582  }
1583  if (pEndRange)
1584  {
1585  pEndRange->Invalidate();
1586  }
1587 
1588  m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
1589  bool bIllegalException = false;
1590  bool bRuntimeException = false;
1591  OUString sMessage;
1592  SwStartNode* pStartStartNode = pStartPam->GetNode().StartOfSectionNode();
1593  while (pStartStartNode && pStartStartNode->IsSectionNode())
1594  {
1595  pStartStartNode = pStartStartNode->StartOfSectionNode();
1596  }
1597  SwStartNode* pEndStartNode = pEndPam->GetNode().StartOfSectionNode();
1598  while (pEndStartNode && pEndStartNode->IsSectionNode())
1599  {
1600  pEndStartNode = pEndStartNode->StartOfSectionNode();
1601  }
1602  bool bParaAfterInserted = false;
1603  bool bParaBeforeInserted = false;
1604  if (
1605  pStartStartNode && pEndStartNode &&
1606  (pStartStartNode != pEndStartNode || pStartStartNode != GetStartNode())
1607  )
1608  {
1609  // todo: if the start/end is in a table then insert a paragraph
1610  // before/after, move the start/end nodes, then convert and
1611  // remove the additional paragraphs in the end
1612  SwTableNode * pStartTableNode(nullptr);
1613  if (pStartStartNode->GetStartNodeType() == SwTableBoxStartNode)
1614  {
1615  pStartTableNode = pStartStartNode->FindTableNode();
1616  // Is it the same table start node than the end?
1617  SwTableNode *const pEndStartTableNode(pEndStartNode->FindTableNode());
1618  while (pEndStartTableNode && pStartTableNode &&
1619  pEndStartTableNode->GetIndex() < pStartTableNode->GetIndex())
1620  {
1621  SwStartNode* pStartStartTableNode = pStartTableNode->StartOfSectionNode();
1622  pStartTableNode = pStartStartTableNode->FindTableNode();
1623  }
1624  }
1625  if (pStartTableNode)
1626  {
1627  const SwNodeIndex aTableIdx( *pStartTableNode, -1 );
1628  SwPosition aBefore(aTableIdx);
1629  bParaBeforeInserted = GetDoc()->getIDocumentContentOperations().AppendTextNode( aBefore );
1630  pStartPam->DeleteMark();
1631  *pStartPam->GetPoint() = aBefore;
1632  pStartStartNode = pStartPam->GetNode().StartOfSectionNode();
1633  }
1634  if (pEndStartNode->GetStartNodeType() == SwTableBoxStartNode)
1635  {
1636  SwTableNode *const pEndTableNode = pEndStartNode->FindTableNode();
1637  SwEndNode *const pTableEnd = pEndTableNode->EndOfSectionNode();
1638  SwPosition aTableEnd(*pTableEnd);
1639  bParaAfterInserted = GetDoc()->getIDocumentContentOperations().AppendTextNode( aTableEnd );
1640  pEndPam->DeleteMark();
1641  *pEndPam->GetPoint() = aTableEnd;
1642  pEndStartNode = pEndPam->GetNode().StartOfSectionNode();
1643  }
1644  // now we should have the positions in the same hierarchy
1645  if ((pStartStartNode != pEndStartNode) ||
1646  (pStartStartNode != GetStartNode()))
1647  {
1648  // if not - remove the additional paragraphs and throw
1649  if (bParaBeforeInserted)
1650  {
1651  SwCursor aDelete(*pStartPam->GetPoint(), nullptr);
1652  *pStartPam->GetPoint() = // park it because node is deleted
1653  SwPosition(GetDoc()->GetNodes().GetEndOfContent());
1654  aDelete.MovePara(GoCurrPara, fnParaStart);
1655  aDelete.SetMark();
1656  aDelete.MovePara(GoCurrPara, fnParaEnd);
1658  }
1659  if (bParaAfterInserted)
1660  {
1661  SwCursor aDelete(*pEndPam->GetPoint(), nullptr);
1662  *pEndPam->GetPoint() = // park it because node is deleted
1663  SwPosition(GetDoc()->GetNodes().GetEndOfContent());
1664  aDelete.MovePara(GoCurrPara, fnParaStart);
1665  aDelete.SetMark();
1666  aDelete.MovePara(GoCurrPara, fnParaEnd);
1668  }
1669  throw lang::IllegalArgumentException();
1670  }
1671  }
1672 
1673  // make a selection from pStartPam to pEndPam
1674  // If there is no content in the frame the shape is in
1675  // it gets deleted in the DelFullPara call below,
1676  // In this case insert a tmp text node ( we delete it later )
1677  if (pStartPam->Start()->nNode == pEndPam->Start()->nNode
1678  && pStartPam->End()->nNode == pEndPam->End()->nNode)
1679  {
1680  SwPosition aEnd(*pStartPam->End());
1681  bParaAfterInserted = GetDoc()->getIDocumentContentOperations().AppendTextNode( aEnd );
1682  pEndPam->DeleteMark();
1683  *pEndPam->GetPoint() = aEnd;
1684  }
1685  pStartPam->SetMark();
1686  *pStartPam->End() = *pEndPam->End();
1687  pEndPam.reset();
1688 
1689  // see if there are frames already anchored to this node
1690  // we have to work with the SdrObjects, as unique name is not guaranteed in their frame format
1691  // tdf#115094: do nothing if we have a graphic node
1692  o3tl::sorted_vector<const SdrObject*> aAnchoredObjectsByPtr;
1693  std::set<OUString> aAnchoredObjectsByName;
1694  for (size_t i = 0; i < m_pImpl->m_pDoc->GetSpzFrameFormats()->size(); ++i)
1695  {
1696  const SwFrameFormat* pFrameFormat = (*m_pImpl->m_pDoc->GetSpzFrameFormats())[i];
1697  const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
1698  if ( !isGraphicNode(pFrameFormat) &&
1699  (RndStdIds::FLY_AT_PARA == rAnchor.GetAnchorId() || RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()) &&
1700  pStartPam->Start()->nNode.GetIndex() <= rAnchor.GetContentAnchor()->nNode.GetIndex() &&
1701  pStartPam->End()->nNode.GetIndex() >= rAnchor.GetContentAnchor()->nNode.GetIndex())
1702  {
1703  if (pFrameFormat->GetName().isEmpty())
1704  {
1705  aAnchoredObjectsByPtr.insert(pFrameFormat->FindSdrObject());
1706  }
1707  else
1708  {
1709  aAnchoredObjectsByName.insert(pFrameFormat->GetName());
1710  }
1711  }
1712  }
1713 
1714  const uno::Reference<text::XTextFrame> xNewFrame(
1715  SwXTextFrame::CreateXTextFrame(*m_pImpl->m_pDoc, nullptr));
1716  SwXTextFrame& rNewFrame = dynamic_cast<SwXTextFrame&>(*xNewFrame);
1717  try
1718  {
1719  for (const beans::PropertyValue& rValue : rFrameProperties)
1720  {
1721  rNewFrame.SwXFrame::setPropertyValue(rValue.Name, rValue.Value);
1722  }
1723 
1724  { // has to be in a block to remove the SwIndexes before
1725  // DelFullPara is called
1726  const uno::Reference< text::XTextRange> xInsertTextRange =
1727  new SwXTextRange(*pStartPam, this);
1728  assert(rNewFrame.IsDescriptor());
1729  rNewFrame.attachToRange(xInsertTextRange, pStartPam.get());
1730  rNewFrame.setName(m_pImpl->m_pDoc->GetUniqueFrameName());
1731  }
1732 
1733  SwTextNode *const pTextNode(pStartPam->GetNode().GetTextNode());
1734  assert(pTextNode);
1735  if (!pTextNode || !pTextNode->Len()) // don't remove if it contains text!
1736  {
1737  { // has to be in a block to remove the SwIndexes before
1738  // DelFullPara is called
1739  SwPaM aMovePam( pStartPam->GetNode() );
1740  if (aMovePam.Move( fnMoveForward, GoInContent ))
1741  {
1742  // move the anchor to the next paragraph
1743  SwFormatAnchor aNewAnchor(rNewFrame.GetFrameFormat()->GetAnchor());
1744  aNewAnchor.SetAnchor( aMovePam.Start() );
1745  m_pImpl->m_pDoc->SetAttr(
1746  aNewAnchor, *rNewFrame.GetFrameFormat() );
1747 
1748  // also move frames anchored to us
1749  for (size_t i = 0; i < m_pImpl->m_pDoc->GetSpzFrameFormats()->size(); ++i)
1750  {
1751  SwFrameFormat* pFrameFormat = (*m_pImpl->m_pDoc->GetSpzFrameFormats())[i];
1752  if ((!pFrameFormat->GetName().isEmpty() && aAnchoredObjectsByName.find(pFrameFormat->GetName()) != aAnchoredObjectsByName.end() ) ||
1753  ( pFrameFormat->GetName().isEmpty() && aAnchoredObjectsByPtr.find(pFrameFormat->FindSdrObject()) != aAnchoredObjectsByPtr.end()) )
1754  {
1755  // copy the anchor to the next paragraph
1756  SwFormatAnchor aAnchor(pFrameFormat->GetAnchor());
1757  aAnchor.SetAnchor(aMovePam.Start());
1758  m_pImpl->m_pDoc->SetAttr(aAnchor, *pFrameFormat);
1759  }
1760  }
1761  }
1762  }
1763  m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pStartPam);
1764  }
1765  }
1766  catch (const lang::IllegalArgumentException& rIllegal)
1767  {
1768  sMessage = rIllegal.Message;
1769  bIllegalException = true;
1770  }
1771  catch (const uno::RuntimeException& rRuntime)
1772  {
1773  sMessage = rRuntime.Message;
1774  bRuntimeException = true;
1775  }
1776  xRet = xNewFrame;
1777  if (bParaBeforeInserted || bParaAfterInserted)
1778  {
1779  const uno::Reference<text::XTextCursor> xFrameTextCursor =
1780  rNewFrame.createTextCursor();
1781  SwXTextCursor *const pFrameCursor =
1782  comphelper::getFromUnoTunnel<SwXTextCursor>(xFrameTextCursor);
1783  if (bParaBeforeInserted)
1784  {
1785  // todo: remove paragraph before frame
1786  m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pFrameCursor->GetPaM());
1787  }
1788  if (bParaAfterInserted)
1789  {
1790  xFrameTextCursor->gotoEnd(false);
1791  if (!bParaBeforeInserted)
1792  m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pFrameCursor->GetPaM());
1793  else
1794  {
1795  // In case the frame has a table only, the cursor points to the end of the first cell of the table.
1796  SwPaM aPaM(*pFrameCursor->GetPaM()->GetNode().FindSttNodeByType(SwFlyStartNode)->EndOfSectionNode());
1797  // Now we have the end of the frame -- the node before that will be the paragraph we want to remove.
1798  --aPaM.GetPoint()->nNode;
1799  m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(aPaM);
1800  }
1801  }
1802  }
1803 
1804  m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::END, nullptr);
1805  if (bIllegalException || bRuntimeException)
1806  {
1807  m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
1808  if (bIllegalException)
1809  {
1810  lang::IllegalArgumentException aEx;
1811  aEx.Message = sMessage;
1812  throw aEx;
1813  }
1814  else
1815  {
1816  uno::RuntimeException aEx;
1817  aEx.Message = sMessage;
1818  throw aEx;
1819  }
1820  }
1821  return xRet;
1822 }
1823 
1824 namespace {
1825 
1826 // Move previously imported paragraphs into a new text table.
1827 struct VerticallyMergedCell
1828 {
1829  std::vector<uno::Reference< beans::XPropertySet > > aCells;
1830  sal_Int32 nLeftPosition;
1831  bool bOpen;
1832 
1833  VerticallyMergedCell(uno::Reference< beans::XPropertySet > const& rxCell,
1834  const sal_Int32 nLeft)
1835  : nLeftPosition( nLeft )
1836  , bOpen( true )
1837  {
1838  aCells.push_back( rxCell );
1839  }
1840 };
1841 
1842 }
1843 
1844 #define COL_POS_FUZZY 2
1845 
1846 static bool lcl_SimilarPosition( const sal_Int32 nPos1, const sal_Int32 nPos2 )
1847 {
1848  return abs( nPos1 - nPos2 ) < COL_POS_FUZZY;
1849 }
1850 
1852  const uno::Sequence< uno::Reference< text::XTextRange > > & rCell,
1853  std::vector<SwNodeRange> & rRowNodes,
1854  SwNodeRange *const pLastCell)
1855 {
1856  if (rCell.getLength() != 2)
1857  {
1858  throw lang::IllegalArgumentException(
1859  "rCell needs to contain 2 elements",
1860  uno::Reference< text::XTextCopy >( &m_rThis ), sal_Int16( 2 ) );
1861  }
1862  const uno::Reference<text::XTextRange> xStartRange = rCell[0];
1863  const uno::Reference<text::XTextRange> xEndRange = rCell[1];
1864  SwUnoInternalPaM aStartCellPam(*m_pDoc);
1865  SwUnoInternalPaM aEndCellPam(*m_pDoc);
1866 
1867  // !!! TODO - PaMs in tables and sections do not work here -
1868  // the same applies to PaMs in frames !!!
1869 
1870  if (!::sw::XTextRangeToSwPaM(aStartCellPam, xStartRange) ||
1871  !::sw::XTextRangeToSwPaM(aEndCellPam, xEndRange))
1872  {
1873  throw lang::IllegalArgumentException(
1874  "Start or End range cannot be resolved to a SwPaM",
1875  uno::Reference< text::XTextCopy >( &m_rThis ), sal_Int16( 2 ) );
1876  }
1877 
1878  SwNodeRange aTmpRange(aStartCellPam.Start()->nNode,
1879  aEndCellPam.End()->nNode);
1880  std::unique_ptr<SwNodeRange> pCorrectedRange =
1881  m_pDoc->GetNodes().ExpandRangeForTableBox(aTmpRange);
1882 
1883  if (pCorrectedRange)
1884  {
1885  SwPaM aNewStartPaM(pCorrectedRange->aStart, 0);
1886  aStartCellPam = aNewStartPaM;
1887 
1888  sal_Int32 nEndLen = 0;
1889  SwTextNode * pTextNode = pCorrectedRange->aEnd.GetNode().GetTextNode();
1890  if (pTextNode != nullptr)
1891  nEndLen = pTextNode->Len();
1892 
1893  SwPaM aNewEndPaM(pCorrectedRange->aEnd, nEndLen);
1894  aEndCellPam = aNewEndPaM;
1895 
1896  pCorrectedRange.reset();
1897  }
1898 
1902  if (aStartCellPam.Start()->nNode < aEndCellPam.End()->nNode)
1903  {
1904  // increment on each StartNode and decrement on each EndNode
1905  // we must reach zero at the end and must not go below zero
1906  tools::Long nOpenNodeBlock = 0;
1907  SwNodeIndex aCellIndex = aStartCellPam.Start()->nNode;
1908  while (aCellIndex < aEndCellPam.End()->nNode.GetIndex())
1909  {
1910  if (aCellIndex.GetNode().IsStartNode())
1911  {
1912  ++nOpenNodeBlock;
1913  }
1914  else if (aCellIndex.GetNode().IsEndNode())
1915  {
1916  --nOpenNodeBlock;
1917  }
1918  if (nOpenNodeBlock < 0)
1919  {
1920  throw lang::IllegalArgumentException();
1921  }
1922  ++aCellIndex;
1923  }
1924  if (nOpenNodeBlock != 0)
1925  {
1926  throw lang::IllegalArgumentException();
1927  }
1928  }
1929 
1936  if (!pLastCell) // first cell?
1937  {
1938  // align the beginning - if necessary
1939  if (aStartCellPam.Start()->nContent.GetIndex())
1940  {
1941  m_pDoc->getIDocumentContentOperations().SplitNode(*aStartCellPam.Start(), false);
1942  }
1943  }
1944  else
1945  {
1946  // check the predecessor
1947  const SwNodeOffset nStartCellNodeIndex =
1948  aStartCellPam.Start()->nNode.GetIndex();
1949  const SwNodeOffset nLastNodeEndIndex = pLastCell->aEnd.GetIndex();
1950  if (nLastNodeEndIndex == nStartCellNodeIndex)
1951  {
1952  // same node as predecessor then equal nContent?
1953  if (0 != aStartCellPam.Start()->nContent.GetIndex())
1954  {
1955  throw lang::IllegalArgumentException();
1956  }
1957 
1958  m_pDoc->getIDocumentContentOperations().SplitNode(*aStartCellPam.Start(), false);
1959  SwNodeOffset const nNewIndex(aStartCellPam.Start()->nNode.GetIndex());
1960  if (nNewIndex != nStartCellNodeIndex)
1961  {
1962  // aStartCellPam now points to the 2nd node
1963  // the last cell may *also* point to 2nd node now - fix it!
1964  assert(nNewIndex == nStartCellNodeIndex + 1);
1965  if (pLastCell->aEnd.GetIndex() == nNewIndex)
1966  {
1967  --pLastCell->aEnd;
1968  if (pLastCell->aStart.GetIndex() == nNewIndex)
1969  {
1970  --pLastCell->aStart;
1971  }
1972  }
1973  }
1974  }
1975  else if (nStartCellNodeIndex == (nLastNodeEndIndex + 1))
1976  {
1977  // next paragraph - now the content index of the new should be 0
1978  // and of the old one should be equal to the text length
1979  // but if it isn't we don't care - the cell is being inserted on
1980  // the node border anyway
1981  }
1982  else
1983  {
1984  throw lang::IllegalArgumentException();
1985  }
1986  }
1987  // now check if there's a need to insert another paragraph break
1988  if (aEndCellPam.End()->nContent.GetIndex() <
1989  aEndCellPam.End()->nNode.GetNode().GetTextNode()->Len())
1990  {
1991  m_pDoc->getIDocumentContentOperations().SplitNode(*aEndCellPam.End(), false);
1992  // take care that the new start/endcell is moved to the right position
1993  // aStartCellPam has to point to the start of the new (previous) node
1994  // aEndCellPam has to point to the end of the new (previous) node
1995  aStartCellPam.DeleteMark();
1996  aStartCellPam.Move(fnMoveBackward, GoInNode);
1997  aStartCellPam.GetPoint()->nContent = 0;
1998  aEndCellPam.DeleteMark();
1999  aEndCellPam.Move(fnMoveBackward, GoInNode);
2000  aEndCellPam.GetPoint()->nContent =
2001  aEndCellPam.GetNode().GetTextNode()->Len();
2002  }
2003 
2004  assert(aStartCellPam.Start()->nContent.GetIndex() == 0);
2005  assert(aEndCellPam.End()->nContent.GetIndex() == aEndCellPam.End()->nNode.GetNode().GetTextNode()->Len());
2006  SwNodeRange aCellRange(aStartCellPam.Start()->nNode,
2007  aEndCellPam.End()->nNode);
2008  rRowNodes.push_back(aCellRange); // note: invalidates pLastCell!
2009 }
2010 
2011 typedef uno::Sequence< text::TableColumnSeparator > TableColumnSeparators;
2012 
2013 static void
2015  uno::Sequence<beans::PropertyValue> const& rRowProperties,
2016  uno::Any const& rRow,
2017  TableColumnSeparators & rRowSeparators)
2018 {
2019  uno::Reference< beans::XPropertySet > xRow;
2020  rRow >>= xRow;
2021  for (const beans::PropertyValue& rProperty : rRowProperties)
2022  {
2023  if ( rProperty.Name == "TableColumnSeparators" )
2024  {
2025  // add the separators to access the cell's positions
2026  // for vertical merging later
2027  TableColumnSeparators aSeparators;
2028  rProperty.Value >>= aSeparators;
2029  rRowSeparators = aSeparators;
2030  }
2031  xRow->setPropertyValue(rProperty.Name, rProperty.Value);
2032  }
2033 }
2034 
2035 static sal_Int32 lcl_GetLeftPos(sal_Int32 nCell, TableColumnSeparators const& rRowSeparators)
2036 {
2037  if(!nCell)
2038  return 0;
2039  if (rRowSeparators.getLength() < nCell)
2040  return -1;
2041  return rRowSeparators[nCell - 1].Position;
2042 }
2043 
2044 static void
2046  const sal_Int32 nLeftPos,
2047  const uno::Sequence< beans::PropertyValue >& rCellProperties,
2048  const uno::Reference< uno::XInterface >& xCell,
2049  std::vector<VerticallyMergedCell> & rMergedCells)
2050 {
2051  const uno::Reference< beans::XPropertySet > xCellPS(xCell, uno::UNO_QUERY);
2052  for (const auto& rCellProperty : rCellProperties)
2053  {
2054  const OUString & rName = rCellProperty.Name;
2055  const uno::Any & rValue = rCellProperty.Value;
2056  if ( rName == "VerticalMerge" )
2057  {
2058  // determine left border position
2059  // add the cell to a queue of merged cells
2060  bool bMerge = false;
2061  rValue >>= bMerge;
2062  if (bMerge)
2063  {
2064  // 'close' all the cell with the same left position
2065  // if separate vertical merges in the same column exist
2066  for(auto& aMergedCell : rMergedCells)
2067  {
2068  if(lcl_SimilarPosition(aMergedCell.nLeftPosition, nLeftPos))
2069  {
2070  aMergedCell.bOpen = false;
2071  }
2072  }
2073  // add the new group of merged cells
2074  rMergedCells.emplace_back(xCellPS, nLeftPos);
2075  }
2076  else
2077  {
2078  bool bFound = false;
2079  SAL_WARN_IF(rMergedCells.empty(), "sw.uno", "the first merged cell is missing");
2080  for(auto& aMergedCell : rMergedCells)
2081  {
2082  if (aMergedCell.bOpen && lcl_SimilarPosition(aMergedCell.nLeftPosition, nLeftPos))
2083  {
2084  aMergedCell.aCells.push_back( xCellPS );
2085  bFound = true;
2086  }
2087  }
2088  SAL_WARN_IF(!bFound, "sw.uno", "couldn't find first vertically merged cell" );
2089  }
2090  }
2091  else
2092  {
2093  try
2094  {
2095  xCellPS->setPropertyValue(rName, rValue);
2096  }
2097  catch (const uno::Exception&)
2098  {
2099  TOOLS_WARN_EXCEPTION( "sw.uno", "Exception when setting cell property " << rName );
2100  }
2101  }
2102  }
2103 }
2104 
2105 static void
2106 lcl_MergeCells(std::vector<VerticallyMergedCell> & rMergedCells)
2107 {
2108  for(auto& aMergedCell : rMergedCells)
2109  {
2110  // the first of the cells gets the number of cells set as RowSpan
2111  // the others get the inverted number of remaining merged cells
2112  // (3,-2,-1)
2113  sal_Int32 nCellCount = static_cast<sal_Int32>(aMergedCell.aCells.size());
2114  if(nCellCount<2)
2115  {
2116  SAL_WARN("sw.uno", "incomplete vertical cell merge");
2117  continue;
2118  }
2119  aMergedCell.aCells.front()->setPropertyValue(UNO_NAME_ROW_SPAN, uno::makeAny(nCellCount--));
2120  nCellCount*=-1;
2121  for(auto pxPSet = aMergedCell.aCells.begin()+1; nCellCount<0; ++pxPSet, ++nCellCount)
2122  (*pxPSet)->setPropertyValue(UNO_NAME_ROW_SPAN, uno::makeAny(nCellCount));
2123  }
2124 }
2125 
2126 uno::Reference< text::XTextTable > SAL_CALL
2128  const uno::Sequence< uno::Sequence< uno::Sequence<
2129  uno::Reference< text::XTextRange > > > >& rTableRanges,
2130  const uno::Sequence< uno::Sequence< uno::Sequence<
2131  beans::PropertyValue > > >& rCellProperties,
2132  const uno::Sequence< uno::Sequence< beans::PropertyValue > >&
2133  rRowProperties,
2134  const uno::Sequence< beans::PropertyValue >& rTableProperties)
2135 {
2136  SolarMutexGuard aGuard;
2137 
2138  if(!IsValid())
2139  {
2140  throw uno::RuntimeException();
2141  }
2142 
2143  IDocumentRedlineAccess & rIDRA(m_pImpl->m_pDoc->getIDocumentRedlineAccess());
2144  if (!IDocumentRedlineAccess::IsShowChanges(rIDRA.GetRedlineFlags()))
2145  {
2146  throw uno::RuntimeException(
2147  "cannot convertToTable if tracked changes are hidden!");
2148  }
2149 
2150  //at first collect the text ranges as SwPaMs
2151  const uno::Sequence< uno::Sequence< uno::Reference< text::XTextRange > > >*
2152  pTableRanges = rTableRanges.getConstArray();
2153  std::vector< std::vector<SwNodeRange> > aTableNodes;
2154  for (sal_Int32 nRow = 0; nRow < rTableRanges.getLength(); ++nRow)
2155  {
2156  std::vector<SwNodeRange> aRowNodes;
2157  const uno::Sequence< uno::Reference< text::XTextRange > >* pRow =
2158  pTableRanges[nRow].getConstArray();
2159  const sal_Int32 nCells(pTableRanges[nRow].getLength());
2160 
2161  if (0 == nCells) // this would lead to no pLastCell below
2162  { // and make it impossible to detect node gaps
2163  throw lang::IllegalArgumentException();
2164  }
2165 
2166  for (sal_Int32 nCell = 0; nCell < nCells; ++nCell)
2167  {
2168  SwNodeRange *const pLastCell(
2169  (nCell == 0)
2170  ? ((nRow == 0)
2171  ? nullptr
2172  : &*aTableNodes.rbegin()->rbegin())
2173  : &*aRowNodes.rbegin());
2174  m_pImpl->ConvertCell(pRow[nCell], aRowNodes, pLastCell);
2175  }
2176  assert(!aRowNodes.empty());
2177  aTableNodes.push_back(aRowNodes);
2178  }
2179 
2180  std::vector< TableColumnSeparators >
2181  aRowSeparators(rRowProperties.getLength());
2182  std::vector<VerticallyMergedCell> aMergedCells;
2183 
2184  SwTable const*const pTable = m_pImpl->m_pDoc->TextToTable( aTableNodes );
2185 
2186  if (!pTable)
2187  return uno::Reference< text::XTextTable >();
2188 
2189  uno::Reference<text::XTextTable> const xRet =
2191  uno::Reference<beans::XPropertySet> const xPrSet(xRet, uno::UNO_QUERY);
2192  // set properties to the table
2193  // catch lang::WrappedTargetException and lang::IndexOutOfBoundsException
2194  try
2195  {
2196  //apply table properties
2197  for(const auto& rTableProperty : rTableProperties)
2198  {
2199  try
2200  {
2201  xPrSet->setPropertyValue(rTableProperty.Name, rTableProperty.Value);
2202  }
2203  catch (const uno::Exception&)
2204  {
2205  TOOLS_WARN_EXCEPTION( "sw.uno", "Exception when setting property: " << rTableProperty.Name );
2206  }
2207  }
2208 
2209  //apply row properties
2210  const auto xRows = xRet->getRows();
2211  const sal_Int32 nLast = std::min(xRows->getCount(), rRowProperties.getLength());
2212  SAL_WARN_IF(nLast != rRowProperties.getLength(), "sw.uno", "not enough rows for properties");
2213  for(sal_Int32 nCnt = 0; nCnt < nLast; ++nCnt)
2214  lcl_ApplyRowProperties(rRowProperties[nCnt], xRows->getByIndex(nCnt), aRowSeparators[nCnt]);
2215 
2216  uno::Reference<table::XCellRange> const xCR(xRet, uno::UNO_QUERY_THROW);
2217  //apply cell properties
2218  sal_Int32 nRow = 0;
2219  for(const auto& rCellPropertiesForRow : rCellProperties)
2220  {
2221  sal_Int32 nCell = 0;
2222  for(const auto& rCellProps : rCellPropertiesForRow)
2223  {
2224  lcl_ApplyCellProperties(lcl_GetLeftPos(nCell, aRowSeparators[nRow]),
2225  rCellProps,
2226  xCR->getCellByPosition(nCell, nRow),
2227  aMergedCells);
2228  ++nCell;
2229  }
2230  ++nRow;
2231  }
2232 
2233  // now that the cell properties are set the vertical merge values
2234  // have to be applied
2235  lcl_MergeCells(aMergedCells);
2236  }
2237  catch (const lang::WrappedTargetException&)
2238  {
2239  }
2240  catch (const lang::IndexOutOfBoundsException&)
2241  {
2242  }
2243 
2244  assert(SwTable::FindTable(pTable->GetFrameFormat()) == pTable);
2245  assert(pTable->GetFrameFormat() ==
2246  dynamic_cast<SwXTextTable&>(*xRet).GetFrameFormat());
2247  return xRet;
2248 }
2249 
2250 void SAL_CALL
2252  const uno::Reference< text::XTextCopy >& xSource )
2253 {
2254  SolarMutexGuard aGuard;
2255 
2256  uno::Reference<lang::XUnoTunnel> const xSourceTunnel(xSource,
2257  uno::UNO_QUERY);
2258  SwXText const* const pSource(comphelper::getFromUnoTunnel<SwXText>(xSourceTunnel));
2259 
2260  uno::Reference< text::XText > const xText(xSource, uno::UNO_QUERY_THROW);
2261  uno::Reference< text::XTextCursor > const xCursor =
2262  xText->createTextCursor();
2263  xCursor->gotoEnd( true );
2264 
2265  uno::Reference< lang::XUnoTunnel > const xCursorTunnel(xCursor,
2266  uno::UNO_QUERY_THROW);
2267 
2268  OTextCursorHelper *const pCursor =
2269  comphelper::getFromUnoTunnel<OTextCursorHelper>(xCursorTunnel);
2270  if (!pCursor)
2271  {
2272  throw uno::RuntimeException();
2273  }
2274 
2275  SwNodeIndex rNdIndex( *GetStartNode( ), 1 );
2276  SwPosition rPos( rNdIndex );
2277  // tdf#112202 need SwXText because cursor cannot select table at the start
2278  if (pSource)
2279  {
2280  SwTextNode * pFirstNode;
2281  {
2282  SwPaM temp(*pSource->GetStartNode(), *pSource->GetStartNode()->EndOfSectionNode(), SwNodeOffset(+1), SwNodeOffset(-1));
2283  pFirstNode = temp.GetMark()->nNode.GetNode().GetTextNode();
2284  if (pFirstNode)
2285  {
2286  pFirstNode->MakeStartIndex(&temp.GetMark()->nContent);
2287  }
2288  if (SwTextNode *const pNode = temp.GetPoint()->nNode.GetNode().GetTextNode())
2289  {
2290  pNode->MakeEndIndex(&temp.GetPoint()->nContent);
2291  }
2292  // Explicitly request copy text mode, so
2293  // sw::DocumentContentOperationsManager::CopyFlyInFlyImpl() will copy shapes anchored to
2294  // us, even if we have only a single paragraph.
2295  m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(temp, rPos, SwCopyFlags::CheckPosInFly);
2296  }
2297  if (!pFirstNode)
2298  { // the node at rPos was split; get rid of the first empty one so
2299  // that the pasted table is first
2300  auto pDelCursor(m_pImpl->m_pDoc->CreateUnoCursor(SwPosition(SwNodeIndex(*GetStartNode(), 1))));
2301  m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pDelCursor);
2302  }
2303  }
2304  else
2305  {
2306  m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(*pCursor->GetPaM(), rPos, SwCopyFlags::CheckPosInFly);
2307  }
2308 
2309 }
2310 
2312  : SwXText(pDoc, CursorType::Body)
2313 {
2314 }
2315 
2317 {
2318 }
2319 
2320 OUString SAL_CALL
2322 {
2323  return "SwXBodyText";
2324 }
2325 
2326 sal_Bool SAL_CALL SwXBodyText::supportsService(const OUString& rServiceName)
2327 {
2328  return cppu::supportsService(this, rServiceName);
2329 }
2330 
2331 uno::Sequence< OUString > SAL_CALL
2333 {
2334  return { "com.sun.star.text.Text" };
2335 }
2336 
2337 uno::Any SAL_CALL
2339 {
2340  uno::Any aRet;
2342  {
2343  aRet <<= uno::Reference< container::XEnumerationAccess >(this);
2344  }
2346  {
2347  aRet <<= uno::Reference< container::XElementAccess >(this);
2348  }
2349  else if (rType == cppu::UnoType<lang::XServiceInfo>::get())
2350  {
2351  aRet <<= uno::Reference< lang::XServiceInfo >(this);
2352  }
2353  else
2354  {
2355  aRet = SwXText::queryInterface( rType );
2356  }
2357  if(aRet.getValueType() == cppu::UnoType<void>::get())
2358  {
2359  aRet = OWeakAggObject::queryAggregation( rType );
2360  }
2361  return aRet;
2362 }
2363 
2364 uno::Sequence< uno::Type > SAL_CALL
2366 {
2367  const uno::Sequence< uno::Type > aTypes = SwXBodyText_Base::getTypes();
2368  const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
2369  return ::comphelper::concatSequences(aTypes, aTextTypes);
2370 }
2371 
2372 uno::Sequence< sal_Int8 > SAL_CALL
2374 {
2375  return css::uno::Sequence<sal_Int8>();
2376 }
2377 
2378 uno::Any SAL_CALL
2380 {
2381  const uno::Any ret = SwXText::queryInterface(rType);
2382  return (ret.getValueType() == cppu::UnoType<void>::get())
2384  : ret;
2385 }
2386 
2388 {
2389  if(!IsValid())
2390  {
2391  return nullptr;
2392  }
2393 
2394  // the cursor has to skip tables contained in this text
2395  SwPaM aPam(GetDoc()->GetNodes().GetEndOfContent());
2396  aPam.Move( fnMoveBackward, GoInDoc );
2397  if (!bIgnoreTables)
2398  {
2399  SwTableNode * pTableNode = aPam.GetNode().FindTableNode();
2400  SwContentNode * pCont = nullptr;
2401  while (pTableNode)
2402  {
2403  aPam.GetPoint()->nNode = *pTableNode->EndOfSectionNode();
2404  pCont = GetDoc()->GetNodes().GoNext(&aPam.GetPoint()->nNode);
2405  pTableNode = pCont->FindTableNode();
2406  }
2407  if (pCont)
2408  {
2409  aPam.GetPoint()->nContent.Assign(pCont, 0);
2410  }
2411  }
2412  return new SwXTextCursor(*GetDoc(), this, CursorType::Body, *aPam.GetPoint());
2413 }
2414 
2415 uno::Reference< text::XTextCursor > SAL_CALL
2417 {
2418  SolarMutexGuard aGuard;
2419 
2420  const uno::Reference< text::XTextCursor > xRef =
2421  static_cast<text::XWordCursor*>(CreateTextCursor().get());
2422  if (!xRef.is())
2423  {
2424  uno::RuntimeException aRuntime;
2425  aRuntime.Message = cInvalidObject;
2426  throw aRuntime;
2427  }
2428  return xRef;
2429 }
2430 
2431 uno::Reference< text::XTextCursor > SAL_CALL
2433  const uno::Reference< text::XTextRange > & xTextPosition)
2434 {
2435  SolarMutexGuard aGuard;
2436 
2437  if(!IsValid())
2438  {
2439  uno::RuntimeException aRuntime;
2440  aRuntime.Message = cInvalidObject;
2441  throw aRuntime;
2442  }
2443 
2444  uno::Reference< text::XTextCursor > aRef;
2445  SwUnoInternalPaM aPam(*GetDoc());
2446  if (::sw::XTextRangeToSwPaM(aPam, xTextPosition))
2447  {
2448  if ( !aPam.GetNode().GetTextNode() )
2449  throw uno::RuntimeException("Invalid text range" );
2450 
2451  SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
2452 
2453  SwStartNode* p1 = aPam.GetNode().StartOfSectionNode();
2454  //document starts with a section?
2455  while(p1->IsSectionNode())
2456  {
2457  p1 = p1->StartOfSectionNode();
2458  }
2459  SwStartNode *const p2 = rNode.StartOfSectionNode();
2460 
2461  if(p1 == p2)
2462  {
2463  aRef = static_cast<text::XWordCursor*>(
2464  new SwXTextCursor(*GetDoc(), this, CursorType::Body,
2465  *aPam.GetPoint(), aPam.GetMark()));
2466  }
2467  }
2468  if(!aRef.is())
2469  {
2470  throw uno::RuntimeException( "End of content node doesn't have the proper start node",
2471  uno::Reference< uno::XInterface >( *this ) );
2472  }
2473  return aRef;
2474 }
2475 
2476 uno::Reference< container::XEnumeration > SAL_CALL
2478 {
2479  SolarMutexGuard aGuard;
2480 
2481  if (!IsValid())
2482  {
2483  uno::RuntimeException aRuntime;
2484  aRuntime.Message = cInvalidObject;
2485  throw aRuntime;
2486  }
2487 
2488  SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
2489  SwPosition aPos(rNode);
2490  auto pUnoCursor(GetDoc()->CreateUnoCursor(aPos));
2491  pUnoCursor->Move(fnMoveBackward, GoInDoc);
2492  return SwXParagraphEnumeration::Create(this, pUnoCursor, CursorType::Body);
2493 }
2494 
2495 uno::Type SAL_CALL
2497 {
2499 }
2500 
2501 sal_Bool SAL_CALL
2503 {
2504  SolarMutexGuard aGuard;
2505 
2506  if (!IsValid())
2507  {
2508  uno::RuntimeException aRuntime;
2509  aRuntime.Message = cInvalidObject;
2510  throw aRuntime;
2511  }
2512 
2513  return true;
2514 }
2515 
2517  : public SvtListener
2518 {
2519  public:
2522 
2523  Impl(SwFrameFormat& rHeadFootFormat, const bool bIsHeader)
2524  : m_pHeadFootFormat(&rHeadFootFormat)
2525  , m_bIsHeader(bIsHeader)
2526  {
2527  StartListening(m_pHeadFootFormat->GetNotifier());
2528  }
2529 
2531  return m_pHeadFootFormat;
2532  }
2533 
2535  if (!m_pHeadFootFormat) {
2536  throw uno::RuntimeException("SwXHeadFootText: disposed or invalid", nullptr);
2537  }
2538  return *m_pHeadFootFormat;
2539  }
2540  protected:
2541  virtual void Notify(const SfxHint& rHint) override
2542  {
2543  if(rHint.GetId() == SfxHintId::Dying)
2544  m_pHeadFootFormat = nullptr;
2545  }
2546 };
2547 
2548 uno::Reference<text::XText> SwXHeadFootText::CreateXHeadFootText(
2549  SwFrameFormat& rHeadFootFormat,
2550  const bool bIsHeader)
2551 {
2552  // re-use existing SwXHeadFootText
2553  // #i105557#: do not iterate over the registered clients: race condition
2554  uno::Reference<text::XText> xText(rHeadFootFormat.GetXObject(), uno::UNO_QUERY);
2555  if(!xText.is())
2556  {
2557  xText = new SwXHeadFootText(rHeadFootFormat, bIsHeader);
2558  rHeadFootFormat.SetXObject(xText);
2559  }
2560  return xText;
2561 }
2562 
2563 SwXHeadFootText::SwXHeadFootText(SwFrameFormat& rHeadFootFormat, const bool bIsHeader)
2564  : SwXText(
2565  rHeadFootFormat.GetDoc(),
2566  bIsHeader ? CursorType::Header : CursorType::Footer)
2567  , m_pImpl(new SwXHeadFootText::Impl(rHeadFootFormat, bIsHeader))
2568 {
2569 }
2570 
2572 { }
2573 
2574 OUString SAL_CALL
2576 {
2577  return {"SwXHeadFootText"};
2578 }
2579 
2580 sal_Bool SAL_CALL SwXHeadFootText::supportsService(const OUString& rServiceName)
2581 {
2582  return cppu::supportsService(this, rServiceName);
2583 }
2584 
2585 uno::Sequence<OUString> SAL_CALL
2587 {
2588  return {"com.sun.star.text.Text"};
2589 }
2590 
2592 {
2593  const SwStartNode* pSttNd = nullptr;
2594  SwFrameFormat* const pHeadFootFormat = m_pImpl->GetHeadFootFormat();
2595  if(pHeadFootFormat)
2596  {
2597  const SwFormatContent& rFlyContent = pHeadFootFormat->GetContent();
2598  if(rFlyContent.GetContentIdx())
2599  {
2600  pSttNd = rFlyContent.GetContentIdx()->GetNode().GetStartNode();
2601  }
2602  }
2603  return pSttNd;
2604 }
2605 
2606 uno::Reference<text::XTextCursor> SwXHeadFootText::CreateCursor()
2607 {
2608  return createTextCursor();
2609 }
2610 
2611 uno::Sequence<uno::Type> SAL_CALL SwXHeadFootText::getTypes()
2612 {
2613  return ::comphelper::concatSequences(
2614  SwXHeadFootText_Base::getTypes(),
2615  SwXText::getTypes());
2616 }
2617 
2618 uno::Sequence<sal_Int8> SAL_CALL SwXHeadFootText::getImplementationId()
2619 {
2620  return css::uno::Sequence<sal_Int8>();
2621 }
2622 
2624 {
2625  const uno::Any ret = SwXHeadFootText_Base::queryInterface(rType);
2626  return (ret.getValueType() == cppu::UnoType<void>::get())
2627  ? SwXText::queryInterface(rType)
2628  : ret;
2629 }
2630 
2631 uno::Reference<text::XTextCursor> SwXHeadFootText::CreateTextCursor(const bool bIgnoreTables)
2632 {
2633  SolarMutexGuard aGuard;
2634 
2635  SwFrameFormat & rHeadFootFormat( m_pImpl->GetHeadFootFormatOrThrow() );
2636 
2637  const SwFormatContent& rFlyContent = rHeadFootFormat.GetContent();
2638  const SwNode& rNode = rFlyContent.GetContentIdx()->GetNode();
2639  SwPosition aPos(rNode);
2640  rtl::Reference<SwXTextCursor> pXCursor = new SwXTextCursor(*GetDoc(), this,
2641  (m_pImpl->m_bIsHeader) ? CursorType::Header : CursorType::Footer, aPos);
2642  auto& rUnoCursor(pXCursor->GetCursor());
2643  rUnoCursor.Move(fnMoveForward, GoInNode);
2644 
2645  // save current start node to be able to check if there is content
2646  // after the table - otherwise the cursor would be in the body text!
2647  SwStartNode const*const pOwnStartNode = rNode.FindSttNodeByType(
2648  (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
2649 
2650  if (!bIgnoreTables)
2651  {
2652  // is there a table here?
2653  SwTableNode* pTableNode = rUnoCursor.GetNode().FindTableNode();
2654  SwContentNode* pCont = nullptr;
2655  while (pTableNode)
2656  {
2657  rUnoCursor.GetPoint()->nNode = *pTableNode->EndOfSectionNode();
2658  pCont = GetDoc()->GetNodes().GoNext(&rUnoCursor.GetPoint()->nNode);
2659  pTableNode = pCont->FindTableNode();
2660  }
2661  if (pCont)
2662  {
2663  rUnoCursor.GetPoint()->nContent.Assign(pCont, 0);
2664  }
2665  }
2666  SwStartNode const*const pNewStartNode = rUnoCursor.GetNode().FindSttNodeByType(
2667  (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
2668  if (!pNewStartNode || (pNewStartNode != pOwnStartNode))
2669  {
2670  uno::RuntimeException aExcept;
2671  aExcept.Message = "no text available";
2672  throw aExcept;
2673  }
2674  return static_cast<text::XWordCursor*>(pXCursor.get());
2675 }
2676 
2677 uno::Reference<text::XTextCursor> SAL_CALL
2679 {
2680  return CreateTextCursor(false);
2681 }
2682 
2683 uno::Reference<text::XTextCursor> SAL_CALL SwXHeadFootText::createTextCursorByRange(
2684  const uno::Reference<text::XTextRange>& xTextPosition)
2685 {
2686  SolarMutexGuard aGuard;
2687  SwFrameFormat& rHeadFootFormat( m_pImpl->GetHeadFootFormatOrThrow() );
2688 
2689  SwUnoInternalPaM aPam(*GetDoc());
2690  if (!sw::XTextRangeToSwPaM(aPam, xTextPosition))
2691  {
2692  uno::RuntimeException aRuntime;
2693  aRuntime.Message = cInvalidObject;
2694  throw aRuntime;
2695  }
2696 
2697  SwNode& rNode = rHeadFootFormat.GetContent().GetContentIdx()->GetNode();
2698  SwPosition aPos(rNode);
2699  SwPaM aHFPam(aPos);
2700  aHFPam.Move(fnMoveForward, GoInNode);
2701  SwStartNode* const pOwnStartNode = aHFPam.GetNode().FindSttNodeByType(
2702  (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
2703  SwStartNode* const p1 = aPam.GetNode().FindSttNodeByType(
2704  (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
2705  if (p1 == pOwnStartNode)
2706  {
2707  return static_cast<text::XWordCursor*>(
2708  new SwXTextCursor(
2709  *GetDoc(),
2710  this,
2711  (m_pImpl->m_bIsHeader) ? CursorType::Header : CursorType::Footer,
2712  *aPam.GetPoint(), aPam.GetMark()));
2713  }
2714  return nullptr;
2715 }
2716 
2717 uno::Reference<container::XEnumeration> SAL_CALL SwXHeadFootText::createEnumeration()
2718 {
2719  SolarMutexGuard aGuard;
2720  SwFrameFormat& rHeadFootFormat(m_pImpl->GetHeadFootFormatOrThrow());
2721 
2722  const SwFormatContent& rFlyContent = rHeadFootFormat.GetContent();
2723  const SwNode& rNode = rFlyContent.GetContentIdx()->GetNode();
2724  SwPosition aPos(rNode);
2725  auto pUnoCursor(GetDoc()->CreateUnoCursor(aPos));
2726  pUnoCursor->Move(fnMoveForward, GoInNode);
2728  this,
2729  pUnoCursor,
2730  (m_pImpl->m_bIsHeader)
2732  : CursorType::Footer);
2733 }
2734 
2737 
2739  { return true; }
2740 
2741 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwStartNode * FindSttNodeByType(SwStartNodeType eTyp)
Definition: node.cxx:764
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:684
Starts a section of nodes in the document model.
Definition: node.hxx:313
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:33
virtual css::uno::Reference< css::text::XText > SAL_CALL getText() override
Definition: unotext.cxx:851
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unotext.cxx:2586
static void lcl_ApplyRowProperties(uno::Sequence< beans::PropertyValue > const &rRowProperties, uno::Any const &rRow, TableColumnSeparators &rRowSeparators)
Definition: unotext.cxx:2014
void DeleteMark()
Definition: pam.hxx:178
SwXHeadFootText(SwFrameFormat &rHeadFootFormat, const bool bIsHeader)
Definition: unotext.cxx:2563
const CursorType m_eType
Definition: unotext.cxx:84
void SetDoc(SwDoc *const pDoc)
Definition: unotext.cxx:152
SwMoveFnCollection const & fnParaEnd
Definition: paminit.cxx:47
static css::uno::Reference< css::text::XTextTable > CreateXTextTable(SwFrameFormat *pFrameFormat)
Definition: unotbl.cxx:1998
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:224
OUString sMessage
bool GoInContent(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:970
virtual ~SwXText()
Definition: unotext.cxx:128
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:679
virtual void Notify(const SfxHint &rHint) override
Definition: unotext.cxx:2541
Marks a position in the document model.
Definition: pam.hxx:36
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
Definition: unotext.cxx:2379
bool IsSectionNode() const
Definition: node.hxx:646
SwFrameFormat * GetHeadFootFormat() const
Definition: unotext.cxx:2530
void attachToText(SwXText &rParent, SwTextNode &rTextNode)
for SwXText
#define PROPERTY_MAP_TEXT_CURSOR
Definition: unomap.hxx:27
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
Definition: unotext.cxx:2373
CursorType
static css::uno::Reference< css::text::XText > CreateXHeadFootText(SwFrameFormat &rHeadFootFormat, const bool bIsHeader)
Definition: unotext.cxx:2548
bool GoCurrPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1016
SwNodeIndex nNode
Definition: pam.hxx:38
SAL_DLLPRIVATE css::uno::WeakReference< css::uno::XInterface > const & GetXObject() const
Definition: frmfmt.hxx:170
virtual css::uno::Reference< css::text::XTextCursor > SAL_CALL createTextCursor() override
Definition: unotext.cxx:2416
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:278
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: unotext.cxx:1096
long Long
virtual css::uno::Reference< css::text::XTextCursor > CreateCursor() override
Definition: unotext.cxx:2606
static css::uno::Reference< css::text::XTextContent > CreateXParagraph(SwDoc &rDoc, SwTextNode *pTextNode, css::uno::Reference< css::text::XText > const &xParentText=nullptr, const sal_Int32 nSelStart=-1, const sal_Int32 nSelEnd=-1)
void Invalidate()
Definition: unoobj2.cxx:777
const SwPosition * GetMark() const
Definition: pam.hxx:210
void Invalidate()
Definition: unotext.cxx:147
virtual SwUndoId EndUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Closes undo block.
const SfxItemPropertySet * GetPropertySet(sal_uInt16 PropertyId)
Definition: unomap1.cxx:1062
Definition: doc.hxx:188
SwMoveFnCollection const & fnParaStart
Definition: paminit.cxx:46
SwSectionNode is derived from SwStartNode.
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL finishParagraphInsert(const css::uno::Sequence< css::beans::PropertyValue > &rCharacterAndParagraphProperties, const css::uno::Reference< css::text::XTextRange > &xInsertPosition) override
Definition: unotext.cxx:1223
void DeleteAndInsert(OUString const &rText, const bool bForceExpandHints)
Definition: unoobj.cxx:711
#define CHAR_HARDBLANK
Definition: swtypes.hxx:162
Impl(SwFrameFormat &rHeadFootFormat, const bool bIsHeader)
Definition: unotext.cxx:2523
const_iterator find(const Value &x) const
sal_Int16 SAL_CALL compareRegionEnds(const css::uno::Reference< css::text::XTextRange > &xR1, const css::uno::Reference< css::text::XTextRange > &xR2) override
Definition: unotext.cxx:1079
SwNode & GetNode() const
Definition: ndindex.hxx:121
Content, content of frame (header, footer, fly).
Definition: fmtcntnt.hxx:31
void SetPropertyValues(SwPaM &rPaM, const SfxItemPropertySet &rPropSet, const css::uno::Sequence< css::beans::PropertyValue > &rPropertyValues, const SetAttrMode nAttrMode=SetAttrMode::DEFAULT)
virtual css::uno::Reference< css::text::XTextCursor > SAL_CALL createTextCursorByRange(const css::uno::Reference< css::text::XTextRange > &xTextPosition) override
Definition: unotext.cxx:2683
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:144
static bool isGraphicNode(const SwFrameFormat *pFrameFormat)
Definition: unotext.cxx:1513
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: unotext.cxx:2611
SwNodeOffset abs(const SwNodeOffset &a)
Definition: nodeoffset.hxx:32
#define UNO_NAME_ROW_SPAN
Definition: unoprnms.hxx:790
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:315
bool IsValid() const
Definition: unotext.cxx:142
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getEnd() override
Definition: unotext.cxx:877
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
Definition: unotext.cxx:1201
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:205
virtual ~SwXHeadFootText() override
Definition: unotext.cxx:2571
SfxHintId GetId() const
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: unotext.cxx:263
virtual OUString SAL_CALL getImplementationName() override
Definition: unotext.cxx:2321
static bool IsShowChanges(const RedlineFlags eM)
virtual css::uno::Type SAL_CALL getElementType() override
Definition: unotext.cxx:2735
virtual css::uno::Reference< css::text::XTextCursor > SAL_CALL createTextCursor() override
Definition: unoframe.cxx:3261
css::uno::Reference< css::i18n::XExtendedTransliteration > Body
#define CHAR_SOFTHYPHEN
Definition: swtypes.hxx:164
virtual void SAL_CALL addVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &xListener) override
Definition: unotext.cxx:1182
size_type size() const
Definition: docary.hxx:268
virtual OUString SAL_CALL getImplementationName() override
Definition: unotext.cxx:2575
::sw::UnoImplPtr< Impl > m_pImpl
Definition: unotext.hxx:57
sal_Int16 SAL_CALL compareRegionStarts(const css::uno::Reference< css::text::XTextRange > &xR1, const css::uno::Reference< css::text::XTextRange > &xR2) override
Definition: unotext.cxx:1062
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:165
sal_uInt16 sal_Unicode
virtual void SAL_CALL removeVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &xListener) override
Definition: unotext.cxx:1190
virtual sal_Bool SAL_CALL supportsService(const OUString &rServiceName) override
Definition: unotext.cxx:2326
virtual css::uno::Reference< css::text::XTextTable > SAL_CALL convertToTable(css::uno::Sequence< css::uno::Sequence< css::uno::Sequence< css::uno::Reference< css::text::XTextRange > > > > const &rTableRanges, css::uno::Sequence< css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > > const &rCellProperties, css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > const &rRowProperties, css::uno::Sequence< css::beans::PropertyValue > const &rTableProperties) override
Definition: unotext.cxx:2127
virtual const SwStartNode * GetStartNode() const override
Definition: unotext.cxx:2591
SwNodeType GetNodeType() const
Definition: node.hxx:146
SwIndex nContent
Definition: pam.hxx:39
Any SAL_CALL getCaughtException()
SwNodeIndex aStart
Definition: ndindex.hxx:134
SwSectionNode * GetSectionNode()
Definition: section.cxx:952
check if target position is in fly anchored at source range
const OUString & GetName() const
Definition: format.hxx:115
bool GetPositions(SwPaM &rToFill,::sw::TextRangeMode eMode=::sw::TextRangeMode::RequireTextNode) const
Definition: unoobj2.cxx:1066
TextRangeMode
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
SwFrameFormat * m_pHeadFootFormat
Definition: unotext.cxx:2520
virtual void SAL_CALL insertControlCharacter(const css::uno::Reference< css::text::XTextRange > &xRange, sal_Int16 nControlCharacter, sal_Bool bAbsorb) override
Definition: unotext.cxx:390
virtual const SwStartNode * GetStartNode() const
Definition: unotext.cxx:171
bool IsStartNode() const
Definition: node.hxx:626
Mode eMode
SAL_DLLPRIVATE void SetXObject(css::uno::Reference< css::uno::XInterface > const &xObject)
Definition: frmfmt.hxx:172
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:154
uno::Sequence< text::TableColumnSeparator > TableColumnSeparators
Definition: unotext.cxx:2011
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() SAL_OVERRIDE
virtual sal_Bool SAL_CALL hasElements() override
Definition: unotext.cxx:2738
static void lcl_ApplyCellProperties(const sal_Int32 nLeftPos, const uno::Sequence< beans::PropertyValue > &rCellProperties, const uno::Reference< uno::XInterface > &xCell, std::vector< VerticallyMergedCell > &rMergedCells)
Definition: unotext.cxx:2045
void SelectPam(SwPaM &rPam, const bool bExpand)
Definition: unoobj.cxx:111
const css::uno::Sequence< sal_Int8 > & getSeq() const
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:161
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL appendTextContent(const css::uno::Reference< css::text::XTextContent > &xTextContent, const css::uno::Sequence< css::beans::PropertyValue > &rCharacterAndParagraphProperties) override
Definition: unotext.cxx:1501
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
Definition: unotext.cxx:2618
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:137
void DeleteAndInsert(const OUString &rText, const bool bForceExpandHints)
Definition: unoobj2.cxx:802
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:504
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unotext.cxx:2332
static SwTable * FindTable(SwFrameFormat const *const pFormat)
Definition: swtable.cxx:1966
virtual sal_Bool SAL_CALL supportsService(const OUString &rServiceName) override
Definition: unotext.cxx:2580
Style of a layout element.
Definition: frmfmt.hxx:59
virtual OUString SAL_CALL getString() override
Definition: unotext.cxx:892
#define TOOLS_WARN_EXCEPTION(area, stream)
virtual SwUndoId StartUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Opens undo block.
virtual void SAL_CALL copyText(const css::uno::Reference< css::text::XTextCopy > &xSource) override
Definition: unotext.cxx:2251
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
Definition: unotext.cxx:2717
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
static bool lcl_SimilarPosition(const sal_Int32 nPos1, const sal_Int32 nPos2)
Definition: unotext.cxx:1846
int i
bool GoInNode(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:961
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:133
virtual void SAL_CALL insertTextContentAfter(const css::uno::Reference< css::text::XTextContent > &xNewContent, const css::uno::Reference< css::text::XTextContent > &xPredecessor) override
Definition: unotext.cxx:677
const SwPosition * GetPoint() const
Definition: pam.hxx:208
virtual sal_Int64 SAL_CALL getSomething(const css::uno::Sequence< sal_Int8 > &rIdentifier) override
Definition: unotext.cxx:1208
virtual const SwPaM * GetPaM() const override
Definition: unoobj.cxx:661
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
void ConvertCell(const uno::Sequence< uno::Reference< text::XTextRange > > &rCell, std::vector< SwNodeRange > &rRowNodes, SwNodeRange *const pLastCell)
Definition: unotext.cxx:1851
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
Definition: unotext.cxx:2623
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
static sal_Int32 lcl_GetLeftPos(sal_Int32 nCell, TableColumnSeparators const &rRowSeparators)
Definition: unotext.cxx:2035
bool CheckForOwnMember(const SwPaM &rPaM)
Definition: unotext.cxx:975
uno::Reference< text::XTextRange > finishOrAppendParagraph(const uno::Sequence< beans::PropertyValue > &rCharacterAndParagraphProperties, const uno::Reference< text::XTextRange > &xInsertPosition)
Definition: unotext.cxx:1233
SwNodeOffset GetIndex() const
Definition: node.hxx:292
FlyAnchors.
Definition: fmtanchr.hxx:34
void MakeStartIndex(SwIndex *pIdx)
Definition: node.hxx:399
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:206
virtual void PrepareForAttach(css::uno::Reference< css::text::XTextRange > &xRange, SwPaM const &rPam)
Definition: unotext.cxx:161
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
Definition: unotext.cxx:192
uno::Reference< sdbc::XRow > xRow
float u
unsigned char sal_Bool
void AddRule(SwUndoArg eWhat, const OUString &rWith)
Definition: SwRewriter.cxx:25
virtual css::uno::Reference< css::text::XTextCursor > CreateCursor()
Definition: unotext.cxx:177
virtual css::uno::Type SAL_CALL getElementType() override
Definition: unotext.cxx:2496
Object Value
#define COL_POS_FUZZY
Definition: unotext.cxx:1844
virtual void SAL_CALL removeTextContentAfter(const css::uno::Reference< css::text::XTextContent > &xPredecessor) override
Definition: unotext.cxx:784
Marks a node in the document model.
Definition: ndindex.hxx:32
static void lcl_MergeCells(std::vector< VerticallyMergedCell > &rMergedCells)
Definition: unotext.cxx:2106
bool IsEndNode() const
Definition: node.hxx:634
css::uno::Type const & get()
SfxItemPropertySet const & m_rPropSet
Definition: unotext.cxx:83
bool GoInDoc(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:949
const_iterator end() const
tuple index
SwStartNodeType GetStartNodeType() const
Definition: node.hxx:330
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:123
bool StartListening(SvtBroadcaster &rBroadcaster)
SwStartNode * GetStartNode()
Definition: node.hxx:593
SwDoc * m_pDoc
Definition: unotext.cxx:85
const SvXMLTokenMapEntry aTypes[]
Footer
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:113
const SwPosition * Start() const
Definition: pam.hxx:213
virtual ~SwXBodyText() override
Definition: unotext.cxx:2316
virtual css::uno::Reference< css::text::XTextCursor > SAL_CALL createTextCursorByRange(const css::uno::Reference< css::text::XTextRange > &xTextPosition) override
Definition: unotext.cxx:2432
bool XTextRangeToSwPaM(SwUnoInternalPaM &rToFill, const uno::Reference< text::XTextRange > &xTextRange,::sw::TextRangeMode const eMode)
Definition: unoobj2.cxx:1107
SwXText & m_rThis
Definition: unotext.cxx:82
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
constexpr OUStringLiteral cInvalidObject
Definition: unotext.cxx:76
SvtBroadcaster & GetNotifier()
Definition: calbck.hxx:102
virtual const SwPaM * GetPaM() const =0
virtual void SAL_CALL removePropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: unotext.cxx:1174
virtual bool CheckForOwnMemberMeta(const SwPaM &rPam, const bool bAbsorb)
Definition: unotext.cxx:165
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL appendTextPortion(const OUString &rText, const css::uno::Sequence< css::beans::PropertyValue > &rCharacterAndParagraphProperties) override
Definition: unotext.cxx:1428
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &rType) override
Definition: unotext.cxx:2338
const SwDoc * GetDoc() const
Definition: unotext.cxx:132
sal_Int16 ComparePositions(const uno::Reference< text::XTextRange > &xPos1, const uno::Reference< text::XTextRange > &xPos2)
Definition: unotext.cxx:1023
#define CHAR_HARDHYPHEN
Definition: swtypes.hxx:163
#define PROPERTY_MAP_PARAGRAPH
Definition: unomap.hxx:61
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
static css::uno::Sequence< css::beans::PropertyValue > CreateRedlineProperties(SwRangeRedline const &rRedline, bool const bIsStart)
Definition: unoredline.cxx:290
SwUnoCursor & GetCursor()
Definition: unoobj.cxx:658
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL finishParagraph(const css::uno::Sequence< css::beans::PropertyValue > &rCharacterAndParagraphProperties) override
Definition: unotext.cxx:1214
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getStart() override
Definition: unotext.cxx:861
virtual void SAL_CALL removeTextContent(const css::uno::Reference< css::text::XTextContent > &xContent) override
Definition: unotext.cxx:837
virtual void SAL_CALL insertString(const css::uno::Reference< css::text::XTextRange > &xRange, const OUString &aString, sal_Bool bAbsorb) override
Definition: unotext.cxx:284
#define SAL_WARN_IF(condition, area, stream)
virtual void SAL_CALL setPropertyValue(const OUString &rPropertyName, const css::uno::Any &rValue) override
Definition: unotext.cxx:1106
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
SwXBodyText(SwDoc *const pDoc)
Definition: unotext.cxx:2311
bool DontExpandFormat(const SwPosition &rPos, bool bFlag=true)
Definition: docfmt.cxx:1706
virtual bool DelFullPara(SwPaM &)=0
Delete full paragraphs.
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
Definition: unotext.cxx:2477
sal_Int32 GetIndex() const
Definition: index.hxx:91
virtual void SAL_CALL addPropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: unotext.cxx:1166
Header
Impl(SwXText &rThis, SwDoc *const pDoc, const CursorType eType)
Definition: unotext.cxx:88
void SetPropertyValue(SwPaM &rPaM, const SfxItemPropertySet &rPropSet, const OUString &rPropertyName, const css::uno::Any &rValue, const SetAttrMode nAttrMode=SetAttrMode::DEFAULT)
SwXText(SwDoc *const pDoc, const CursorType eType)
Definition: unotext.cxx:123
SwNodes & GetNodes()
Definition: doc.hxx:409
SwSectionFormat * GetFormat() const
Definition: unosect.cxx:190
const SwPosition * End() const
Definition: pam.hxx:218
SwNodeIndex aEnd
Definition: ndindex.hxx:135
static SW_DLLPUBLIC css::uno::Reference< css::text::XTextFrame > CreateXTextFrame(SwDoc &rDoc, SwFrameFormat *pFrameFormat)
Definition: unoframe.cxx:3196
bool IsDescriptor() const
SwTableNode is derived from SwStartNode.
SwUnoPropertyMapProvider aSwMapProvider
Definition: unomap1.cxx:87
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
double getLength(const B2DPolygon &rCandidate)
virtual bool AppendTextNode(SwPosition &rPos)=0
SwStartNodeType
Definition: ndtyp.hxx:50
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:357
virtual void SAL_CALL removeTextContentBefore(const css::uno::Reference< css::text::XTextContent > &xSuccessor) override
Definition: unotext.cxx:732
bool m_bIsValid
Definition: unotext.cxx:86
virtual css::uno::Reference< css::text::XTextContent > SAL_CALL convertToTextFrame(const css::uno::Reference< css::text::XTextRange > &xStart, const css::uno::Reference< css::text::XTextRange > &xEnd, const css::uno::Sequence< css::beans::PropertyValue > &xFrameProperties) override
Definition: unotext.cxx:1529
rtl::Reference< SwXTextCursor > CreateTextCursor(const bool bIgnoreTables=false)
Definition: unotext.cxx:2387
#define SAL_WARN(area, stream)
bool IsTableNode() const
Definition: node.hxx:642
bool DocInsertStringSplitCR(SwDoc &rDoc, const SwPaM &rNewCursor, const OUString &rText, const bool bForceExpandHints)
Ends a section of nodes in the document model.
Definition: node.hxx:343
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:478
static rtl::Reference< SwXParagraphEnumeration > Create(css::uno::Reference< css::text::XText > const &xParent, const std::shared_ptr< SwUnoCursor > &pCursor, const CursorType eType, SwTableBox const *const pTableBox=nullptr)
Definition: unoobj2.cxx:449
virtual const SwRedlineTable & GetRedlineTable() const =0
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
std::pair< const_iterator, bool > insert(Value &&x)
virtual void SAL_CALL setString(const OUString &rString) override
Definition: unotext.cxx:907
#define FN_UNO_REDLINE_NODE_END
Definition: cmdid.h:571
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL insertTextContentWithProperties(const css::uno::Reference< css::text::XTextContent > &xTextContent, const css::uno::Sequence< css::beans::PropertyValue > &rCharacterAndParagraphProperties, const css::uno::Reference< css::text::XTextRange > &xInsertPosition) override
Definition: unotext.cxx:1442
virtual void SAL_CALL insertTextContentBefore(const css::uno::Reference< css::text::XTextContent > &xNewContent, const css::uno::Reference< css::text::XTextContent > &xSuccessor) override
Definition: unotext.cxx:619
virtual void SAL_CALL insertTextContent(const css::uno::Reference< css::text::XTextRange > &xRange, const css::uno::Reference< css::text::XTextContent > &xContent, sal_Bool bAbsorb) override
Definition: unotext.cxx:501
::sw::UnoImplPtr< Impl > m_pImpl
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &rPropertyName) override
Definition: unotext.cxx:1113
css::uno::Reference< css::text::XTextCursor > CreateTextCursor(const bool bIgnoreTables=false)
Definition: unotext.cxx:2631
bool IsTextNode() const
Definition: node.hxx:638
void SetPositions(SwPaM const &rPam)
Definition: unoobj2.cxx:782
virtual css::uno::Reference< css::text::XTextCursor > SAL_CALL createTextCursor() override
Definition: unotext.cxx:2678
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1293
SdrObject * FindSdrObject()
Definition: frmfmt.hxx:140
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL insertTextPortion(const OUString &rText, const css::uno::Sequence< css::beans::PropertyValue > &rCharacterAndParagraphProperties, const css::uno::Reference< css::text::XTextRange > &rTextRange) override
Definition: unotext.cxx:1347
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:856
virtual sal_Bool SAL_CALL hasElements() override
Definition: unotext.cxx:2502
SwFrameFormat & GetHeadFootFormatOrThrow()
Definition: unotext.cxx:2534
void SetAnchor(const SwPosition *pPos)
Definition: atrfrm.cxx:1584
#define PROPERTY_MAP_TEXT
Definition: unomap.hxx:112
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: unotext.cxx:2365
SwTableNode * GetTableNode() const
Definition: swtable.cxx:1973
Base class of the Writer document model elements.
Definition: node.hxx:81
SW_DLLPUBLIC SwFrameFormat * GetFrameFormat()
Definition: unotbl.cxx:2014