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