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