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