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, ::getBooleanCppuType(), 0, 0 },
45 0 : { OUString(UNO_NAME_SEARCH_CASE), WID_SEARCH_CASE, ::getBooleanCppuType(), 0, 0 },
46 0 : { OUString(UNO_NAME_SEARCH_WORDS), WID_SEARCH_WORDS, ::getBooleanCppuType(), 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 2076 : SdUnoSearchReplaceShape::SdUnoSearchReplaceShape( drawing::XDrawPage* pPage ) throw()
89 : : mpShape(NULL)
90 2076 : , mpPage(pPage)
91 : {
92 2076 : }
93 :
94 2074 : SdUnoSearchReplaceShape::~SdUnoSearchReplaceShape() throw()
95 : {
96 2074 : }
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 : return (container::XIndexAccess*)new SdUnoFindAllAccess( aSeq );
307 : }
308 :
309 0 : uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SdUnoSearchReplaceShape::findFirst( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XSearchDescriptor >& xDesc )
310 : throw(::com::sun::star::uno::RuntimeException, std::exception)
311 : {
312 0 : uno::Reference< text::XTextRange > xRange( GetCurrentShape(), uno::UNO_QUERY );
313 0 : if( xRange.is() )
314 0 : return findNext( xRange, xDesc );
315 :
316 0 : return uno::Reference< uno::XInterface > ();
317 : }
318 :
319 0 : uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetCurrentShape() const throw()
320 : {
321 0 : uno::Reference< drawing::XShape > xShape;
322 :
323 0 : if( mpPage )
324 : {
325 0 : uno::Reference< drawing::XDrawPage > xPage( mpPage );
326 0 : uno::Reference< container::XIndexAccess > xShapes( xPage, uno::UNO_QUERY );
327 0 : if( xShapes.is() )
328 : {
329 0 : if(xShapes->getCount() > 0)
330 : {
331 0 : xShapes->getByIndex(0) >>= xShape;
332 : }
333 0 : }
334 : }
335 0 : else if( mpShape )
336 : {
337 0 : xShape = mpShape;
338 : }
339 :
340 0 : return xShape;
341 :
342 : }
343 :
344 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 )
345 : throw(::com::sun::star::uno::RuntimeException, std::exception)
346 : {
347 0 : SdUnoSearchReplaceDescriptor* pDescr = SdUnoSearchReplaceDescriptor::getImplementation( xDesc );
348 :
349 0 : uno::Reference< uno::XInterface > xFound;
350 :
351 0 : uno::Reference< text::XTextRange > xRange( xStartAt, uno::UNO_QUERY );
352 0 : if(pDescr && xRange.is() )
353 : {
354 :
355 0 : uno::Reference< text::XTextRange > xCurrentRange( xStartAt, uno::UNO_QUERY );
356 :
357 0 : uno::Reference< drawing::XShape > xCurrentShape( GetShape( xCurrentRange ) );
358 :
359 0 : while(!xFound.is() && xRange.is())
360 : {
361 0 : xFound = Search( xRange, pDescr );
362 0 : if(!xFound.is())
363 : {
364 : // we need a new starting range now
365 0 : xRange = NULL;
366 :
367 0 : if(mpPage)
368 : {
369 0 : uno::Reference< drawing::XDrawPage > xPage( mpPage );
370 :
371 : // we do a page wide search, so skip to the next shape here
372 0 : uno::Reference< container::XIndexAccess > xShapes( xPage, uno::UNO_QUERY );
373 :
374 : // get next shape on our page
375 0 : if( xShapes.is() )
376 : {
377 0 : uno::Reference< drawing::XShape > xFound2( GetNextShape( xShapes, xCurrentShape ) );
378 0 : if( xFound2.is() && (xFound2.get() != xCurrentShape.get()) )
379 0 : xCurrentShape = xFound2;
380 : else
381 0 : xCurrentShape = NULL;
382 :
383 0 : xRange.set( xCurrentShape, uno::UNO_QUERY );
384 0 : if(!(xCurrentShape.is() && (xRange.is())))
385 0 : xRange = NULL;
386 0 : }
387 : }
388 : else
389 : {
390 : // we search only in this shape, so end search if we have
391 : // not found anything
392 : }
393 : }
394 0 : }
395 : }
396 0 : return xFound;
397 : }
398 :
399 : /** this method returns the shape that follows xCurrentShape in the shape collection xShapes.
400 : It steps recursive into groupshapes and returns the xCurrentShape if it is the last
401 : shape in this collection */
402 0 : uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetNextShape( uno::Reference< container::XIndexAccess > xShapes, uno::Reference< drawing::XShape > xCurrentShape ) throw()
403 : {
404 0 : uno::Reference< drawing::XShape > xFound;
405 :
406 0 : if(xShapes.is() && xCurrentShape.is())
407 : {
408 0 : const sal_Int32 nCount = xShapes->getCount();
409 0 : for( sal_Int32 i = 0; i < nCount; i++ )
410 : {
411 0 : uno::Reference< drawing::XShape > xSearchShape;
412 0 : xShapes->getByIndex(i) >>= xSearchShape;
413 :
414 0 : if( xSearchShape.is() )
415 : {
416 0 : uno::Reference< container::XIndexAccess > xGroup( xSearchShape, uno::UNO_QUERY );
417 :
418 0 : if( xCurrentShape.get() == xSearchShape.get() )
419 : {
420 0 : if( xGroup.is() && xGroup->getCount() > 0 )
421 : {
422 0 : xGroup->getByIndex( 0 ) >>= xFound;
423 : }
424 : else
425 : {
426 0 : i++;
427 0 : if( i < nCount )
428 0 : xShapes->getByIndex( i ) >>= xFound;
429 : else
430 0 : xFound = xCurrentShape;
431 : }
432 :
433 0 : break;
434 : }
435 0 : else if( xGroup.is() )
436 : {
437 0 : xFound = GetNextShape( xGroup, xCurrentShape );
438 0 : if( xFound.is() )
439 : {
440 0 : if( xFound.get() == xCurrentShape.get() )
441 : {
442 : // the current shape was found at the end of the group
443 0 : i++;
444 0 : if( i < nCount )
445 : {
446 0 : xShapes->getByIndex(i) >>= xFound;
447 : }
448 : }
449 0 : break;
450 : }
451 0 : }
452 : }
453 0 : }
454 : }
455 :
456 0 : return xFound;
457 : }
458 :
459 0 : uno::Reference< text::XTextRange > SdUnoSearchReplaceShape::Search( uno::Reference< text::XTextRange > xText, SdUnoSearchReplaceDescriptor* pDescr ) throw()
460 : {
461 0 : if(!xText.is())
462 0 : return uno::Reference< text::XTextRange > ();
463 :
464 0 : uno::Reference< text::XText > xParent( xText->getText() );
465 :
466 0 : if( !xParent.is() )
467 : {
468 0 : xParent.set( xText, uno::UNO_QUERY );
469 : }
470 :
471 0 : const OUString aText( xParent->getString() );
472 :
473 0 : const sal_Int32 nTextLen = aText.getLength();
474 :
475 0 : sal_Int32* pConvertPos = new sal_Int32[nTextLen+2];
476 0 : sal_Int32* pConvertPara = new sal_Int32[nTextLen+2];
477 :
478 0 : int ndbg = 0;
479 0 : const sal_Unicode* pText = aText.getStr();
480 :
481 0 : sal_Int32* pPos = pConvertPos;
482 0 : sal_Int32* pPara = pConvertPara;
483 :
484 0 : sal_Int32 nLastPos = 0, nLastPara = 0;
485 :
486 0 : uno::Reference< container::XEnumerationAccess > xEnumAccess( xParent, uno::UNO_QUERY );
487 :
488 : // first we fill the arrys with the position and paragraph for every character
489 : // inside the text
490 0 : if( xEnumAccess.is() )
491 : {
492 0 : uno::Reference< container::XEnumeration > xParaEnum( xEnumAccess->createEnumeration() );
493 :
494 0 : while(xParaEnum->hasMoreElements())
495 : {
496 0 : uno::Reference< text::XTextContent > xParagraph( xParaEnum->nextElement(), uno::UNO_QUERY );
497 0 : if( xParagraph.is() )
498 0 : xEnumAccess.set(xParagraph, css::uno::UNO_QUERY);
499 : else
500 0 : xEnumAccess.clear();
501 :
502 0 : if( xEnumAccess.is() )
503 : {
504 0 : uno::Reference< container::XEnumeration > xPortionEnum( xEnumAccess->createEnumeration() );
505 0 : if( xPortionEnum.is() )
506 : {
507 0 : while(xPortionEnum->hasMoreElements())
508 : {
509 0 : uno::Reference< text::XTextRange > xPortion( xPortionEnum->nextElement(), uno::UNO_QUERY );
510 0 : if( xPortion.is() )
511 : {
512 0 : const OUString aPortion( xPortion->getString() );
513 0 : const sal_Int32 nLen = aPortion.getLength();
514 :
515 0 : ESelection aStartSel( GetSelection( xPortion->getStart() ) );
516 0 : ESelection aEndSel( GetSelection( xPortion->getEnd() ) );
517 :
518 : // special case for empty portions with content or length one portions with content (fields)
519 0 : if( (aStartSel.nStartPos == aEndSel.nStartPos) || ( (aStartSel.nStartPos == (aEndSel.nStartPos - 1)) && (nLen > 1) ) )
520 : {
521 0 : for( sal_Int32 i = 0; i < nLen; i++ )
522 : {
523 0 : if( ndbg < (nTextLen+2) )
524 : {
525 0 : *pPos++ = aStartSel.nStartPos;
526 0 : *pPara++ = aStartSel.nStartPara;
527 :
528 0 : ndbg += 1;
529 0 : pText++;
530 : }
531 : else
532 : {
533 : OSL_FAIL( "array overflow while searching" );
534 : }
535 : }
536 :
537 0 : nLastPos = aStartSel.nStartPos;
538 : }
539 : // normal case
540 : else
541 : {
542 0 : for( sal_Int32 i = 0; i < nLen; i++ )
543 : {
544 0 : if( ndbg < (nTextLen+2) )
545 : {
546 0 : *pPos++ = aStartSel.nStartPos++;
547 0 : *pPara++ = aStartSel.nStartPara;
548 :
549 0 : ndbg += 1;
550 0 : pText++;
551 : }
552 : else
553 : {
554 : OSL_FAIL( "array overflow while searching" );
555 : }
556 : }
557 :
558 0 : nLastPos = aStartSel.nStartPos - 1;
559 : DBG_ASSERT( aEndSel.nStartPos == aStartSel.nStartPos, "Search is not working" );
560 : }
561 0 : nLastPara = aStartSel.nStartPara;
562 : }
563 0 : }
564 0 : }
565 : }
566 :
567 0 : if( ndbg < (nTextLen+2) )
568 : {
569 0 : *pPos++ = nLastPos + 1;
570 0 : *pPara++ = nLastPara;
571 :
572 0 : ndbg += 1;
573 0 : pText++;
574 : }
575 : else
576 : {
577 : OSL_FAIL( "array overflow while searching" );
578 : }
579 0 : }
580 : }
581 :
582 0 : uno::Reference< text::XText > xFound;
583 0 : ESelection aSel;
584 :
585 0 : uno::Reference< text::XTextRange > xRangeRef( xText, uno::UNO_QUERY );
586 0 : if( xRangeRef.is() )
587 0 : aSel = GetSelection( xRangeRef );
588 :
589 : sal_Int32 nStartPos;
590 0 : sal_Int32 nEndPos = 0;
591 0 : for( nStartPos = 0; nStartPos < nTextLen; nStartPos++ )
592 : {
593 0 : if( pConvertPara[nStartPos] == aSel.nStartPara && pConvertPos[nStartPos] == aSel.nStartPos )
594 0 : break;
595 : }
596 :
597 0 : if( Search( aText, nStartPos, nEndPos, pDescr ) )
598 : {
599 0 : if( nStartPos <= nTextLen && nEndPos <= nTextLen )
600 : {
601 0 : ESelection aSelection( pConvertPara[nStartPos], pConvertPos[nStartPos],
602 0 : pConvertPara[nEndPos], pConvertPos[nEndPos] );
603 : SvxUnoTextRange *pRange;
604 :
605 0 : SvxUnoTextBase* pParent = SvxUnoTextBase::getImplementation( xParent );
606 :
607 0 : if(pParent)
608 : {
609 0 : pRange = new SvxUnoTextRange( *pParent );
610 0 : xFound = (text::XText*)pRange;
611 0 : pRange->SetSelection(aSelection);
612 :
613 : }
614 : }
615 : else
616 : {
617 : OSL_FAIL("Array overflow while searching!");
618 : }
619 : }
620 :
621 0 : delete[] pConvertPos;
622 0 : delete[] pConvertPara;
623 :
624 0 : return uno::Reference< text::XTextRange > ( xFound, uno::UNO_QUERY );
625 : }
626 :
627 0 : bool SdUnoSearchReplaceShape::Search( const OUString& rText, sal_Int32& nStartPos, sal_Int32& nEndPos, SdUnoSearchReplaceDescriptor* pDescr ) throw()
628 : {
629 0 : OUString aSearchStr( pDescr->getSearchString() );
630 0 : OUString aText( rText );
631 :
632 0 : if( !pDescr->IsCaseSensitive() )
633 : {
634 0 : aText = aText.toAsciiLowerCase();
635 0 : aSearchStr = aSearchStr.toAsciiLowerCase();
636 : }
637 :
638 0 : sal_Int32 nFound = aText.indexOf( aSearchStr, nStartPos );
639 0 : if( nFound != -1 )
640 : {
641 0 : nStartPos = nFound;
642 0 : nEndPos = nFound + aSearchStr.getLength();
643 :
644 0 : if(pDescr->IsWords())
645 : {
646 0 : if( (nStartPos > 0 && aText[nStartPos-1] > ' ') ||
647 0 : (nEndPos < aText.getLength() && aText[nEndPos] > ' ') )
648 : {
649 0 : nStartPos++;
650 0 : return Search( aText, nStartPos, nEndPos, pDescr );
651 : }
652 : }
653 :
654 0 : return true;
655 : }
656 : else
657 0 : return false;
658 : }
659 :
660 0 : ESelection SdUnoSearchReplaceShape::GetSelection( uno::Reference< text::XTextRange > xTextRange ) throw()
661 : {
662 0 : ESelection aSel;
663 0 : SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( xTextRange );
664 :
665 0 : if(pRange)
666 0 : aSel = pRange->GetSelection();
667 :
668 0 : return aSel;
669 : }
670 :
671 0 : uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetShape( uno::Reference< text::XTextRange > xTextRange ) throw()
672 : {
673 0 : uno::Reference< drawing::XShape > xShape;
674 :
675 0 : if(xTextRange.is())
676 : {
677 0 : uno::Reference< text::XText > xText( xTextRange->getText() );
678 :
679 0 : if(xText.is())
680 : {
681 0 : do
682 : {
683 0 : xShape.set( xText, uno::UNO_QUERY );
684 0 : if(!xShape.is())
685 : {
686 0 : uno::Reference< text::XText > xParent( xText->getText() );
687 0 : if(!xParent.is() || xText.get() == xParent.get())
688 0 : return xShape;
689 :
690 0 : xText = xParent;
691 : }
692 0 : } while( !xShape.is() );
693 0 : }
694 : }
695 :
696 0 : return xShape;
697 : }
698 :
699 : /* ================================================================= */
700 : /** this class holds the parameters and status of a search or replace
701 : operation performed by class SdUnoSearchReplaceShape
702 : */
703 :
704 0 : UNO3_GETIMPLEMENTATION_IMPL( SdUnoSearchReplaceDescriptor );
705 :
706 0 : SdUnoSearchReplaceDescriptor::SdUnoSearchReplaceDescriptor( bool bReplace ) throw (css::uno::RuntimeException)
707 : {
708 0 : mpPropSet = new SvxItemPropertySet(ImplGetSearchPropertyMap(), SdrObject::GetGlobalDrawObjectItemPool());
709 :
710 0 : mbBackwards = false;
711 0 : mbCaseSensitive = false;
712 0 : mbWords = false;
713 :
714 0 : mbReplace = bReplace;
715 0 : }
716 :
717 0 : SdUnoSearchReplaceDescriptor::~SdUnoSearchReplaceDescriptor() throw()
718 : {
719 0 : delete mpPropSet;
720 0 : }
721 :
722 : // XSearchDescriptor
723 0 : OUString SAL_CALL SdUnoSearchReplaceDescriptor::getSearchString()
724 : throw(::com::sun::star::uno::RuntimeException, std::exception)
725 : {
726 0 : return maSearchStr;
727 : }
728 :
729 0 : void SAL_CALL SdUnoSearchReplaceDescriptor::setSearchString( const OUString& aString )
730 : throw(::com::sun::star::uno::RuntimeException, std::exception)
731 : {
732 0 : maSearchStr = aString;
733 0 : }
734 :
735 : // XReplaceDescriptor
736 0 : OUString SAL_CALL SdUnoSearchReplaceDescriptor::getReplaceString()
737 : throw(::com::sun::star::uno::RuntimeException, std::exception)
738 : {
739 0 : return maReplaceStr;
740 : }
741 :
742 0 : void SAL_CALL SdUnoSearchReplaceDescriptor::setReplaceString( const OUString& aReplaceString )
743 : throw(::com::sun::star::uno::RuntimeException, std::exception)
744 : {
745 0 : maReplaceStr = aReplaceString;
746 0 : }
747 :
748 : // XPropertySet
749 0 : uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL SdUnoSearchReplaceDescriptor::getPropertySetInfo()
750 : throw(::com::sun::star::uno::RuntimeException, std::exception)
751 : {
752 0 : SolarMutexGuard aGuard;
753 0 : return mpPropSet->getPropertySetInfo();
754 : }
755 :
756 0 : void SAL_CALL SdUnoSearchReplaceDescriptor::setPropertyValue( const OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue )
757 : 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)
758 : {
759 0 : SolarMutexGuard aGuard;
760 :
761 0 : const SfxItemPropertySimpleEntry* pEntry = mpPropSet->getPropertyMapEntry(aPropertyName);
762 :
763 0 : bool bOk = false;
764 :
765 0 : switch( pEntry ? pEntry->nWID : -1 )
766 : {
767 : case WID_SEARCH_BACKWARDS:
768 0 : bOk = (aValue >>= mbBackwards);
769 0 : break;
770 : case WID_SEARCH_CASE:
771 0 : bOk = (aValue >>= mbCaseSensitive);
772 0 : break;
773 : case WID_SEARCH_WORDS:
774 0 : bOk = (aValue >>= mbWords);
775 0 : break;
776 : default:
777 0 : throw beans::UnknownPropertyException();
778 : }
779 :
780 0 : if( !bOk )
781 0 : throw lang::IllegalArgumentException();
782 0 : }
783 :
784 0 : uno::Any SAL_CALL SdUnoSearchReplaceDescriptor::getPropertyValue( const OUString& PropertyName )
785 : throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
786 : {
787 0 : SolarMutexGuard aGuard;
788 :
789 0 : uno::Any aAny;
790 :
791 0 : const SfxItemPropertySimpleEntry* pEntry = mpPropSet->getPropertyMapEntry(PropertyName);
792 :
793 0 : switch( pEntry ? pEntry->nWID : -1 )
794 : {
795 : case WID_SEARCH_BACKWARDS:
796 0 : aAny <<= mbBackwards;
797 0 : break;
798 : case WID_SEARCH_CASE:
799 0 : aAny <<= mbCaseSensitive;
800 0 : break;
801 : case WID_SEARCH_WORDS:
802 0 : aAny <<= mbWords;
803 0 : break;
804 : default:
805 0 : throw beans::UnknownPropertyException();
806 : }
807 :
808 0 : return aAny;
809 : }
810 :
811 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) {}
812 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) {}
813 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) {}
814 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) {}
815 :
816 : /* ================================================================= */
817 :
818 0 : SdUnoFindAllAccess::SdUnoFindAllAccess( uno::Sequence< uno::Reference< uno::XInterface > >& rSequence ) throw()
819 0 : :maSequence( rSequence )
820 : {
821 0 : }
822 :
823 0 : SdUnoFindAllAccess::~SdUnoFindAllAccess() throw()
824 : {
825 0 : }
826 :
827 : // XElementAccess
828 0 : uno::Type SAL_CALL SdUnoFindAllAccess::getElementType()
829 : throw(::com::sun::star::uno::RuntimeException, std::exception)
830 : {
831 0 : return cppu::UnoType<text::XTextRange>::get();
832 : }
833 :
834 0 : sal_Bool SAL_CALL SdUnoFindAllAccess::hasElements()
835 : throw(::com::sun::star::uno::RuntimeException, std::exception)
836 : {
837 0 : return maSequence.getLength() > 0;
838 : }
839 :
840 : // XIndexAccess
841 0 : sal_Int32 SAL_CALL SdUnoFindAllAccess::getCount()
842 : throw(::com::sun::star::uno::RuntimeException, std::exception)
843 : {
844 0 : return maSequence.getLength();
845 : }
846 :
847 0 : uno::Any SAL_CALL SdUnoFindAllAccess::getByIndex( sal_Int32 Index )
848 : throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)
849 : {
850 0 : uno::Any aAny;
851 :
852 0 : if( Index < 0 || Index >= getCount() )
853 0 : throw lang::IndexOutOfBoundsException();
854 :
855 0 : const uno::Reference< uno::XInterface > *pRefs = maSequence.getConstArray();
856 0 : if(pRefs)
857 0 : aAny <<= pRefs[ Index ];
858 0 : return aAny;
859 114 : }
860 :
861 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|