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