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