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