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