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