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