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