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& ) 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::XPropertyState > 2180 xCellTextPropState(xCellCurs, uno::UNO_QUERY); 2181 const beans::PropertyState state = xCellTextPropState->getPropertyState(rName); 2182 if (state == beans::PropertyState_DEFAULT_VALUE) 2183 { 2184 const uno::Reference< beans::XPropertySet > 2185 xCellTextProps(xCellCurs, uno::UNO_QUERY); 2186 xCellTextProps->setPropertyValue(rName, rValue); 2187 } 2188 } 2189 } 2190 } 2191 } 2192 2193 static void 2194 lcl_MergeCells(::std::vector<VerticallyMergedCell> & rMergedCells) 2195 { 2196 if (rMergedCells.size()) 2197 { 2198 std::vector<VerticallyMergedCell>::iterator aMergedIter = 2199 rMergedCells.begin(); 2200 while (aMergedIter != rMergedCells.end()) 2201 { 2202 sal_Int32 nCellCount = 2203 static_cast<sal_Int32>(aMergedIter->aCells.size()); 2204 std::vector<uno::Reference< beans::XPropertySet > >::iterator 2205 aCellIter = aMergedIter->aCells.begin(); 2206 bool bFirstCell = true; 2207 // the first of the cells gets the number of cells set as RowSpan 2208 // the others get the inverted number of remaining merged cells 2209 // (3,-2,-1) 2210 while (aCellIter != aMergedIter->aCells.end()) 2211 { 2212 (*aCellIter)->setPropertyValue( 2213 C2U(SW_PROP_NAME_STR(UNO_NAME_ROW_SPAN)), 2214 uno::makeAny(nCellCount)); 2215 if (bFirstCell) 2216 { 2217 nCellCount *= -1; 2218 bFirstCell = false; 2219 } 2220 ++nCellCount; 2221 ++aCellIter; 2222 } 2223 ++aMergedIter; 2224 } 2225 } 2226 } 2227 2228 uno::Reference< text::XTextTable > SAL_CALL 2229 SwXText::convertToTable( 2230 const uno::Sequence< uno::Sequence< uno::Sequence< 2231 uno::Reference< text::XTextRange > > > >& rTableRanges, 2232 const uno::Sequence< uno::Sequence< uno::Sequence< 2233 beans::PropertyValue > > >& rCellProperties, 2234 const uno::Sequence< uno::Sequence< beans::PropertyValue > >& 2235 rRowProperties, 2236 const uno::Sequence< beans::PropertyValue >& rTableProperties) 2237 throw (lang::IllegalArgumentException, uno::RuntimeException) 2238 { 2239 vos::OGuard aGuard(Application::GetSolarMutex()); 2240 2241 if(!IsValid()) 2242 { 2243 throw uno::RuntimeException(); 2244 } 2245 2246 //at first collect the text ranges as SwPaMs 2247 const uno::Sequence< uno::Sequence< uno::Reference< text::XTextRange > > >* 2248 pTableRanges = rTableRanges.getConstArray(); 2249 std::auto_ptr < SwPaM > pFirstPaM; 2250 std::vector< std::vector<SwNodeRange> > aTableNodes; 2251 bool bExcept = false; 2252 SwPaM aLastPaM(m_pImpl->m_pDoc->GetNodes()); 2253 for (sal_Int32 nRow = 0; !bExcept && (nRow < rTableRanges.getLength()); 2254 ++nRow) 2255 { 2256 std::vector<SwNodeRange> aRowNodes; 2257 const uno::Sequence< uno::Reference< text::XTextRange > >* pRow = 2258 pTableRanges[nRow].getConstArray(); 2259 const sal_Int32 nCells(pTableRanges[nRow].getLength()); 2260 2261 for (sal_Int32 nCell = 0; nCell < nCells; ++nCell) 2262 { 2263 m_pImpl->ConvertCell((nCell == 0) && (nRow == 0), pRow[nCell], 2264 aRowNodes, pFirstPaM, aLastPaM, bExcept); 2265 } 2266 aTableNodes.push_back(aRowNodes); 2267 } 2268 2269 if(bExcept) 2270 { 2271 m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo(); 2272 throw lang::IllegalArgumentException(); 2273 } 2274 2275 std::vector< TableColumnSeparators > 2276 aRowSeparators(rRowProperties.getLength()); 2277 std::vector<VerticallyMergedCell> aMergedCells; 2278 2279 SwTable const*const pTable = m_pImpl->m_pDoc->TextToTable( aTableNodes ); 2280 SwXTextTable *const pTextTable = new SwXTextTable( *pTable->GetFrmFmt() ); 2281 const uno::Reference< text::XTextTable > xRet = pTextTable; 2282 const uno::Reference< beans::XPropertySet > xPrSet = pTextTable; 2283 // set properties to the table 2284 // catch lang::WrappedTargetException and lang::IndexOutOfBoundsException 2285 try 2286 { 2287 //apply table properties 2288 const beans::PropertyValue* pTableProperties = 2289 rTableProperties.getConstArray(); 2290 for (sal_Int32 nProperty = 0; nProperty < rTableProperties.getLength(); 2291 ++nProperty) 2292 { 2293 try 2294 { 2295 xPrSet->setPropertyValue( pTableProperties[nProperty].Name, 2296 pTableProperties[nProperty].Value ); 2297 } 2298 catch ( uno::Exception const& e ) 2299 { 2300 #if DEBUG 2301 std::clog << "Exception when setting property: "; 2302 std::clog << rtl::OUStringToOString( 2303 pTableProperties[nProperty].Name, RTL_TEXTENCODING_UTF8) 2304 .getStr(); 2305 std::clog << ". Message: "; 2306 std::clog << rtl::OUStringToOString( e.Message, 2307 RTL_TEXTENCODING_UTF8 ).getStr(); 2308 std::clog << std::endl; 2309 #endif 2310 } 2311 } 2312 2313 //apply row properties 2314 const uno::Reference< table::XTableRows > xRows = xRet->getRows(); 2315 2316 const beans::PropertyValues* pRowProperties = 2317 rRowProperties.getConstArray(); 2318 for (sal_Int32 nRow = 0; nRow < xRows->getCount(); ++nRow) 2319 { 2320 if( nRow >= rRowProperties.getLength()) 2321 { 2322 break; 2323 } 2324 lcl_ApplyRowProperties(pRowProperties[nRow], 2325 xRows->getByIndex(nRow), aRowSeparators[nRow]); 2326 } 2327 2328 #ifdef DEBUG 2329 lcl_DebugCellProperties(rCellProperties); 2330 #endif 2331 2332 //apply cell properties 2333 for (sal_Int32 nRow = 0; nRow < rCellProperties.getLength(); ++nRow) 2334 { 2335 const uno::Sequence< beans::PropertyValues > aCurrentRow = 2336 rCellProperties[nRow]; 2337 sal_Int32 nCells = aCurrentRow.getLength(); 2338 for (sal_Int32 nCell = 0; nCell < nCells; ++nCell) 2339 { 2340 lcl_ApplyCellProperties(nCell, 2341 aRowSeparators[nRow], aCurrentRow[nCell], 2342 pTextTable->getCellByPosition(nCell, nRow), 2343 aMergedCells); 2344 } 2345 } 2346 // now that the cell properties are set the vertical merge values 2347 // have to be applied 2348 lcl_MergeCells(aMergedCells); 2349 } 2350 catch( const lang::WrappedTargetException& rWrapped ) 2351 { 2352 (void)rWrapped; 2353 } 2354 catch ( const lang::IndexOutOfBoundsException& rBounds ) 2355 { 2356 (void)rBounds; 2357 } 2358 2359 return xRet; 2360 } 2361 2362 2363 void SAL_CALL 2364 SwXText::copyText( 2365 const uno::Reference< text::XTextCopy >& xSource ) 2366 throw (uno::RuntimeException) 2367 { 2368 vos::OGuard g(Application::GetSolarMutex()); 2369 2370 uno::Reference< text::XText > const xText(xSource, uno::UNO_QUERY_THROW); 2371 uno::Reference< text::XTextCursor > const xCursor = 2372 xText->createTextCursor(); 2373 xCursor->gotoEnd( sal_True ); 2374 2375 uno::Reference< lang::XUnoTunnel > const xCursorTunnel(xCursor, 2376 uno::UNO_QUERY_THROW); 2377 2378 OTextCursorHelper *const pCursor = 2379 ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xCursorTunnel); 2380 if (!pCursor) 2381 { 2382 throw uno::RuntimeException(); 2383 } 2384 2385 SwNodeIndex rNdIndex( *GetStartNode( ), 1 ); 2386 SwPosition rPos( rNdIndex ); 2387 m_pImpl->m_pDoc->CopyRange( *pCursor->GetPaM(), rPos, false ); 2388 } 2389 2390 2391 /****************************************************************** 2392 * SwXBodyText 2393 ******************************************************************/ 2394 SwXBodyText::SwXBodyText(SwDoc *const pDoc) 2395 : SwXText(pDoc, CURSOR_BODY) 2396 { 2397 } 2398 2399 /*-- 10.12.98 11:17:27--------------------------------------------------- 2400 2401 -----------------------------------------------------------------------*/ 2402 SwXBodyText::~SwXBodyText() 2403 { 2404 2405 } 2406 /* -----------------------------06.04.00 16:33-------------------------------- 2407 2408 ---------------------------------------------------------------------------*/ 2409 OUString SAL_CALL 2410 SwXBodyText::getImplementationName() throw (uno::RuntimeException) 2411 { 2412 return C2U("SwXBodyText"); 2413 } 2414 /* -----------------------------06.04.00 16:33-------------------------------- 2415 2416 ---------------------------------------------------------------------------*/ 2417 static char const*const g_ServicesBodyText[] = 2418 { 2419 "com.sun.star.text.Text", 2420 }; 2421 static const size_t g_nServicesBodyText( 2422 sizeof(g_ServicesBodyText)/sizeof(g_ServicesBodyText[0])); 2423 2424 sal_Bool SAL_CALL SwXBodyText::supportsService(const OUString& rServiceName) 2425 throw (uno::RuntimeException) 2426 { 2427 return ::sw::SupportsServiceImpl( 2428 g_nServicesBodyText, g_ServicesBodyText, rServiceName); 2429 } 2430 2431 uno::Sequence< OUString > SAL_CALL 2432 SwXBodyText::getSupportedServiceNames() throw (uno::RuntimeException) 2433 { 2434 return ::sw::GetSupportedServiceNamesImpl( 2435 g_nServicesBodyText, g_ServicesBodyText); 2436 } 2437 2438 /*-- 10.12.98 11:17:27--------------------------------------------------- 2439 2440 -----------------------------------------------------------------------*/ 2441 uno::Any SAL_CALL 2442 SwXBodyText::queryAggregation(const uno::Type& rType) 2443 throw (uno::RuntimeException) 2444 { 2445 uno::Any aRet; 2446 if (rType == container::XEnumerationAccess::static_type()) 2447 { 2448 aRet <<= uno::Reference< container::XEnumerationAccess >(this); 2449 } 2450 else if (rType == container::XElementAccess::static_type()) 2451 { 2452 aRet <<= uno::Reference< container::XElementAccess >(this); 2453 } 2454 else if (rType == lang::XServiceInfo::static_type()) 2455 { 2456 aRet <<= uno::Reference< lang::XServiceInfo >(this); 2457 } 2458 else 2459 { 2460 aRet = SwXText::queryInterface( rType ); 2461 } 2462 if(aRet.getValueType() == ::getCppuVoidType()) 2463 { 2464 aRet = OWeakAggObject::queryAggregation( rType ); 2465 } 2466 return aRet; 2467 } 2468 2469 /*-- 10.12.98 11:17:28--------------------------------------------------- 2470 2471 -----------------------------------------------------------------------*/ 2472 uno::Sequence< uno::Type > SAL_CALL 2473 SwXBodyText::getTypes() throw (uno::RuntimeException) 2474 { 2475 const uno::Sequence< uno::Type > aTypes = SwXBodyText_Base::getTypes(); 2476 const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes(); 2477 return ::comphelper::concatSequences(aTypes, aTextTypes); 2478 } 2479 /* -----------------------------21.03.00 15:39-------------------------------- 2480 2481 ---------------------------------------------------------------------------*/ 2482 uno::Sequence< sal_Int8 > SAL_CALL 2483 SwXBodyText::getImplementationId() throw (uno::RuntimeException) 2484 { 2485 vos::OGuard aGuard(Application::GetSolarMutex()); 2486 static uno::Sequence< sal_Int8 > aId( 16 ); 2487 static sal_Bool bInit = sal_False; 2488 if(!bInit) 2489 { 2490 rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True ); 2491 bInit = sal_True; 2492 } 2493 return aId; 2494 } 2495 /*-- 10.12.98 11:17:28--------------------------------------------------- 2496 2497 -----------------------------------------------------------------------*/ 2498 uno::Any SAL_CALL 2499 SwXBodyText::queryInterface(const uno::Type& rType) 2500 throw (uno::RuntimeException) 2501 { 2502 const uno::Any ret = SwXText::queryInterface(rType); 2503 return (ret.getValueType() == ::getCppuVoidType()) 2504 ? SwXBodyText_Base::queryInterface(rType) 2505 : ret; 2506 } 2507 /* -----------------------------05.01.00 11:07-------------------------------- 2508 2509 ---------------------------------------------------------------------------*/ 2510 SwXTextCursor * SwXBodyText::CreateTextCursor(const bool bIgnoreTables) 2511 { 2512 if(!IsValid()) 2513 { 2514 return 0; 2515 } 2516 2517 // the cursor has to skip tables contained in this text 2518 SwPaM aPam(GetDoc()->GetNodes().GetEndOfContent()); 2519 aPam.Move( fnMoveBackward, fnGoDoc ); 2520 if (!bIgnoreTables) 2521 { 2522 SwTableNode * pTblNode = aPam.GetNode()->FindTableNode(); 2523 SwCntntNode * pCont = 0; 2524 while (pTblNode) 2525 { 2526 aPam.GetPoint()->nNode = *pTblNode->EndOfSectionNode(); 2527 pCont = GetDoc()->GetNodes().GoNext(&aPam.GetPoint()->nNode); 2528 pTblNode = pCont->FindTableNode(); 2529 } 2530 if (pCont) 2531 { 2532 aPam.GetPoint()->nContent.Assign(pCont, 0); 2533 } 2534 } 2535 return new SwXTextCursor(*GetDoc(), this, CURSOR_BODY, *aPam.GetPoint()); 2536 } 2537 2538 /*-- 10.12.98 11:17:29--------------------------------------------------- 2539 2540 -----------------------------------------------------------------------*/ 2541 uno::Reference< text::XTextCursor > SAL_CALL 2542 SwXBodyText::createTextCursor() throw (uno::RuntimeException) 2543 { 2544 vos::OGuard aGuard(Application::GetSolarMutex()); 2545 2546 const uno::Reference< text::XTextCursor > xRef( 2547 static_cast<text::XWordCursor*>(CreateTextCursor(false)) ); 2548 if (!xRef.is()) 2549 { 2550 uno::RuntimeException aRuntime; 2551 aRuntime.Message = C2U(cInvalidObject); 2552 throw aRuntime; 2553 } 2554 return xRef; 2555 } 2556 /*-- 10.12.98 11:17:29--------------------------------------------------- 2557 2558 -----------------------------------------------------------------------*/ 2559 uno::Reference< text::XTextCursor > SAL_CALL 2560 SwXBodyText::createTextCursorByRange( 2561 const uno::Reference< text::XTextRange > & xTextPosition) 2562 throw (uno::RuntimeException) 2563 { 2564 vos::OGuard aGuard(Application::GetSolarMutex()); 2565 2566 if(!IsValid()) 2567 { 2568 uno::RuntimeException aRuntime; 2569 aRuntime.Message = C2U(cInvalidObject); 2570 throw aRuntime; 2571 } 2572 2573 uno::Reference< text::XTextCursor > aRef; 2574 SwUnoInternalPaM aPam(*GetDoc()); 2575 if (::sw::XTextRangeToSwPaM(aPam, xTextPosition)) 2576 { 2577 SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent(); 2578 2579 SwStartNode* p1 = aPam.GetNode()->StartOfSectionNode(); 2580 //document starts with a section? 2581 while(p1->IsSectionNode()) 2582 { 2583 p1 = p1->StartOfSectionNode(); 2584 } 2585 SwStartNode *const p2 = rNode.StartOfSectionNode(); 2586 2587 if(p1 == p2) 2588 { 2589 aRef = static_cast<text::XWordCursor*>( 2590 new SwXTextCursor(*GetDoc(), this, CURSOR_BODY, 2591 *aPam.GetPoint(), aPam.GetMark())); 2592 } 2593 } 2594 if(!aRef.is()) 2595 { 2596 throw uno::RuntimeException(); 2597 } 2598 return aRef; 2599 } 2600 2601 /*-- 10.12.98 11:17:30--------------------------------------------------- 2602 2603 -----------------------------------------------------------------------*/ 2604 uno::Reference< container::XEnumeration > SAL_CALL 2605 SwXBodyText::createEnumeration() 2606 throw (uno::RuntimeException) 2607 { 2608 vos::OGuard aGuard(Application::GetSolarMutex()); 2609 2610 if (!IsValid()) 2611 { 2612 uno::RuntimeException aRuntime; 2613 aRuntime.Message = C2U(cInvalidObject); 2614 throw aRuntime; 2615 } 2616 2617 SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent(); 2618 SwPosition aPos(rNode); 2619 ::std::auto_ptr<SwUnoCrsr> pUnoCursor( 2620 GetDoc()->CreateUnoCrsr(aPos, sal_False)); 2621 pUnoCursor->Move(fnMoveBackward, fnGoDoc); 2622 const uno::Reference< container::XEnumeration > xRet 2623 = new SwXParagraphEnumeration(this, pUnoCursor, CURSOR_BODY); 2624 return xRet; 2625 } 2626 2627 /* -----------------18.12.98 13:36------------------- 2628 * 2629 * --------------------------------------------------*/ 2630 uno::Type SAL_CALL 2631 SwXBodyText::getElementType() throw (uno::RuntimeException) 2632 { 2633 return text::XTextRange::static_type(); 2634 } 2635 /* -----------------18.12.98 13:36------------------- 2636 * 2637 * --------------------------------------------------*/ 2638 sal_Bool SAL_CALL 2639 SwXBodyText::hasElements() throw (uno::RuntimeException) 2640 { 2641 vos::OGuard aGuard(Application::GetSolarMutex()); 2642 2643 if (!IsValid()) 2644 { 2645 uno::RuntimeException aRuntime; 2646 aRuntime.Message = C2U(cInvalidObject); 2647 throw aRuntime; 2648 } 2649 2650 return sal_True; 2651 } 2652 2653 /****************************************************************** 2654 * SwXHeadFootText 2655 ******************************************************************/ 2656 2657 class SwXHeadFootText::Impl 2658 : public SwClient 2659 { 2660 2661 public: 2662 2663 bool m_bIsHeader; 2664 2665 Impl( SwXHeadFootText & /*rThis*/, 2666 SwFrmFmt & rHeadFootFmt, const bool bIsHeader) 2667 : SwClient(& rHeadFootFmt) 2668 , m_bIsHeader(bIsHeader) 2669 { 2670 } 2671 2672 SwFrmFmt * GetHeadFootFmt() const { 2673 return static_cast<SwFrmFmt*>( 2674 const_cast<SwModify*>(GetRegisteredIn())); 2675 } 2676 2677 SwFrmFmt & GetHeadFootFmtOrThrow() { 2678 SwFrmFmt *const pFmt( GetHeadFootFmt() ); 2679 if (!pFmt) { 2680 throw uno::RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM( 2681 "SwXHeadFootText: disposed or invalid")), 0); 2682 } 2683 return *pFmt; 2684 } 2685 protected: 2686 // SwClient 2687 virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew); 2688 2689 }; 2690 2691 /*-- 11.12.98 10:14:51--------------------------------------------------- 2692 2693 -----------------------------------------------------------------------*/ 2694 void SwXHeadFootText::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) 2695 { 2696 ClientModify(this, pOld, pNew); 2697 } 2698 2699 bool SwXHeadFootText::IsXHeadFootText(SwClient *const pClient) 2700 { 2701 return 0 != dynamic_cast<SwXHeadFootText::Impl*>(pClient); 2702 } 2703 2704 uno::Reference< text::XText > 2705 SwXHeadFootText::CreateXHeadFootText( 2706 SwFrmFmt & rHeadFootFmt, const bool bIsHeader) 2707 { 2708 // re-use existing SwXHeadFootText 2709 // #i105557#: do not iterate over the registered clients: race condition 2710 uno::Reference< text::XText > xText(rHeadFootFmt.GetXObject(), 2711 uno::UNO_QUERY); 2712 if (!xText.is()) 2713 { 2714 SwXHeadFootText *const pXHFT( 2715 new SwXHeadFootText(rHeadFootFmt, bIsHeader)); 2716 xText.set(pXHFT); 2717 rHeadFootFmt.SetXObject(xText); 2718 } 2719 return xText; 2720 } 2721 2722 /*-- 11.12.98 10:14:48--------------------------------------------------- 2723 2724 -----------------------------------------------------------------------*/ 2725 SwXHeadFootText::SwXHeadFootText(SwFrmFmt & rHeadFootFmt, const bool bIsHeader) 2726 : SwXText(rHeadFootFmt.GetDoc(), 2727 (bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER) 2728 , m_pImpl( new SwXHeadFootText::Impl(*this, rHeadFootFmt, bIsHeader) ) 2729 { 2730 } 2731 2732 /*-- 11.12.98 10:14:48--------------------------------------------------- 2733 2734 -----------------------------------------------------------------------*/ 2735 SwXHeadFootText::~SwXHeadFootText() 2736 { 2737 } 2738 2739 /* -----------------------------06.04.00 16:40-------------------------------- 2740 2741 ---------------------------------------------------------------------------*/ 2742 OUString SAL_CALL 2743 SwXHeadFootText::getImplementationName() throw (uno::RuntimeException) 2744 { 2745 return C2U("SwXHeadFootText"); 2746 } 2747 2748 /* -----------------------------06.04.00 16:40-------------------------------- 2749 2750 ---------------------------------------------------------------------------*/ 2751 static char const*const g_ServicesHeadFootText[] = 2752 { 2753 "com.sun.star.text.Text", 2754 }; 2755 static const size_t g_nServicesHeadFootText( 2756 sizeof(g_ServicesHeadFootText)/sizeof(g_ServicesHeadFootText[0])); 2757 2758 sal_Bool SAL_CALL SwXHeadFootText::supportsService(const OUString& rServiceName) 2759 throw (uno::RuntimeException) 2760 { 2761 return ::sw::SupportsServiceImpl( 2762 g_nServicesHeadFootText, g_ServicesHeadFootText, rServiceName); 2763 } 2764 2765 uno::Sequence< OUString > SAL_CALL 2766 SwXHeadFootText::getSupportedServiceNames() throw (uno::RuntimeException) 2767 { 2768 return ::sw::GetSupportedServiceNamesImpl( 2769 g_nServicesHeadFootText, g_ServicesHeadFootText); 2770 } 2771 2772 /*-- 11.12.98 10:14:49--------------------------------------------------- 2773 2774 -----------------------------------------------------------------------*/ 2775 const SwStartNode *SwXHeadFootText::GetStartNode() const 2776 { 2777 const SwStartNode *pSttNd = 0; 2778 SwFrmFmt *const pHeadFootFmt = m_pImpl->GetHeadFootFmt(); 2779 if(pHeadFootFmt) 2780 { 2781 const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt(); 2782 if( rFlyCntnt.GetCntntIdx() ) 2783 { 2784 pSttNd = rFlyCntnt.GetCntntIdx()->GetNode().GetStartNode(); 2785 } 2786 } 2787 return pSttNd; 2788 } 2789 2790 uno::Reference< text::XTextCursor > 2791 SwXHeadFootText::CreateCursor() throw (uno::RuntimeException) 2792 { 2793 return createTextCursor(); 2794 } 2795 /* -----------------------------21.03.00 15:39-------------------------------- 2796 2797 ---------------------------------------------------------------------------*/ 2798 uno::Sequence< uno::Type > SAL_CALL 2799 SwXHeadFootText::getTypes() throw (uno::RuntimeException) 2800 { 2801 const uno::Sequence< uno::Type > aTypes = SwXHeadFootText_Base::getTypes(); 2802 const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes(); 2803 return ::comphelper::concatSequences(aTypes, aTextTypes); 2804 } 2805 2806 /* -----------------------------21.03.00 15:39-------------------------------- 2807 2808 ---------------------------------------------------------------------------*/ 2809 uno::Sequence< sal_Int8 > SAL_CALL 2810 SwXHeadFootText::getImplementationId() throw (uno::RuntimeException) 2811 { 2812 vos::OGuard aGuard(Application::GetSolarMutex()); 2813 static uno::Sequence< sal_Int8 > aId( 16 ); 2814 static sal_Bool bInit = sal_False; 2815 if(!bInit) 2816 { 2817 rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True ); 2818 bInit = sal_True; 2819 } 2820 return aId; 2821 } 2822 /* -----------------------------21.03.00 15:46-------------------------------- 2823 2824 ---------------------------------------------------------------------------*/ 2825 uno::Any SAL_CALL 2826 SwXHeadFootText::queryInterface(const uno::Type& rType) 2827 throw (uno::RuntimeException) 2828 { 2829 const uno::Any ret = SwXHeadFootText_Base::queryInterface(rType); 2830 return (ret.getValueType() == ::getCppuVoidType()) 2831 ? SwXText::queryInterface(rType) 2832 : ret; 2833 } 2834 2835 /*-- 11.12.98 10:14:50--------------------------------------------------- 2836 2837 -----------------------------------------------------------------------*/ 2838 uno::Reference< text::XTextCursor > SAL_CALL 2839 SwXHeadFootText::createTextCursor() throw (uno::RuntimeException) 2840 { 2841 vos::OGuard aGuard(Application::GetSolarMutex()); 2842 2843 SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() ); 2844 2845 uno::Reference< text::XTextCursor > xRet; 2846 const SwFmtCntnt& rFlyCntnt = rHeadFootFmt.GetCntnt(); 2847 const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode(); 2848 SwPosition aPos(rNode); 2849 SwXTextCursor *const pXCursor = new SwXTextCursor(*GetDoc(), this, 2850 (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER, aPos); 2851 SwUnoCrsr *const pUnoCrsr = pXCursor->GetCursor(); 2852 pUnoCrsr->Move(fnMoveForward, fnGoNode); 2853 2854 // save current start node to be able to check if there is content 2855 // after the table - otherwise the cursor would be in the body text! 2856 SwStartNode const*const pOwnStartNode = rNode.FindSttNodeByType( 2857 (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode); 2858 // is there a table here? 2859 SwTableNode* pTblNode = pUnoCrsr->GetNode()->FindTableNode(); 2860 SwCntntNode* pCont = 0; 2861 while (pTblNode) 2862 { 2863 pUnoCrsr->GetPoint()->nNode = *pTblNode->EndOfSectionNode(); 2864 pCont = GetDoc()->GetNodes().GoNext(&pUnoCrsr->GetPoint()->nNode); 2865 pTblNode = pCont->FindTableNode(); 2866 } 2867 if (pCont) 2868 { 2869 pUnoCrsr->GetPoint()->nContent.Assign(pCont, 0); 2870 } 2871 SwStartNode const*const pNewStartNode = 2872 pUnoCrsr->GetNode()->FindSttNodeByType( 2873 (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode); 2874 if (!pNewStartNode || (pNewStartNode != pOwnStartNode)) 2875 { 2876 uno::RuntimeException aExcept; 2877 aExcept.Message = C2U("no text available"); 2878 throw aExcept; 2879 } 2880 xRet = static_cast<text::XWordCursor*>(pXCursor); 2881 return xRet; 2882 } 2883 2884 /*-- 11.12.98 10:14:50--------------------------------------------------- 2885 2886 -----------------------------------------------------------------------*/ 2887 uno::Reference< text::XTextCursor > SAL_CALL 2888 SwXHeadFootText::createTextCursorByRange( 2889 const uno::Reference< text::XTextRange > & xTextPosition) 2890 throw (uno::RuntimeException) 2891 { 2892 vos::OGuard aGuard(Application::GetSolarMutex()); 2893 2894 SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() ); 2895 2896 SwUnoInternalPaM aPam(*GetDoc()); 2897 if (!::sw::XTextRangeToSwPaM(aPam, xTextPosition)) 2898 { 2899 uno::RuntimeException aRuntime; 2900 aRuntime.Message = C2U(cInvalidObject); 2901 throw aRuntime; 2902 } 2903 2904 uno::Reference< text::XTextCursor > xRet; 2905 SwNode& rNode = rHeadFootFmt.GetCntnt().GetCntntIdx()->GetNode(); 2906 SwPosition aPos(rNode); 2907 SwPaM aHFPam(aPos); 2908 aHFPam.Move(fnMoveForward, fnGoNode); 2909 SwStartNode *const pOwnStartNode = aHFPam.GetNode()->FindSttNodeByType( 2910 (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode); 2911 SwStartNode *const p1 = aPam.GetNode()->FindSttNodeByType( 2912 (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode); 2913 if (p1 == pOwnStartNode) 2914 { 2915 xRet = static_cast<text::XWordCursor*>( 2916 new SwXTextCursor(*GetDoc(), this, 2917 (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER, 2918 *aPam.GetPoint(), aPam.GetMark())); 2919 } 2920 return xRet; 2921 } 2922 2923 /* -----------------19.03.99 15:44------------------- 2924 * 2925 * --------------------------------------------------*/ 2926 uno::Reference< container::XEnumeration > SAL_CALL 2927 SwXHeadFootText::createEnumeration() 2928 throw (uno::RuntimeException) 2929 { 2930 vos::OGuard aGuard(Application::GetSolarMutex()); 2931 2932 SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() ); 2933 2934 uno::Reference< container::XEnumeration > aRef; 2935 const SwFmtCntnt& rFlyCntnt = rHeadFootFmt.GetCntnt(); 2936 const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode(); 2937 SwPosition aPos(rNode); 2938 ::std::auto_ptr<SwUnoCrsr> pUnoCursor( 2939 GetDoc()->CreateUnoCrsr(aPos, sal_False)); 2940 pUnoCursor->Move(fnMoveForward, fnGoNode); 2941 aRef = new SwXParagraphEnumeration(this, pUnoCursor, 2942 (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER); 2943 2944 return aRef; 2945 } 2946 2947 /* -----------------19.03.99 15:50------------------- 2948 * 2949 * --------------------------------------------------*/ 2950 uno::Type SAL_CALL 2951 SwXHeadFootText::getElementType() throw (uno::RuntimeException) 2952 { 2953 return text::XTextRange::static_type(); 2954 } 2955 /* -----------------19.03.99 15:50------------------- 2956 * 2957 * --------------------------------------------------*/ 2958 sal_Bool SAL_CALL SwXHeadFootText::hasElements() throw (uno::RuntimeException) 2959 { 2960 return sal_True; 2961 } 2962 2963