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