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