xref: /trunk/main/sw/source/core/unocore/unotext.cxx (revision f1a18c4f)
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 additional 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     catch (...)
1795     {
1796         return pNewFrame;
1797     }
1798     xRet = pNewFrame;
1799     if (bParaBeforeInserted || bParaAfterInserted)
1800     {
1801         const uno::Reference<text::XTextCursor> xFrameTextCursor =
1802             pNewFrame->createTextCursor();
1803         const uno::Reference<XUnoTunnel> xTunnel(xFrameTextCursor,
1804                 uno::UNO_QUERY);
1805         SwXTextCursor *const pFrameCursor =
1806             ::sw::UnoTunnelGetImplementation<SwXTextCursor>(xTunnel);
1807         if (bParaBeforeInserted)
1808         {
1809             // todo: remove paragraph before frame
1810             m_pImpl->m_pDoc->DelFullPara(*pFrameCursor->GetPaM());
1811         }
1812         if (bParaAfterInserted)
1813         {
1814             xFrameTextCursor->gotoEnd(sal_False);
1815             m_pImpl->m_pDoc->DelFullPara(*pFrameCursor->GetPaM());
1816         }
1817     }
1818 
1819     m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
1820     if (bIllegalException || bRuntimeException)
1821     {
1822         m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
1823         if (bIllegalException)
1824         {
1825             lang::IllegalArgumentException aEx;
1826             aEx.Message = sMessage;
1827             throw aEx;
1828         }
1829         else //if(bRuntimeException)
1830         {
1831             uno::RuntimeException aEx;
1832             aEx.Message = sMessage;
1833             throw aEx;
1834         }
1835     }
1836     return xRet;
1837 }
1838 
1839 /*-- 11.05.2006 15:46:26---------------------------------------------------
1840     Move previously imported paragraphs into a new text table.
1841 
1842   -----------------------------------------------------------------------*/
1843 struct VerticallyMergedCell
1844 {
1845     std::vector<uno::Reference< beans::XPropertySet > > aCells;
1846     sal_Int32                                           nLeftPosition;
1847     bool                                                bOpen;
1848 
VerticallyMergedCellVerticallyMergedCell1849     VerticallyMergedCell(uno::Reference< beans::XPropertySet > const& rxCell,
1850             const sal_Int32 nLeft)
1851         : nLeftPosition( nLeft )
1852         , bOpen( true )
1853     {
1854         aCells.push_back( rxCell );
1855     }
1856 };
1857 #define COL_POS_FUZZY 2
lcl_SimilarPosition(const sal_Int32 nPos1,const sal_Int32 nPos2)1858 static bool lcl_SimilarPosition( const sal_Int32 nPos1, const sal_Int32 nPos2 )
1859 {
1860     return abs( nPos1 - nPos2 ) < COL_POS_FUZZY;
1861 }
1862 
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)1863 void SwXText::Impl::ConvertCell(
1864     const bool bFirstCell,
1865     const uno::Sequence< uno::Reference< text::XTextRange > > & rCell,
1866     ::std::vector<SwNodeRange> & rRowNodes,
1867     ::std::auto_ptr< SwPaM > & rpFirstPaM,
1868     SwPaM & rLastPaM,
1869     bool & rbExcept)
1870 {
1871     if (rCell.getLength() != 2)
1872     {
1873         throw lang::IllegalArgumentException();
1874     }
1875     const uno::Reference<text::XTextRange> xStartRange = rCell[0];
1876     const uno::Reference<text::XTextRange> xEndRange = rCell[1];
1877     SwUnoInternalPaM aStartCellPam(*m_pDoc);
1878     SwUnoInternalPaM aEndCellPam(*m_pDoc);
1879 
1880     // !!! TODO - PaMs in tables and sections do not work here -
1881     //     the same applies to PaMs in frames !!!
1882 
1883     if (!::sw::XTextRangeToSwPaM(aStartCellPam, xStartRange) ||
1884         !::sw::XTextRangeToSwPaM(aEndCellPam, xEndRange))
1885     {
1886         throw lang::IllegalArgumentException();
1887     }
1888 
1889     SwNodeRange aTmpRange(aStartCellPam.Start()->nNode,
1890                           aEndCellPam.End()->nNode);
1891     SwNodeRange * pCorrectedRange =
1892         m_pDoc->GetNodes().ExpandRangeForTableBox(aTmpRange);
1893 
1894     if (pCorrectedRange != NULL)
1895     {
1896         SwPaM aNewStartPaM(pCorrectedRange->aStart, 0);
1897         aStartCellPam = aNewStartPaM;
1898 
1899         xub_StrLen nEndLen = 0;
1900         SwTxtNode * pTxtNode = pCorrectedRange->aEnd.GetNode().GetTxtNode();
1901         if (pTxtNode != NULL)
1902             nEndLen = pTxtNode->Len();
1903 
1904         SwPaM aNewEndPaM(pCorrectedRange->aEnd, nEndLen);
1905         aEndCellPam = aNewEndPaM;
1906     }
1907 
1908     /** check the nodes between start and end
1909         it is allowed to have pairs of StartNode/EndNodes
1910      */
1911     if (aStartCellPam.Start()->nNode < aEndCellPam.End()->nNode)
1912     {
1913         // increment on each StartNode and decrement on each EndNode
1914         // we must reach zero at the end and must not go below zero
1915         long nOpenNodeBlock = 0;
1916         SwNodeIndex aCellIndex = aStartCellPam.Start()->nNode;
1917         while (aCellIndex < aEndCellPam.End()->nNode.GetIndex())
1918         {
1919             if (aCellIndex.GetNode().IsStartNode())
1920             {
1921                 ++nOpenNodeBlock;
1922             }
1923             else if (aCellIndex.GetNode().IsEndNode())
1924             {
1925                 --nOpenNodeBlock;
1926             }
1927             if (nOpenNodeBlock < 0)
1928             {
1929                 rbExcept = true;
1930                 break;
1931             }
1932             ++aCellIndex;
1933         }
1934         if (nOpenNodeBlock != 0)
1935         {
1936             rbExcept = true;
1937             return;
1938         }
1939     }
1940 
1941     /** The vector<vector> NodeRanges has to contain consecutive nodes.
1942         In rTableRanges the ranges don't need to be full paragraphs but
1943         they have to follow each other. To process the ranges they
1944         have to be aligned on paragraph borders by inserting paragraph
1945         breaks. Non-consecutive ranges must initiate an exception.
1946      */
1947     if (bFirstCell)
1948     {
1949         // align the beginning - if necessary
1950         if (aStartCellPam.Start()->nContent.GetIndex())
1951         {
1952             m_pDoc->SplitNode(*aStartCellPam.Start(), sal_False);
1953         }
1954     }
1955     else
1956     {
1957         // check the predecessor
1958         const sal_uLong nLastNodeIndex = rLastPaM.End()->nNode.GetIndex();
1959         const sal_uLong nStartCellNodeIndex =
1960             aStartCellPam.Start()->nNode.GetIndex();
1961         const sal_uLong nLastNodeEndIndex = rLastPaM.End()->nNode.GetIndex();
1962         if (nLastNodeIndex == nStartCellNodeIndex)
1963         {
1964             // same node as predecessor then equal nContent?
1965             if (rLastPaM.End()->nContent != aStartCellPam.Start()->nContent)
1966             {
1967                 rbExcept = true;
1968             }
1969             else
1970             {
1971                 m_pDoc->SplitNode(*aStartCellPam.Start(), sal_False);
1972             }
1973         }
1974         else if (nStartCellNodeIndex == (nLastNodeEndIndex + 1))
1975         {
1976             // next paragraph - now the content index of the new should be 0
1977             // and of the old one should be equal to the text length
1978             // but if it isn't we don't care - the cell is being inserted on
1979             // the node border anyway
1980         }
1981         else
1982         {
1983             rbExcept = true;
1984         }
1985     }
1986     // now check if there's a need to insert another paragraph break
1987     if (aEndCellPam.End()->nContent.GetIndex() <
1988             aEndCellPam.End()->nNode.GetNode().GetTxtNode()->Len())
1989     {
1990         m_pDoc->SplitNode(*aEndCellPam.End(), sal_False);
1991         // take care that the new start/endcell is moved to the right position
1992         // aStartCellPam has to point to the start of the new (previous) node
1993         // aEndCellPam has to point to the end of the new (previous) node
1994         aStartCellPam.DeleteMark();
1995         aStartCellPam.Move(fnMoveBackward, fnGoNode);
1996         aStartCellPam.GetPoint()->nContent = 0;
1997         aEndCellPam.DeleteMark();
1998         aEndCellPam.Move(fnMoveBackward, fnGoNode);
1999         aEndCellPam.GetPoint()->nContent =
2000             aEndCellPam.GetNode()->GetTxtNode()->Len();
2001     }
2002 
2003     *rLastPaM.GetPoint() = *aEndCellPam.Start();
2004     if (aStartCellPam.HasMark())
2005     {
2006         rLastPaM.SetMark();
2007         *rLastPaM.GetMark() = *aEndCellPam.End();
2008     }
2009     else
2010     {
2011         rLastPaM.DeleteMark();
2012     }
2013 
2014     SwNodeRange aCellRange(aStartCellPam.Start()->nNode,
2015             aEndCellPam.End()->nNode);
2016     rRowNodes.push_back(aCellRange);
2017     if (bFirstCell)
2018     {
2019         rpFirstPaM.reset(new SwPaM(*aStartCellPam.Start()));
2020     }
2021 }
2022 
2023 typedef uno::Sequence< text::TableColumnSeparator > TableColumnSeparators;
2024 
2025 static void
lcl_ApplyRowProperties(uno::Sequence<beans::PropertyValue> const & rRowProperties,uno::Any const & rRow,TableColumnSeparators & rRowSeparators)2026 lcl_ApplyRowProperties(
2027     uno::Sequence<beans::PropertyValue> const& rRowProperties,
2028     uno::Any const& rRow,
2029     TableColumnSeparators & rRowSeparators)
2030 {
2031     uno::Reference< beans::XPropertySet > xRow;
2032     rRow >>= xRow;
2033     const beans::PropertyValue* pProperties = rRowProperties.getConstArray();
2034     for (sal_Int32 nProperty = 0; nProperty < rRowProperties.getLength();
2035          ++nProperty)
2036     {
2037         if (pProperties[ nProperty ].Name.equalsAsciiL(
2038                 RTL_CONSTASCII_STRINGPARAM("TableColumnSeparators")))
2039         {
2040             // add the separators to access the cell's positions
2041             // for vertical merging later
2042             TableColumnSeparators aSeparators;
2043             pProperties[ nProperty ].Value >>= aSeparators;
2044             rRowSeparators = aSeparators;
2045         }
2046         xRow->setPropertyValue(
2047             pProperties[ nProperty ].Name, pProperties[ nProperty ].Value);
2048     }
2049 }
2050 
2051 #ifdef DEBUG
2052 //-->debug cell properties of all rows
2053 static void
lcl_DebugCellProperties(const uno::Sequence<uno::Sequence<uno::Sequence<beans::PropertyValue>>> & rCellProperties)2054 lcl_DebugCellProperties(
2055     const uno::Sequence< uno::Sequence< uno::Sequence<
2056         beans::PropertyValue > > >& rCellProperties)
2057 {
2058     ::rtl::OUString sNames;
2059     for (sal_Int32  nDebugRow = 0; nDebugRow < rCellProperties.getLength();
2060          ++nDebugRow)
2061     {
2062         const uno::Sequence< beans::PropertyValues > aDebugCurrentRow =
2063             rCellProperties[nDebugRow];
2064         sal_Int32 nDebugCells = aDebugCurrentRow.getLength();
2065         (void) nDebugCells;
2066         for (sal_Int32  nDebugCell = 0; nDebugCell < nDebugCells;
2067              ++nDebugCell)
2068         {
2069             const uno::Sequence< beans::PropertyValue >&
2070                 rDebugCellProperties = aDebugCurrentRow[nDebugCell];
2071             const sal_Int32 nDebugCellProperties =
2072                 rDebugCellProperties.getLength();
2073             for (sal_Int32  nDebugProperty = 0;
2074                  nDebugProperty < nDebugCellProperties; ++nDebugProperty)
2075             {
2076                 const ::rtl::OUString sName =
2077                     rDebugCellProperties[nDebugProperty].Name;
2078                 sNames += sName;
2079                 sNames += ::rtl::OUString('-');
2080             }
2081             sNames += ::rtl::OUString('+');
2082         }
2083         sNames += ::rtl::OUString('|');
2084     }
2085     (void)sNames;
2086 }
2087 //--<
2088 #endif
2089 
2090 
2091 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)2092 lcl_ApplyCellProperties(
2093     const sal_Int32 nCell,
2094     TableColumnSeparators const& rRowSeparators,
2095     const uno::Sequence< beans::PropertyValue >& rCellProperties,
2096     uno::Reference< uno::XInterface > xCell,
2097     ::std::vector<VerticallyMergedCell> & rMergedCells)
2098 {
2099     const sal_Int32 nCellProperties = rCellProperties.getLength();
2100     const uno::Reference< beans::XPropertySet > xCellPS(xCell, uno::UNO_QUERY);
2101     for (sal_Int32 nProperty = 0; nProperty < nCellProperties; ++nProperty)
2102     {
2103         const OUString & rName  = rCellProperties[nProperty].Name;
2104         const uno::Any & rValue = rCellProperties[nProperty].Value;
2105         if (rName.equalsAscii("VerticalMerge"))
2106         {
2107             // determine left border position
2108             // add the cell to a queue of merged cells
2109             sal_Bool bMerge = sal_False;
2110             rValue >>= bMerge;
2111             sal_Int32 nLeftPos = -1;
2112             if (!nCell)
2113             {
2114                 nLeftPos = 0;
2115             }
2116             else if (rRowSeparators.getLength() >= nCell)
2117             {
2118                 const text::TableColumnSeparator* pSeparators =
2119                     rRowSeparators.getConstArray();
2120                 nLeftPos = pSeparators[nCell - 1].Position;
2121             }
2122             if (bMerge)
2123             {
2124                 // 'close' all the cell with the same left position
2125                 // if separate vertical merges in the same column exist
2126                 if (rMergedCells.size())
2127                 {
2128                     std::vector<VerticallyMergedCell>::iterator aMergedIter =
2129                         rMergedCells.begin();
2130                     while (aMergedIter != rMergedCells.end())
2131                     {
2132                         if (lcl_SimilarPosition(aMergedIter->nLeftPosition,
2133                                     nLeftPos))
2134                         {
2135                             aMergedIter->bOpen = false;
2136                         }
2137                         ++aMergedIter;
2138                     }
2139                 }
2140                 // add the new group of merged cells
2141                 rMergedCells.push_back(VerticallyMergedCell(xCellPS, nLeftPos));
2142             }
2143             else
2144             {
2145                 // find the cell that
2146                 DBG_ASSERT(rMergedCells.size(),
2147                         "the first merged cell is missing");
2148                 if (rMergedCells.size())
2149                 {
2150                     std::vector<VerticallyMergedCell>::iterator aMergedIter =
2151                         rMergedCells.begin();
2152 #if OSL_DEBUG_LEVEL > 1
2153                     bool bDbgFound = false;
2154 #endif
2155                     while (aMergedIter != rMergedCells.end())
2156                     {
2157                         if (aMergedIter->bOpen &&
2158                             lcl_SimilarPosition(aMergedIter->nLeftPosition,
2159                                 nLeftPos))
2160                         {
2161                             aMergedIter->aCells.push_back( xCellPS );
2162 #if OSL_DEBUG_LEVEL > 1
2163                             bDbgFound = true;
2164 #endif
2165                         }
2166                         ++aMergedIter;
2167                     }
2168 #if OSL_DEBUG_LEVEL > 1
2169                     DBG_ASSERT( bDbgFound,
2170                             "couldn't find first vertically merged cell" );
2171 #endif
2172                 }
2173             }
2174         }
2175         else
2176         {
2177             try
2178             {
2179                 xCellPS->setPropertyValue(rName, rValue);
2180             }
2181             catch (uno::Exception const& )
2182             {
2183                 // Apply the paragraph and char properties to the cell's content
2184                 const uno::Reference< text::XText > xCellText(xCell,
2185                         uno::UNO_QUERY);
2186                 const uno::Reference< text::XTextCursor > xCellCurs =
2187                     xCellText->createTextCursor();
2188                 xCellCurs->gotoStart( sal_False );
2189                 xCellCurs->gotoEnd( sal_True );
2190                 const uno::Reference< beans::XPropertyState >
2191                     xCellTextPropState(xCellCurs, uno::UNO_QUERY);
2192                 const beans::PropertyState state = xCellTextPropState->getPropertyState(rName);
2193                 if (state == beans::PropertyState_DEFAULT_VALUE)
2194                 {
2195                     const uno::Reference< beans::XPropertySet >
2196                         xCellTextProps(xCellCurs, uno::UNO_QUERY);
2197                     xCellTextProps->setPropertyValue(rName, rValue);
2198                 }
2199             }
2200         }
2201     }
2202 }
2203 
2204 static void
lcl_MergeCells(::std::vector<VerticallyMergedCell> & rMergedCells)2205 lcl_MergeCells(::std::vector<VerticallyMergedCell> & rMergedCells)
2206 {
2207     if (rMergedCells.size())
2208     {
2209         std::vector<VerticallyMergedCell>::iterator aMergedIter =
2210             rMergedCells.begin();
2211         while (aMergedIter != rMergedCells.end())
2212         {
2213             sal_Int32 nCellCount =
2214                 static_cast<sal_Int32>(aMergedIter->aCells.size());
2215             std::vector<uno::Reference< beans::XPropertySet > >::iterator
2216                 aCellIter = aMergedIter->aCells.begin();
2217             bool bFirstCell = true;
2218             // the first of the cells gets the number of cells set as RowSpan
2219             // the others get the inverted number of remaining merged cells
2220             // (3,-2,-1)
2221             while (aCellIter != aMergedIter->aCells.end())
2222             {
2223                 (*aCellIter)->setPropertyValue(
2224                     C2U(SW_PROP_NAME_STR(UNO_NAME_ROW_SPAN)),
2225                     uno::makeAny(nCellCount));
2226                 if (bFirstCell)
2227                 {
2228                     nCellCount *= -1;
2229                     bFirstCell = false;
2230                 }
2231                 ++nCellCount;
2232                 ++aCellIter;
2233             }
2234             ++aMergedIter;
2235         }
2236     }
2237 }
2238 
2239 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)2240 SwXText::convertToTable(
2241     const uno::Sequence< uno::Sequence< uno::Sequence<
2242         uno::Reference< text::XTextRange > > > >& rTableRanges,
2243     const uno::Sequence< uno::Sequence< uno::Sequence<
2244         beans::PropertyValue > > >& rCellProperties,
2245     const uno::Sequence< uno::Sequence< beans::PropertyValue > >&
2246         rRowProperties,
2247     const uno::Sequence< beans::PropertyValue >& rTableProperties)
2248 throw (lang::IllegalArgumentException, uno::RuntimeException)
2249 {
2250     vos::OGuard aGuard(Application::GetSolarMutex());
2251 
2252     if(!IsValid())
2253     {
2254         throw  uno::RuntimeException();
2255     }
2256 
2257     //at first collect the text ranges as SwPaMs
2258     const uno::Sequence< uno::Sequence< uno::Reference< text::XTextRange > > >*
2259         pTableRanges = rTableRanges.getConstArray();
2260     std::auto_ptr < SwPaM > pFirstPaM;
2261     std::vector< std::vector<SwNodeRange> > aTableNodes;
2262     bool bExcept = false;
2263     SwPaM aLastPaM(m_pImpl->m_pDoc->GetNodes());
2264     for (sal_Int32 nRow = 0; !bExcept && (nRow < rTableRanges.getLength());
2265             ++nRow)
2266     {
2267         std::vector<SwNodeRange> aRowNodes;
2268         const uno::Sequence< uno::Reference< text::XTextRange > >* pRow =
2269             pTableRanges[nRow].getConstArray();
2270         const sal_Int32 nCells(pTableRanges[nRow].getLength());
2271 
2272         for (sal_Int32 nCell = 0; nCell < nCells; ++nCell)
2273         {
2274             m_pImpl->ConvertCell((nCell == 0) && (nRow == 0), pRow[nCell],
2275                 aRowNodes, pFirstPaM, aLastPaM, bExcept);
2276         }
2277         aTableNodes.push_back(aRowNodes);
2278     }
2279 
2280     if(bExcept)
2281     {
2282         m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
2283         throw lang::IllegalArgumentException();
2284     }
2285 
2286     std::vector< TableColumnSeparators >
2287         aRowSeparators(rRowProperties.getLength());
2288     std::vector<VerticallyMergedCell> aMergedCells;
2289 
2290     SwTable const*const pTable = m_pImpl->m_pDoc->TextToTable( aTableNodes );
2291     SwXTextTable *const pTextTable = new SwXTextTable( *pTable->GetFrmFmt() );
2292     const uno::Reference< text::XTextTable > xRet = pTextTable;
2293     const uno::Reference< beans::XPropertySet > xPrSet = pTextTable;
2294     // set properties to the table
2295     // catch lang::WrappedTargetException and lang::IndexOutOfBoundsException
2296     try
2297     {
2298         //apply table properties
2299         const beans::PropertyValue* pTableProperties =
2300             rTableProperties.getConstArray();
2301         for (sal_Int32 nProperty = 0; nProperty < rTableProperties.getLength();
2302              ++nProperty)
2303         {
2304             try
2305             {
2306                 xPrSet->setPropertyValue( pTableProperties[nProperty].Name,
2307                         pTableProperties[nProperty].Value );
2308             }
2309             catch ( uno::Exception const& e )
2310             {
2311 #if DEBUG
2312                 std::clog << "Exception when setting property: ";
2313                 std::clog << rtl::OUStringToOString(
2314                     pTableProperties[nProperty].Name, RTL_TEXTENCODING_UTF8)
2315                     .getStr();
2316                 std::clog << ". Message: ";
2317                 std::clog << rtl::OUStringToOString( e.Message,
2318                     RTL_TEXTENCODING_UTF8 ).getStr();
2319                 std::clog << std::endl;
2320 #endif
2321             }
2322         }
2323 
2324         //apply row properties
2325         const uno::Reference< table::XTableRows >  xRows = xRet->getRows();
2326 
2327         const beans::PropertyValues* pRowProperties =
2328             rRowProperties.getConstArray();
2329         for (sal_Int32 nRow = 0; nRow < xRows->getCount(); ++nRow)
2330         {
2331             if( nRow >= rRowProperties.getLength())
2332             {
2333                 break;
2334             }
2335             lcl_ApplyRowProperties(pRowProperties[nRow],
2336                 xRows->getByIndex(nRow), aRowSeparators[nRow]);
2337         }
2338 
2339 #ifdef DEBUG
2340         lcl_DebugCellProperties(rCellProperties);
2341 #endif
2342 
2343         //apply cell properties
2344         for (sal_Int32 nRow = 0; nRow < rCellProperties.getLength(); ++nRow)
2345         {
2346             const uno::Sequence< beans::PropertyValues > aCurrentRow =
2347                 rCellProperties[nRow];
2348             sal_Int32 nCells = aCurrentRow.getLength();
2349             for (sal_Int32  nCell = 0; nCell < nCells; ++nCell)
2350             {
2351                 lcl_ApplyCellProperties(nCell,
2352                     aRowSeparators[nRow], aCurrentRow[nCell],
2353                     pTextTable->getCellByPosition(nCell, nRow),
2354                     aMergedCells);
2355             }
2356         }
2357         // now that the cell properties are set the vertical merge values
2358         // have to be applied
2359         lcl_MergeCells(aMergedCells);
2360     }
2361     catch( const lang::WrappedTargetException& rWrapped )
2362     {
2363         (void)rWrapped;
2364     }
2365     catch ( const lang::IndexOutOfBoundsException& rBounds )
2366     {
2367         (void)rBounds;
2368     }
2369 
2370     return xRet;
2371 }
2372 
2373 
2374 void SAL_CALL
copyText(const uno::Reference<text::XTextCopy> & xSource)2375 SwXText::copyText(
2376     const uno::Reference< text::XTextCopy >& xSource )
2377 throw (uno::RuntimeException)
2378 {
2379     vos::OGuard g(Application::GetSolarMutex());
2380 
2381     uno::Reference< text::XText > const xText(xSource, uno::UNO_QUERY_THROW);
2382     uno::Reference< text::XTextCursor > const xCursor =
2383         xText->createTextCursor();
2384     xCursor->gotoEnd( sal_True );
2385 
2386     uno::Reference< lang::XUnoTunnel > const xCursorTunnel(xCursor,
2387         uno::UNO_QUERY_THROW);
2388 
2389     OTextCursorHelper *const pCursor =
2390         ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xCursorTunnel);
2391     if (!pCursor)
2392     {
2393         throw uno::RuntimeException();
2394     }
2395 
2396     SwNodeIndex rNdIndex( *GetStartNode( ), 1 );
2397     SwPosition rPos( rNdIndex );
2398     m_pImpl->m_pDoc->CopyRange( *pCursor->GetPaM(), rPos, false );
2399 }
2400 
2401 
2402 /******************************************************************
2403  * SwXBodyText
2404  ******************************************************************/
SwXBodyText(SwDoc * const pDoc)2405 SwXBodyText::SwXBodyText(SwDoc *const pDoc)
2406     : SwXText(pDoc, CURSOR_BODY)
2407 {
2408 }
2409 
2410 /*-- 10.12.98 11:17:27---------------------------------------------------
2411 
2412   -----------------------------------------------------------------------*/
~SwXBodyText()2413 SwXBodyText::~SwXBodyText()
2414 {
2415 
2416 }
2417 /* -----------------------------06.04.00 16:33--------------------------------
2418 
2419  ---------------------------------------------------------------------------*/
2420 OUString SAL_CALL
getImplementationName()2421 SwXBodyText::getImplementationName() throw (uno::RuntimeException)
2422 {
2423 	return C2U("SwXBodyText");
2424 }
2425 /* -----------------------------06.04.00 16:33--------------------------------
2426 
2427  ---------------------------------------------------------------------------*/
2428 static char const*const g_ServicesBodyText[] =
2429 {
2430     "com.sun.star.text.Text",
2431 };
2432 static const size_t g_nServicesBodyText(
2433     sizeof(g_ServicesBodyText)/sizeof(g_ServicesBodyText[0]));
2434 
supportsService(const OUString & rServiceName)2435 sal_Bool SAL_CALL SwXBodyText::supportsService(const OUString& rServiceName)
2436 throw (uno::RuntimeException)
2437 {
2438     return ::sw::SupportsServiceImpl(
2439             g_nServicesBodyText, g_ServicesBodyText, rServiceName);
2440 }
2441 
2442 uno::Sequence< OUString > SAL_CALL
getSupportedServiceNames()2443 SwXBodyText::getSupportedServiceNames() throw (uno::RuntimeException)
2444 {
2445     return ::sw::GetSupportedServiceNamesImpl(
2446             g_nServicesBodyText, g_ServicesBodyText);
2447 }
2448 
2449 /*-- 10.12.98 11:17:27---------------------------------------------------
2450 
2451   -----------------------------------------------------------------------*/
2452 uno::Any SAL_CALL
queryAggregation(const uno::Type & rType)2453 SwXBodyText::queryAggregation(const uno::Type& rType)
2454 throw (uno::RuntimeException)
2455 {
2456 	uno::Any aRet;
2457     if (rType == container::XEnumerationAccess::static_type())
2458     {
2459         aRet <<= uno::Reference< container::XEnumerationAccess >(this);
2460     }
2461     else if (rType == container::XElementAccess::static_type())
2462     {
2463         aRet <<= uno::Reference< container::XElementAccess >(this);
2464     }
2465     else if (rType == lang::XServiceInfo::static_type())
2466     {
2467         aRet <<= uno::Reference< lang::XServiceInfo >(this);
2468     }
2469     else
2470     {
2471         aRet = SwXText::queryInterface( rType );
2472     }
2473 	if(aRet.getValueType() == ::getCppuVoidType())
2474     {
2475 		aRet = OWeakAggObject::queryAggregation( rType );
2476     }
2477 	return aRet;
2478 }
2479 
2480 /*-- 10.12.98 11:17:28---------------------------------------------------
2481 
2482   -----------------------------------------------------------------------*/
2483 uno::Sequence< uno::Type > SAL_CALL
getTypes()2484 SwXBodyText::getTypes() throw (uno::RuntimeException)
2485 {
2486     const uno::Sequence< uno::Type > aTypes = SwXBodyText_Base::getTypes();
2487     const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
2488     return ::comphelper::concatSequences(aTypes, aTextTypes);
2489 }
2490 /* -----------------------------21.03.00 15:39--------------------------------
2491 
2492  ---------------------------------------------------------------------------*/
2493 uno::Sequence< sal_Int8 > SAL_CALL
getImplementationId()2494 SwXBodyText::getImplementationId() throw (uno::RuntimeException)
2495 {
2496     vos::OGuard aGuard(Application::GetSolarMutex());
2497     static uno::Sequence< sal_Int8 > aId( 16 );
2498     static sal_Bool bInit = sal_False;
2499     if(!bInit)
2500     {
2501         rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
2502         bInit = sal_True;
2503     }
2504     return aId;
2505 }
2506 /*-- 10.12.98 11:17:28---------------------------------------------------
2507 
2508   -----------------------------------------------------------------------*/
2509 uno::Any SAL_CALL
queryInterface(const uno::Type & rType)2510 SwXBodyText::queryInterface(const uno::Type& rType)
2511 throw (uno::RuntimeException)
2512 {
2513     const uno::Any ret = SwXText::queryInterface(rType);
2514     return (ret.getValueType() == ::getCppuVoidType())
2515         ?   SwXBodyText_Base::queryInterface(rType)
2516         :   ret;
2517 }
2518 /* -----------------------------05.01.00 11:07--------------------------------
2519 
2520  ---------------------------------------------------------------------------*/
CreateTextCursor(const bool bIgnoreTables)2521 SwXTextCursor * SwXBodyText::CreateTextCursor(const bool bIgnoreTables)
2522 {
2523     if(!IsValid())
2524     {
2525         return 0;
2526     }
2527 
2528     // the cursor has to skip tables contained in this text
2529     SwPaM aPam(GetDoc()->GetNodes().GetEndOfContent());
2530     aPam.Move( fnMoveBackward, fnGoDoc );
2531     if (!bIgnoreTables)
2532     {
2533         SwTableNode * pTblNode = aPam.GetNode()->FindTableNode();
2534         SwCntntNode * pCont = 0;
2535         while (pTblNode)
2536         {
2537             aPam.GetPoint()->nNode = *pTblNode->EndOfSectionNode();
2538             pCont = GetDoc()->GetNodes().GoNext(&aPam.GetPoint()->nNode);
2539             pTblNode = pCont->FindTableNode();
2540         }
2541         if (pCont)
2542         {
2543             aPam.GetPoint()->nContent.Assign(pCont, 0);
2544         }
2545     }
2546     return new SwXTextCursor(*GetDoc(), this, CURSOR_BODY, *aPam.GetPoint());
2547 }
2548 
2549 /*-- 10.12.98 11:17:29---------------------------------------------------
2550 
2551   -----------------------------------------------------------------------*/
2552 uno::Reference< text::XTextCursor > SAL_CALL
createTextCursor()2553 SwXBodyText::createTextCursor() throw (uno::RuntimeException)
2554 {
2555 	vos::OGuard aGuard(Application::GetSolarMutex());
2556 
2557     const uno::Reference< text::XTextCursor > xRef(
2558             static_cast<text::XWordCursor*>(CreateTextCursor(false)) );
2559     if (!xRef.is())
2560 	{
2561 		uno::RuntimeException aRuntime;
2562 		aRuntime.Message = C2U(cInvalidObject);
2563 		throw aRuntime;
2564 	}
2565 	return xRef;
2566 }
2567 /*-- 10.12.98 11:17:29---------------------------------------------------
2568 
2569   -----------------------------------------------------------------------*/
2570 uno::Reference< text::XTextCursor > SAL_CALL
createTextCursorByRange(const uno::Reference<text::XTextRange> & xTextPosition)2571 SwXBodyText::createTextCursorByRange(
2572     const uno::Reference< text::XTextRange > & xTextPosition)
2573 throw (uno::RuntimeException)
2574 {
2575 	vos::OGuard aGuard(Application::GetSolarMutex());
2576 
2577 	if(!IsValid())
2578 	{
2579 		uno::RuntimeException aRuntime;
2580 		aRuntime.Message = C2U(cInvalidObject);
2581 		throw aRuntime;
2582 	}
2583 
2584 	uno::Reference< text::XTextCursor >  aRef;
2585 	SwUnoInternalPaM aPam(*GetDoc());
2586     if (::sw::XTextRangeToSwPaM(aPam, xTextPosition))
2587 	{
2588 		SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
2589 
2590         SwStartNode* p1 = aPam.GetNode()->StartOfSectionNode();
2591 		//document starts with a section?
2592 		while(p1->IsSectionNode())
2593 		{
2594             p1 = p1->StartOfSectionNode();
2595 		}
2596         SwStartNode *const p2 = rNode.StartOfSectionNode();
2597 
2598 		if(p1 == p2)
2599         {
2600             aRef = static_cast<text::XWordCursor*>(
2601                     new SwXTextCursor(*GetDoc(), this, CURSOR_BODY,
2602                         *aPam.GetPoint(), aPam.GetMark()));
2603         }
2604 	}
2605 	if(!aRef.is())
2606     {
2607 		throw uno::RuntimeException();
2608     }
2609 	return aRef;
2610 }
2611 
2612 /*-- 10.12.98 11:17:30---------------------------------------------------
2613 
2614   -----------------------------------------------------------------------*/
2615 uno::Reference< container::XEnumeration > SAL_CALL
createEnumeration()2616 SwXBodyText::createEnumeration()
2617 throw (uno::RuntimeException)
2618 {
2619 	vos::OGuard aGuard(Application::GetSolarMutex());
2620 
2621     if (!IsValid())
2622 	{
2623 		uno::RuntimeException aRuntime;
2624 		aRuntime.Message = C2U(cInvalidObject);
2625 		throw aRuntime;
2626 	}
2627 
2628     SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
2629     SwPosition aPos(rNode);
2630     ::std::auto_ptr<SwUnoCrsr> pUnoCursor(
2631         GetDoc()->CreateUnoCrsr(aPos, sal_False));
2632     pUnoCursor->Move(fnMoveBackward, fnGoDoc);
2633     const uno::Reference< container::XEnumeration > xRet
2634         = new SwXParagraphEnumeration(this, pUnoCursor, CURSOR_BODY);
2635     return xRet;
2636 }
2637 
2638 /* -----------------18.12.98 13:36-------------------
2639  *
2640  * --------------------------------------------------*/
2641 uno::Type SAL_CALL
getElementType()2642 SwXBodyText::getElementType() throw (uno::RuntimeException)
2643 {
2644     return text::XTextRange::static_type();
2645 }
2646 /* -----------------18.12.98 13:36-------------------
2647  *
2648  * --------------------------------------------------*/
2649 sal_Bool SAL_CALL
hasElements()2650 SwXBodyText::hasElements() throw (uno::RuntimeException)
2651 {
2652 	vos::OGuard aGuard(Application::GetSolarMutex());
2653 
2654     if (!IsValid())
2655 	{
2656 		uno::RuntimeException aRuntime;
2657 		aRuntime.Message = C2U(cInvalidObject);
2658 		throw aRuntime;
2659 	}
2660 
2661     return sal_True;
2662 }
2663 
2664 /******************************************************************
2665  *	SwXHeadFootText
2666  ******************************************************************/
2667 
2668 class SwXHeadFootText::Impl
2669     : public SwClient
2670 {
2671 
2672 public:
2673 
2674     bool                        m_bIsHeader;
2675 
Impl(SwXHeadFootText &,SwFrmFmt & rHeadFootFmt,const bool bIsHeader)2676     Impl(   SwXHeadFootText & /*rThis*/,
2677             SwFrmFmt & rHeadFootFmt, const bool bIsHeader)
2678         : SwClient(& rHeadFootFmt)
2679         , m_bIsHeader(bIsHeader)
2680     {
2681     }
2682 
GetHeadFootFmt() const2683     SwFrmFmt * GetHeadFootFmt() const {
2684         return static_cast<SwFrmFmt*>(
2685                 const_cast<SwModify*>(GetRegisteredIn()));
2686     }
2687 
GetHeadFootFmtOrThrow()2688     SwFrmFmt & GetHeadFootFmtOrThrow() {
2689         SwFrmFmt *const pFmt( GetHeadFootFmt() );
2690         if (!pFmt) {
2691             throw uno::RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
2692                     "SwXHeadFootText: disposed or invalid")), 0);
2693         }
2694         return *pFmt;
2695     }
2696 protected:
2697     // SwClient
2698     virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew);
2699 
2700 };
2701 
2702 /*-- 11.12.98 10:14:51---------------------------------------------------
2703 
2704   -----------------------------------------------------------------------*/
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)2705 void SwXHeadFootText::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
2706 {
2707     ClientModify(this, pOld, pNew);
2708 }
2709 
IsXHeadFootText(SwClient * const pClient)2710 bool SwXHeadFootText::IsXHeadFootText(SwClient *const pClient)
2711 {
2712     return 0 != dynamic_cast<SwXHeadFootText::Impl*>(pClient);
2713 }
2714 
2715 uno::Reference< text::XText >
CreateXHeadFootText(SwFrmFmt & rHeadFootFmt,const bool bIsHeader)2716 SwXHeadFootText::CreateXHeadFootText(
2717         SwFrmFmt & rHeadFootFmt, const bool bIsHeader)
2718 {
2719     // re-use existing SwXHeadFootText
2720     // #i105557#: do not iterate over the registered clients: race condition
2721     uno::Reference< text::XText > xText(rHeadFootFmt.GetXObject(),
2722             uno::UNO_QUERY);
2723     if (!xText.is())
2724     {
2725         SwXHeadFootText *const pXHFT(
2726                 new SwXHeadFootText(rHeadFootFmt, bIsHeader));
2727         xText.set(pXHFT);
2728         rHeadFootFmt.SetXObject(xText);
2729     }
2730     return xText;
2731 }
2732 
2733 /*-- 11.12.98 10:14:48---------------------------------------------------
2734 
2735   -----------------------------------------------------------------------*/
SwXHeadFootText(SwFrmFmt & rHeadFootFmt,const bool bIsHeader)2736 SwXHeadFootText::SwXHeadFootText(SwFrmFmt & rHeadFootFmt, const bool bIsHeader)
2737     : SwXText(rHeadFootFmt.GetDoc(),
2738             (bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER)
2739     , m_pImpl( new SwXHeadFootText::Impl(*this, rHeadFootFmt, bIsHeader) )
2740 {
2741 }
2742 
2743 /*-- 11.12.98 10:14:48---------------------------------------------------
2744 
2745   -----------------------------------------------------------------------*/
~SwXHeadFootText()2746 SwXHeadFootText::~SwXHeadFootText()
2747 {
2748 }
2749 
2750 /* -----------------------------06.04.00 16:40--------------------------------
2751 
2752  ---------------------------------------------------------------------------*/
2753 OUString SAL_CALL
getImplementationName()2754 SwXHeadFootText::getImplementationName() throw (uno::RuntimeException)
2755 {
2756 	return C2U("SwXHeadFootText");
2757 }
2758 
2759 /* -----------------------------06.04.00 16:40--------------------------------
2760 
2761  ---------------------------------------------------------------------------*/
2762 static char const*const g_ServicesHeadFootText[] =
2763 {
2764     "com.sun.star.text.Text",
2765 };
2766 static const size_t g_nServicesHeadFootText(
2767     sizeof(g_ServicesHeadFootText)/sizeof(g_ServicesHeadFootText[0]));
2768 
supportsService(const OUString & rServiceName)2769 sal_Bool SAL_CALL SwXHeadFootText::supportsService(const OUString& rServiceName)
2770 throw (uno::RuntimeException)
2771 {
2772     return ::sw::SupportsServiceImpl(
2773             g_nServicesHeadFootText, g_ServicesHeadFootText, rServiceName);
2774 }
2775 
2776 uno::Sequence< OUString > SAL_CALL
getSupportedServiceNames()2777 SwXHeadFootText::getSupportedServiceNames() throw (uno::RuntimeException)
2778 {
2779     return ::sw::GetSupportedServiceNamesImpl(
2780             g_nServicesHeadFootText, g_ServicesHeadFootText);
2781 }
2782 
2783 /*-- 11.12.98 10:14:49---------------------------------------------------
2784 
2785   -----------------------------------------------------------------------*/
GetStartNode() const2786 const SwStartNode *SwXHeadFootText::GetStartNode() const
2787 {
2788 	const SwStartNode *pSttNd = 0;
2789     SwFrmFmt *const pHeadFootFmt = m_pImpl->GetHeadFootFmt();
2790 	if(pHeadFootFmt)
2791 	{
2792 		const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt();
2793 		if( rFlyCntnt.GetCntntIdx() )
2794         {
2795 			pSttNd = rFlyCntnt.GetCntntIdx()->GetNode().GetStartNode();
2796         }
2797 	}
2798 	return pSttNd;
2799 }
2800 
2801 uno::Reference< text::XTextCursor >
CreateCursor()2802 SwXHeadFootText::CreateCursor() throw (uno::RuntimeException)
2803 {
2804 	return createTextCursor();
2805 }
2806 /* -----------------------------21.03.00 15:39--------------------------------
2807 
2808  ---------------------------------------------------------------------------*/
2809 uno::Sequence< uno::Type > SAL_CALL
getTypes()2810 SwXHeadFootText::getTypes() throw (uno::RuntimeException)
2811 {
2812     const uno::Sequence< uno::Type > aTypes = SwXHeadFootText_Base::getTypes();
2813     const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
2814     return ::comphelper::concatSequences(aTypes, aTextTypes);
2815 }
2816 
2817 /* -----------------------------21.03.00 15:39--------------------------------
2818 
2819  ---------------------------------------------------------------------------*/
2820 uno::Sequence< sal_Int8 > SAL_CALL
getImplementationId()2821 SwXHeadFootText::getImplementationId() throw (uno::RuntimeException)
2822 {
2823     vos::OGuard aGuard(Application::GetSolarMutex());
2824     static uno::Sequence< sal_Int8 > aId( 16 );
2825     static sal_Bool bInit = sal_False;
2826     if(!bInit)
2827     {
2828         rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
2829         bInit = sal_True;
2830     }
2831     return aId;
2832 }
2833 /* -----------------------------21.03.00 15:46--------------------------------
2834 
2835  ---------------------------------------------------------------------------*/
2836 uno::Any SAL_CALL
queryInterface(const uno::Type & rType)2837 SwXHeadFootText::queryInterface(const uno::Type& rType)
2838 throw (uno::RuntimeException)
2839 {
2840     const uno::Any ret = SwXHeadFootText_Base::queryInterface(rType);
2841     return (ret.getValueType() == ::getCppuVoidType())
2842         ?   SwXText::queryInterface(rType)
2843         :   ret;
2844 }
2845 
2846 /*-- 11.12.98 10:14:50---------------------------------------------------
2847 
2848   -----------------------------------------------------------------------*/
2849 uno::Reference< text::XTextCursor > SAL_CALL
createTextCursor()2850 SwXHeadFootText::createTextCursor() throw (uno::RuntimeException)
2851 {
2852 	vos::OGuard aGuard(Application::GetSolarMutex());
2853 
2854     SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() );
2855 
2856     uno::Reference< text::XTextCursor > xRet;
2857     const SwFmtCntnt& rFlyCntnt = rHeadFootFmt.GetCntnt();
2858     const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
2859     SwPosition aPos(rNode);
2860     SwXTextCursor *const pXCursor = new SwXTextCursor(*GetDoc(), this,
2861             (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER, aPos);
2862     SwUnoCrsr *const pUnoCrsr = pXCursor->GetCursor();
2863     pUnoCrsr->Move(fnMoveForward, fnGoNode);
2864 
2865     // save current start node to be able to check if there is content
2866     // after the table - otherwise the cursor would be in the body text!
2867     SwStartNode const*const pOwnStartNode = rNode.FindSttNodeByType(
2868             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
2869     // is there a table here?
2870     SwTableNode* pTblNode = pUnoCrsr->GetNode()->FindTableNode();
2871     SwCntntNode* pCont = 0;
2872     while (pTblNode)
2873     {
2874         pUnoCrsr->GetPoint()->nNode = *pTblNode->EndOfSectionNode();
2875         pCont = GetDoc()->GetNodes().GoNext(&pUnoCrsr->GetPoint()->nNode);
2876         pTblNode = pCont->FindTableNode();
2877     }
2878     if (pCont)
2879     {
2880         pUnoCrsr->GetPoint()->nContent.Assign(pCont, 0);
2881     }
2882     SwStartNode const*const pNewStartNode =
2883         pUnoCrsr->GetNode()->FindSttNodeByType(
2884             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
2885     if (!pNewStartNode || (pNewStartNode != pOwnStartNode))
2886     {
2887         uno::RuntimeException aExcept;
2888         aExcept.Message = C2U("no text available");
2889         throw aExcept;
2890     }
2891     xRet = static_cast<text::XWordCursor*>(pXCursor);
2892 	return xRet;
2893 }
2894 
2895 /*-- 11.12.98 10:14:50---------------------------------------------------
2896 
2897   -----------------------------------------------------------------------*/
2898 uno::Reference< text::XTextCursor > SAL_CALL
createTextCursorByRange(const uno::Reference<text::XTextRange> & xTextPosition)2899 SwXHeadFootText::createTextCursorByRange(
2900     const uno::Reference< text::XTextRange > & xTextPosition)
2901 throw (uno::RuntimeException)
2902 {
2903 	vos::OGuard aGuard(Application::GetSolarMutex());
2904 
2905     SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() );
2906 
2907 	SwUnoInternalPaM aPam(*GetDoc());
2908     if (!::sw::XTextRangeToSwPaM(aPam, xTextPosition))
2909     {
2910         uno::RuntimeException aRuntime;
2911         aRuntime.Message = C2U(cInvalidObject);
2912         throw aRuntime;
2913     }
2914 
2915 	uno::Reference< text::XTextCursor >  xRet;
2916     SwNode& rNode = rHeadFootFmt.GetCntnt().GetCntntIdx()->GetNode();
2917     SwPosition aPos(rNode);
2918     SwPaM aHFPam(aPos);
2919     aHFPam.Move(fnMoveForward, fnGoNode);
2920     SwStartNode *const pOwnStartNode = aHFPam.GetNode()->FindSttNodeByType(
2921             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
2922     SwStartNode *const p1 = aPam.GetNode()->FindSttNodeByType(
2923             (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
2924     if (p1 == pOwnStartNode)
2925     {
2926         xRet = static_cast<text::XWordCursor*>(
2927                 new SwXTextCursor(*GetDoc(), this,
2928                     (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER,
2929                     *aPam.GetPoint(), aPam.GetMark()));
2930     }
2931 	return xRet;
2932 }
2933 
2934 /* -----------------19.03.99 15:44-------------------
2935  *
2936  * --------------------------------------------------*/
2937 uno::Reference< container::XEnumeration > SAL_CALL
createEnumeration()2938 SwXHeadFootText::createEnumeration()
2939 throw (uno::RuntimeException)
2940 {
2941 	vos::OGuard aGuard(Application::GetSolarMutex());
2942 
2943     SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() );
2944 
2945     uno::Reference< container::XEnumeration >  aRef;
2946     const SwFmtCntnt& rFlyCntnt = rHeadFootFmt.GetCntnt();
2947     const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
2948     SwPosition aPos(rNode);
2949     ::std::auto_ptr<SwUnoCrsr> pUnoCursor(
2950         GetDoc()->CreateUnoCrsr(aPos, sal_False));
2951     pUnoCursor->Move(fnMoveForward, fnGoNode);
2952     aRef = new SwXParagraphEnumeration(this, pUnoCursor,
2953                 (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER);
2954 
2955 	return aRef;
2956 }
2957 
2958 /* -----------------19.03.99 15:50-------------------
2959  *
2960  * --------------------------------------------------*/
2961 uno::Type SAL_CALL
getElementType()2962 SwXHeadFootText::getElementType() throw (uno::RuntimeException)
2963 {
2964     return text::XTextRange::static_type();
2965 }
2966 /* -----------------19.03.99 15:50-------------------
2967  *
2968  * --------------------------------------------------*/
hasElements()2969 sal_Bool SAL_CALL SwXHeadFootText::hasElements() throw (uno::RuntimeException)
2970 {
2971 	return sal_True;
2972 }
2973 
2974