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