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