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