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