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