1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sd.hxx" 30 #include <vcl/svapp.hxx> 31 #include <vos/mutex.hxx> 32 33 #include <svx/unoshape.hxx> 34 #include <svx/svdpool.hxx> 35 #include <svx/unoprov.hxx> 36 #include <editeng/unotext.hxx> 37 38 #include <comphelper/extract.hxx> 39 #include <rtl/uuid.h> 40 #include <rtl/memory.h> 41 42 #include "unohelp.hxx" 43 #include "unoprnms.hxx" 44 #include "unosrch.hxx" 45 46 using namespace ::vos; 47 using namespace ::rtl; 48 using namespace ::com::sun::star; 49 50 #define WID_SEARCH_BACKWARDS 0 51 #define WID_SEARCH_CASE 1 52 #define WID_SEARCH_WORDS 2 53 54 const SfxItemPropertyMapEntry* ImplGetSearchPropertyMap() 55 { 56 static const SfxItemPropertyMapEntry aSearchPropertyMap_Impl[] = 57 { 58 { MAP_CHAR_LEN(UNO_NAME_SEARCH_BACKWARDS), WID_SEARCH_BACKWARDS, &::getBooleanCppuType(), 0, 0 }, 59 { MAP_CHAR_LEN(UNO_NAME_SEARCH_CASE), WID_SEARCH_CASE, &::getBooleanCppuType(), 0, 0 }, 60 { MAP_CHAR_LEN(UNO_NAME_SEARCH_WORDS), WID_SEARCH_WORDS, &::getBooleanCppuType(), 0, 0 }, 61 { 0,0,0,0,0,0} 62 }; 63 64 return aSearchPropertyMap_Impl; 65 } 66 67 class SearchContext_impl 68 { 69 uno::Reference< drawing::XShapes > mxShapes; 70 sal_Int32 mnIndex; 71 SearchContext_impl* mpParent; 72 73 public: 74 SearchContext_impl( uno::Reference< drawing::XShapes > xShapes, SearchContext_impl* pParent = NULL ) 75 : mxShapes( xShapes ), mnIndex( -1 ), mpParent( pParent ) {} 76 77 78 uno::Reference< drawing::XShape > firstShape() 79 { 80 mnIndex = -1; 81 return nextShape(); 82 } 83 84 uno::Reference< drawing::XShape > nextShape() 85 { 86 uno::Reference< drawing::XShape > xShape; 87 mnIndex++; 88 if( mxShapes.is() && mxShapes->getCount() > mnIndex ) 89 { 90 mxShapes->getByIndex( mnIndex ) >>= xShape; 91 } 92 return xShape; 93 } 94 95 SearchContext_impl* getParent() const { return mpParent; } 96 }; 97 98 /* ================================================================= */ 99 /** this class implements a search or replace operation on a given 100 page or a given sdrobj 101 */ 102 103 SdUnoSearchReplaceShape::SdUnoSearchReplaceShape( drawing::XDrawPage* pPage ) throw() 104 { 105 mpPage = pPage; 106 } 107 108 SdUnoSearchReplaceShape::~SdUnoSearchReplaceShape() throw() 109 { 110 } 111 112 // util::XReplaceable 113 uno::Reference< util::XReplaceDescriptor > SAL_CALL SdUnoSearchReplaceShape::createReplaceDescriptor() 114 throw( uno::RuntimeException ) 115 { 116 return new SdUnoSearchReplaceDescriptor(sal_True); 117 } 118 119 sal_Int32 SAL_CALL SdUnoSearchReplaceShape::replaceAll( const uno::Reference< util::XSearchDescriptor >& xDesc ) 120 throw( uno::RuntimeException ) 121 { 122 SdUnoSearchReplaceDescriptor* pDescr = SdUnoSearchReplaceDescriptor::getImplementation( xDesc ); 123 if( pDescr == NULL ) 124 return 0; 125 126 sal_Int32 nFound = 0; 127 128 uno::Reference< drawing::XShapes > xShapes; 129 uno::Reference< drawing::XShape > xShape; 130 131 SearchContext_impl* pContext = NULL; 132 if(mpPage) 133 { 134 uno::Reference< drawing::XDrawPage > xPage( mpPage ); 135 136 xPage->queryInterface( ITYPE( drawing::XShapes ) ) >>= xShapes; 137 138 if( xShapes.is() && (xShapes->getCount() > 0) ) 139 { 140 pContext = new SearchContext_impl( xShapes ); 141 xShape = pContext->firstShape(); 142 } 143 else 144 { 145 xShapes = NULL; 146 } 147 } 148 else 149 { 150 xShape = mpShape; 151 } 152 153 while( xShape.is() ) 154 { 155 // replace in xShape 156 uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY); 157 uno::Reference< text::XTextRange > xRange(xText, uno::UNO_QUERY); 158 uno::Reference< text::XTextRange > xFound; 159 160 while( xRange.is() ) 161 { 162 xFound = Search( xRange, pDescr ); 163 if( !xFound.is() ) 164 break; 165 166 xFound->setString( pDescr->getReplaceString() ); 167 xRange = xFound->getEnd(); 168 nFound++; 169 } 170 // done with xShape -> get next shape 171 172 // test if its a group 173 uno::Reference< drawing::XShapes > xGroupShape( xShape, uno::UNO_QUERY ); 174 if( xGroupShape.is() && ( xGroupShape->getCount() > 0 ) ) 175 { 176 pContext = new SearchContext_impl( xGroupShape, pContext ); 177 xShape = pContext->firstShape(); 178 } 179 else 180 { 181 if( pContext ) 182 xShape = pContext->nextShape(); 183 else 184 xShape = NULL; 185 } 186 187 // test parent contexts for next shape if none 188 // is found in the current context 189 while( pContext && !xShape.is() ) 190 { 191 if( pContext->getParent() ) 192 { 193 SearchContext_impl* pOldContext = pContext; 194 pContext = pContext->getParent(); 195 delete pOldContext; 196 xShape = pContext->nextShape(); 197 } 198 else 199 { 200 delete pContext; 201 pContext = NULL; 202 xShape = NULL; 203 } 204 } 205 } 206 207 return nFound; 208 } 209 210 // XSearchable 211 uno::Reference< ::com::sun::star::util::XSearchDescriptor > SAL_CALL SdUnoSearchReplaceShape::createSearchDescriptor( ) 212 throw(::com::sun::star::uno::RuntimeException) 213 { 214 return new SdUnoSearchReplaceDescriptor(sal_False); 215 } 216 217 uno::Reference< ::com::sun::star::container::XIndexAccess > SAL_CALL SdUnoSearchReplaceShape::findAll( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XSearchDescriptor >& xDesc ) 218 throw(::com::sun::star::uno::RuntimeException) 219 { 220 SdUnoSearchReplaceDescriptor* pDescr = SdUnoSearchReplaceDescriptor::getImplementation( xDesc ); 221 if( pDescr == NULL ) 222 return uno::Reference< container::XIndexAccess > (); 223 224 225 sal_Int32 nSequence = 32; 226 sal_Int32 nFound = 0; 227 228 uno::Sequence < uno::Reference< uno::XInterface > > aSeq( nSequence ); 229 230 uno::Reference< uno::XInterface > * pArray = aSeq.getArray(); 231 232 uno::Reference< drawing::XShapes > xShapes; 233 uno::Reference< drawing::XShape > xShape; 234 235 SearchContext_impl* pContext = NULL; 236 if(mpPage) 237 { 238 uno::Reference< drawing::XDrawPage > xPage( mpPage ); 239 xPage->queryInterface( ITYPE( drawing::XShapes ) ) >>= xShapes; 240 241 if( xShapes.is() && xShapes->getCount() > 0 ) 242 { 243 pContext = new SearchContext_impl( xShapes ); 244 xShape = pContext->firstShape(); 245 } 246 else 247 { 248 xShapes = NULL; 249 } 250 } 251 else 252 { 253 xShape = mpShape; 254 } 255 while( xShape.is() ) 256 { 257 // find in xShape 258 uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY); 259 uno::Reference< text::XTextRange > xRange(xText, uno::UNO_QUERY); 260 uno::Reference< text::XTextRange > xFound; 261 262 while( xRange.is() ) 263 { 264 xFound = Search( xRange, pDescr ); 265 if( !xFound.is() ) 266 break; 267 268 if( nFound >= nSequence ) 269 { 270 nSequence += 32; 271 aSeq.realloc( nSequence ); 272 pArray = aSeq.getArray(); 273 } 274 275 pArray[nFound++] = xFound; 276 277 xRange = xFound->getEnd(); 278 } 279 // done with shape -> get next shape 280 281 // test if its a group 282 uno::Reference< drawing::XShapes > xGroupShape; 283 uno::Any aAny( xShape->queryInterface( ITYPE( drawing::XShapes ))); 284 285 if( (aAny >>= xGroupShape ) && xGroupShape->getCount() > 0 ) 286 { 287 pContext = new SearchContext_impl( xGroupShape, pContext ); 288 xShape = pContext->firstShape(); 289 } 290 else 291 { 292 if( pContext ) 293 xShape = pContext->nextShape(); 294 else 295 xShape = NULL; 296 } 297 298 // test parent contexts for next shape if none 299 // is found in the current context 300 while( pContext && !xShape.is() ) 301 { 302 if( pContext->getParent() ) 303 { 304 SearchContext_impl* pOldContext = pContext; 305 pContext = pContext->getParent(); 306 delete pOldContext; 307 xShape = pContext->nextShape(); 308 } 309 else 310 { 311 delete pContext; 312 pContext = NULL; 313 xShape = NULL; 314 } 315 } 316 } 317 318 if( nFound != nSequence ) 319 aSeq.realloc( nFound ); 320 321 return (container::XIndexAccess*)new SdUnoFindAllAccess( aSeq ); 322 } 323 324 uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SdUnoSearchReplaceShape::findFirst( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XSearchDescriptor >& xDesc ) 325 throw(::com::sun::star::uno::RuntimeException) 326 { 327 uno::Reference< text::XTextRange > xRange( GetCurrentShape(), uno::UNO_QUERY ); 328 if( xRange.is() ) 329 return findNext( xRange, xDesc ); 330 331 return uno::Reference< uno::XInterface > (); 332 } 333 334 uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetCurrentShape() const throw() 335 { 336 uno::Reference< drawing::XShape > xShape; 337 338 if( mpPage ) 339 { 340 uno::Reference< drawing::XDrawPage > xPage( mpPage ); 341 uno::Reference< container::XIndexAccess > xShapes( xPage, uno::UNO_QUERY ); 342 if( xShapes.is() ) 343 { 344 if(xShapes->getCount() > 0) 345 { 346 xShapes->getByIndex(0) >>= xShape; 347 } 348 } 349 } 350 else if( mpShape ) 351 { 352 xShape = mpShape; 353 } 354 355 return xShape; 356 357 } 358 359 uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SdUnoSearchReplaceShape::findNext( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xStartAt, const ::com::sun::star::uno::Reference< ::com::sun::star::util::XSearchDescriptor >& xDesc ) 360 throw(::com::sun::star::uno::RuntimeException) 361 { 362 SdUnoSearchReplaceDescriptor* pDescr = SdUnoSearchReplaceDescriptor::getImplementation( xDesc ); 363 364 uno::Reference< uno::XInterface > xFound; 365 366 uno::Reference< text::XTextRange > xRange( xStartAt, uno::UNO_QUERY ); 367 if(pDescr && xRange.is() ) 368 { 369 370 uno::Reference< text::XTextRange > xCurrentRange( xStartAt, uno::UNO_QUERY ); 371 372 uno::Reference< drawing::XShape > xCurrentShape( GetShape( xCurrentRange ) ); 373 374 while(!xFound.is() && xRange.is()) 375 { 376 xFound = Search( xRange, pDescr ); 377 if(!xFound.is()) 378 { 379 // we need a new starting range now 380 xRange = NULL; 381 382 if(mpPage) 383 { 384 uno::Reference< drawing::XDrawPage > xPage( mpPage ); 385 386 // we do a page wide search, so skip to the next shape here 387 uno::Reference< container::XIndexAccess > xShapes( xPage, uno::UNO_QUERY ); 388 389 // get next shape on our page 390 if( xShapes.is() ) 391 { 392 uno::Reference< drawing::XShape > xFound2( GetNextShape( xShapes, xCurrentShape ) ); 393 if( xFound2.is() && (xFound2.get() != xCurrentShape.get()) ) 394 xCurrentShape = xFound2; 395 else 396 xCurrentShape = NULL; 397 398 xCurrentShape->queryInterface( ITYPE( text::XTextRange ) ) >>= xRange; 399 if(!(xCurrentShape.is() && (xRange.is()))) 400 xRange = NULL; 401 } 402 } 403 else 404 { 405 // we search only in this shape, so end search if we have 406 // not found anything 407 } 408 } 409 } 410 } 411 return xFound; 412 } 413 414 /** this method returns the shape that follows xCurrentShape in the shape collection xShapes. 415 It steps recursive into groupshapes and returns the xCurrentShape if it is the last 416 shape in this collection */ 417 uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetNextShape( uno::Reference< container::XIndexAccess > xShapes, uno::Reference< drawing::XShape > xCurrentShape ) throw() 418 { 419 uno::Reference< drawing::XShape > xFound; 420 uno::Any aAny; 421 422 if(xShapes.is() && xCurrentShape.is()) 423 { 424 const sal_Int32 nCount = xShapes->getCount(); 425 for( sal_Int32 i = 0; i < nCount; i++ ) 426 { 427 uno::Reference< drawing::XShape > xSearchShape; 428 xShapes->getByIndex(i) >>= xSearchShape; 429 430 if( xSearchShape.is() ) 431 { 432 uno::Reference< container::XIndexAccess > xGroup( xSearchShape, uno::UNO_QUERY ); 433 434 if( xCurrentShape.get() == xSearchShape.get() ) 435 { 436 if( xGroup.is() && xGroup->getCount() > 0 ) 437 { 438 xGroup->getByIndex( 0 ) >>= xFound; 439 } 440 else 441 { 442 i++; 443 if( i < nCount ) 444 xShapes->getByIndex( i ) >>= xFound; 445 else 446 xFound = xCurrentShape; 447 } 448 449 break; 450 } 451 else if( xGroup.is() ) 452 { 453 xFound = GetNextShape( xGroup, xCurrentShape ); 454 if( xFound.is() ) 455 { 456 if( xFound.get() == xCurrentShape.get() ) 457 { 458 // the current shape was found at the end of the group 459 i++; 460 if( i < nCount ) 461 { 462 xShapes->getByIndex(i) >>= xFound; 463 } 464 } 465 break; 466 } 467 } 468 } 469 } 470 } 471 472 return xFound; 473 } 474 475 uno::Reference< text::XTextRange > SdUnoSearchReplaceShape::Search( uno::Reference< text::XTextRange > xText, SdUnoSearchReplaceDescriptor* pDescr ) throw() 476 { 477 if(!xText.is()) 478 return uno::Reference< text::XTextRange > (); 479 480 uno::Reference< text::XText > xParent( xText->getText() ); 481 482 if( !xParent.is() ) 483 { 484 uno::Any aAny( xText->queryInterface( ITYPE( text::XText )) ); 485 aAny >>= xParent; 486 } 487 488 const OUString aText( xParent->getString() ); 489 490 const sal_Int32 nTextLen = aText.getLength(); 491 492 sal_Int32* pConvertPos = new sal_Int32[nTextLen+2]; 493 sal_Int32* pConvertPara = new sal_Int32[nTextLen+2]; 494 495 int ndbg = 0; 496 const sal_Unicode* pText = aText; 497 498 sal_Int32* pPos = pConvertPos; 499 sal_Int32* pPara = pConvertPara; 500 501 sal_Int32 nLastPos = 0, nLastPara = 0; 502 503 uno::Reference< container::XEnumerationAccess > xEnumAccess( xParent, uno::UNO_QUERY ); 504 505 // first we fill the arrys with the position and paragraph for every character 506 // inside the text 507 if( xEnumAccess.is() ) 508 { 509 uno::Reference< container::XEnumeration > xParaEnum( xEnumAccess->createEnumeration() ); 510 511 while(xParaEnum->hasMoreElements()) 512 { 513 uno::Reference< text::XTextContent > xParagraph( xParaEnum->nextElement(), uno::UNO_QUERY ); 514 if( xParagraph.is() ) 515 xEnumAccess.query( xParagraph ); 516 else 517 xEnumAccess.clear(); 518 519 if( xEnumAccess.is() ) 520 { 521 uno::Reference< container::XEnumeration > xPortionEnum( xEnumAccess->createEnumeration() ); 522 if( xPortionEnum.is() ) 523 { 524 while(xPortionEnum->hasMoreElements()) 525 { 526 uno::Reference< text::XTextRange > xPortion( xPortionEnum->nextElement(), uno::UNO_QUERY ); 527 if( xPortion.is() ) 528 { 529 const OUString aPortion( xPortion->getString() ); 530 const sal_Int32 nLen = aPortion.getLength(); 531 532 ESelection aStartSel( GetSelection( xPortion->getStart() ) ); 533 ESelection aEndSel( GetSelection( xPortion->getEnd() ) ); 534 535 // special case for empty portions with content or length one portions with content (fields) 536 if( (aStartSel.nStartPos == aEndSel.nStartPos) || ( (aStartSel.nStartPos == (aEndSel.nStartPos - 1)) && (nLen > 1) ) ) 537 { 538 for( sal_Int32 i = 0; i < nLen; i++ ) 539 { 540 if( ndbg < (nTextLen+2) ) 541 { 542 *pPos++ = aStartSel.nStartPos; 543 *pPara++ = aStartSel.nStartPara; 544 545 ndbg += 1; 546 pText++; 547 } 548 else 549 { 550 DBG_ERROR( "array overflow while searching" ); 551 } 552 } 553 554 nLastPos = aStartSel.nStartPos; 555 } 556 // normal case 557 else 558 { 559 for( sal_Int32 i = 0; i < nLen; i++ ) 560 { 561 if( ndbg < (nTextLen+2) ) 562 { 563 *pPos++ = aStartSel.nStartPos++; 564 *pPara++ = aStartSel.nStartPara; 565 566 ndbg += 1; 567 pText++; 568 } 569 else 570 { 571 DBG_ERROR( "array overflow while searching" ); 572 } 573 } 574 575 nLastPos = aStartSel.nStartPos - 1; 576 DBG_ASSERT( aEndSel.nStartPos == aStartSel.nStartPos, "Search is not working" ); 577 } 578 nLastPara = aStartSel.nStartPara; 579 } 580 } 581 } 582 } 583 584 if( ndbg < (nTextLen+2) ) 585 { 586 *pPos++ = nLastPos + 1; 587 *pPara++ = nLastPara; 588 589 ndbg += 1; 590 pText++; 591 } 592 else 593 { 594 DBG_ERROR( "array overflow while searching" ); 595 } 596 } 597 } 598 599 uno::Reference< text::XText > xFound; 600 ESelection aSel; 601 602 uno::Reference< text::XTextRange > xRangeRef( xText, uno::UNO_QUERY ); 603 if( xRangeRef.is() ) 604 aSel = GetSelection( xRangeRef ); 605 606 sal_Int32 nStartPos; 607 sal_Int32 nEndPos = 0; 608 for( nStartPos = 0; nStartPos < nTextLen; nStartPos++ ) 609 { 610 if( pConvertPara[nStartPos] == aSel.nStartPara && pConvertPos[nStartPos] == aSel.nStartPos ) 611 break; 612 } 613 614 if( Search( aText, nStartPos, nEndPos, pDescr ) ) 615 { 616 if( nStartPos <= nTextLen && nEndPos <= nTextLen ) 617 { 618 ESelection aSelection( (sal_uInt16)pConvertPara[nStartPos], (sal_uInt16)pConvertPos[nStartPos], 619 (sal_uInt16)pConvertPara[nEndPos], (sal_uInt16)pConvertPos[nEndPos] ); 620 SvxUnoTextRange *pRange; 621 622 SvxUnoTextBase* pParent = SvxUnoTextBase::getImplementation( xParent ); 623 624 if(pParent) 625 { 626 pRange = new SvxUnoTextRange( *pParent ); 627 xFound = (text::XText*)pRange; 628 pRange->SetSelection(aSelection); 629 630 // pDescr->SetStartPos( nEndPos ); 631 } 632 } 633 else 634 { 635 DBG_ERROR("Array overflow while searching!"); 636 } 637 } 638 639 delete[] pConvertPos; 640 delete[] pConvertPara; 641 642 return uno::Reference< text::XTextRange > ( xFound, uno::UNO_QUERY ); 643 } 644 645 sal_Bool SdUnoSearchReplaceShape::Search( const OUString& rText, sal_Int32& nStartPos, sal_Int32& nEndPos, SdUnoSearchReplaceDescriptor* pDescr ) throw() 646 { 647 OUString aSearchStr( pDescr->getSearchString() ); 648 OUString aText( rText ); 649 650 if( !pDescr->IsCaseSensitive() ) 651 { 652 aText.toAsciiLowerCase(); 653 aSearchStr.toAsciiLowerCase(); 654 } 655 656 sal_Int32 nFound = aText.indexOf( aSearchStr, nStartPos ); 657 if( nFound != -1 ) 658 { 659 nStartPos = nFound; 660 nEndPos = nFound + aSearchStr.getLength(); 661 662 if(pDescr->IsWords()) 663 { 664 if( (nStartPos > 0 && aText.getStr()[nStartPos-1] > ' ') || 665 (nEndPos < aText.getLength() && aText.getStr()[nEndPos] > ' ') ) 666 { 667 nStartPos++; 668 return Search( aText, nStartPos, nEndPos, pDescr ); 669 } 670 } 671 672 return sal_True; 673 } 674 else 675 return sal_False; 676 } 677 678 ESelection SdUnoSearchReplaceShape::GetSelection( uno::Reference< text::XTextRange > xTextRange ) throw() 679 { 680 ESelection aSel; 681 SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( xTextRange ); 682 683 if(pRange) 684 aSel = pRange->GetSelection(); 685 686 return aSel; 687 } 688 689 uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetShape( uno::Reference< text::XTextRange > xTextRange ) throw() 690 { 691 uno::Reference< drawing::XShape > xShape; 692 693 if(xTextRange.is()) 694 { 695 uno::Reference< text::XText > xText( xTextRange->getText() ); 696 697 if(xText.is()) 698 { 699 do 700 { 701 xText->queryInterface( ITYPE( drawing::XShape )) >>= xShape; 702 if(!xShape.is()) 703 { 704 uno::Reference< text::XText > xParent( xText->getText() ); 705 if(!xParent.is() || xText.get() == xParent.get()) 706 return xShape; 707 708 xText = xParent; 709 } 710 } while( !xShape.is() ); 711 } 712 } 713 714 return xShape; 715 } 716 717 /* ================================================================= */ 718 /** this class holds the parameters and status of a search or replace 719 operation performed by class SdUnoSearchReplaceShape 720 */ 721 722 UNO3_GETIMPLEMENTATION_IMPL( SdUnoSearchReplaceDescriptor ); 723 724 SdUnoSearchReplaceDescriptor::SdUnoSearchReplaceDescriptor( sal_Bool bReplace ) throw() 725 { 726 mpPropSet = new SvxItemPropertySet(ImplGetSearchPropertyMap(), SdrObject::GetGlobalDrawObjectItemPool()); 727 728 mbBackwards = sal_False; 729 mbCaseSensitive = sal_False; 730 mbWords = sal_False; 731 732 mbReplace = bReplace; 733 } 734 735 SdUnoSearchReplaceDescriptor::~SdUnoSearchReplaceDescriptor() throw() 736 { 737 delete mpPropSet; 738 } 739 740 // XSearchDescriptor 741 OUString SAL_CALL SdUnoSearchReplaceDescriptor::getSearchString() 742 throw(::com::sun::star::uno::RuntimeException) 743 { 744 return maSearchStr; 745 } 746 747 void SAL_CALL SdUnoSearchReplaceDescriptor::setSearchString( const OUString& aString ) 748 throw(::com::sun::star::uno::RuntimeException) 749 { 750 maSearchStr = aString; 751 } 752 753 // XReplaceDescriptor 754 OUString SAL_CALL SdUnoSearchReplaceDescriptor::getReplaceString() 755 throw(::com::sun::star::uno::RuntimeException) 756 { 757 return maReplaceStr; 758 } 759 760 void SAL_CALL SdUnoSearchReplaceDescriptor::setReplaceString( const ::rtl::OUString& aReplaceString ) 761 throw(::com::sun::star::uno::RuntimeException) 762 { 763 maReplaceStr = aReplaceString; 764 } 765 766 // XPropertySet 767 uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL SdUnoSearchReplaceDescriptor::getPropertySetInfo() 768 throw(::com::sun::star::uno::RuntimeException) 769 { 770 OGuard aGuard( Application::GetSolarMutex() ); 771 return mpPropSet->getPropertySetInfo(); 772 } 773 774 void SAL_CALL SdUnoSearchReplaceDescriptor::setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) 775 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 776 { 777 OGuard aGuard( Application::GetSolarMutex() ); 778 779 const SfxItemPropertySimpleEntry* pEntry = mpPropSet->getPropertyMapEntry(aPropertyName); 780 781 sal_Bool bOk = sal_False; 782 783 switch( pEntry ? pEntry->nWID : -1 ) 784 { 785 case WID_SEARCH_BACKWARDS: 786 bOk = (aValue >>= mbBackwards); 787 break; 788 case WID_SEARCH_CASE: 789 bOk = (aValue >>= mbCaseSensitive); 790 break; 791 case WID_SEARCH_WORDS: 792 bOk = (aValue >>= mbWords); 793 break; 794 default: 795 throw beans::UnknownPropertyException(); 796 } 797 798 if( !bOk ) 799 throw lang::IllegalArgumentException(); 800 } 801 802 uno::Any SAL_CALL SdUnoSearchReplaceDescriptor::getPropertyValue( const ::rtl::OUString& PropertyName ) 803 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 804 { 805 OGuard aGuard( Application::GetSolarMutex() ); 806 807 uno::Any aAny; 808 809 const SfxItemPropertySimpleEntry* pEntry = mpPropSet->getPropertyMapEntry(PropertyName); 810 811 switch( pEntry ? pEntry->nWID : -1 ) 812 { 813 case WID_SEARCH_BACKWARDS: 814 aAny <<= (sal_Bool)mbBackwards; 815 break; 816 case WID_SEARCH_CASE: 817 aAny <<= (sal_Bool)mbCaseSensitive; 818 break; 819 case WID_SEARCH_WORDS: 820 aAny <<= (sal_Bool)mbWords; 821 break; 822 default: 823 throw beans::UnknownPropertyException(); 824 } 825 826 return aAny; 827 } 828 829 void SAL_CALL SdUnoSearchReplaceDescriptor::addPropertyChangeListener( const ::rtl::OUString& , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) {} 830 void SAL_CALL SdUnoSearchReplaceDescriptor::removePropertyChangeListener( const ::rtl::OUString& , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) {} 831 void SAL_CALL SdUnoSearchReplaceDescriptor::addVetoableChangeListener( const ::rtl::OUString& , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) {} 832 void SAL_CALL SdUnoSearchReplaceDescriptor::removeVetoableChangeListener( const ::rtl::OUString& , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) {} 833 834 835 /* ================================================================= */ 836 837 SdUnoFindAllAccess::SdUnoFindAllAccess( uno::Sequence< uno::Reference< uno::XInterface > >& rSequence ) throw() 838 :maSequence( rSequence ) 839 { 840 } 841 842 SdUnoFindAllAccess::~SdUnoFindAllAccess() throw() 843 { 844 } 845 846 // XElementAccess 847 uno::Type SAL_CALL SdUnoFindAllAccess::getElementType() 848 throw(::com::sun::star::uno::RuntimeException) 849 { 850 return ITYPE( text::XTextRange ); 851 } 852 853 sal_Bool SAL_CALL SdUnoFindAllAccess::hasElements() 854 throw(::com::sun::star::uno::RuntimeException) 855 { 856 return maSequence.getLength() > 0; 857 } 858 859 // XIndexAccess 860 sal_Int32 SAL_CALL SdUnoFindAllAccess::getCount() 861 throw(::com::sun::star::uno::RuntimeException) 862 { 863 return maSequence.getLength(); 864 } 865 866 uno::Any SAL_CALL SdUnoFindAllAccess::getByIndex( sal_Int32 Index ) 867 throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 868 { 869 uno::Any aAny; 870 871 if( Index < 0 || Index >= getCount() ) 872 throw lang::IndexOutOfBoundsException(); 873 874 const uno::Reference< uno::XInterface > *pRefs = maSequence.getConstArray(); 875 if(pRefs) 876 aAny <<= pRefs[ Index ]; 877 return aAny; 878 } 879 880