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