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