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