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