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 : { OUString(UNO_NAME_SEARCH_BACKWARDS), WID_SEARCH_BACKWARDS, ::getBooleanCppuType(), 0, 0 },
46 0 : { OUString(UNO_NAME_SEARCH_CASE), WID_SEARCH_CASE, ::getBooleanCppuType(), 0, 0 },
47 0 : { OUString(UNO_NAME_SEARCH_WORDS), WID_SEARCH_WORDS, ::getBooleanCppuType(), 0, 0 },
48 : { OUString(), 0, css::uno::Type(), 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 0 : SdUnoSearchReplaceShape::SdUnoSearchReplaceShape( drawing::XDrawPage* pPage ) throw()
91 : : mpShape(NULL)
92 0 : , mpPage(pPage)
93 : {
94 0 : }
95 :
96 0 : SdUnoSearchReplaceShape::~SdUnoSearchReplaceShape() throw()
97 : {
98 0 : }
99 :
100 : // util::XReplaceable
101 0 : uno::Reference< util::XReplaceDescriptor > SAL_CALL SdUnoSearchReplaceShape::createReplaceDescriptor()
102 : throw( uno::RuntimeException, std::exception )
103 : {
104 0 : return new SdUnoSearchReplaceDescriptor(sal_True);
105 : }
106 :
107 0 : sal_Int32 SAL_CALL SdUnoSearchReplaceShape::replaceAll( const uno::Reference< util::XSearchDescriptor >& xDesc )
108 : throw( uno::RuntimeException, std::exception )
109 : {
110 0 : SdUnoSearchReplaceDescriptor* pDescr = SdUnoSearchReplaceDescriptor::getImplementation( xDesc );
111 0 : if( pDescr == NULL )
112 0 : return 0;
113 :
114 0 : sal_Int32 nFound = 0;
115 :
116 0 : uno::Reference< drawing::XShapes > xShapes;
117 0 : uno::Reference< drawing::XShape > xShape;
118 :
119 0 : SearchContext_impl* pContext = NULL;
120 0 : if(mpPage)
121 : {
122 0 : uno::Reference< drawing::XDrawPage > xPage( mpPage );
123 :
124 0 : xShapes.set( xPage, uno::UNO_QUERY );
125 :
126 0 : if( xShapes.is() && (xShapes->getCount() > 0) )
127 : {
128 0 : pContext = new SearchContext_impl( xShapes );
129 0 : xShape = pContext->firstShape();
130 : }
131 : else
132 : {
133 0 : xShapes = NULL;
134 0 : }
135 : }
136 : else
137 : {
138 0 : xShape = mpShape;
139 : }
140 :
141 0 : while( xShape.is() )
142 : {
143 : // replace in xShape
144 0 : uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY);
145 0 : uno::Reference< text::XTextRange > xRange(xText, uno::UNO_QUERY);
146 0 : uno::Reference< text::XTextRange > xFound;
147 :
148 0 : while( xRange.is() )
149 : {
150 0 : xFound = Search( xRange, pDescr );
151 0 : if( !xFound.is() )
152 0 : break;
153 :
154 0 : xFound->setString( pDescr->getReplaceString() );
155 0 : xRange = xFound->getEnd();
156 0 : nFound++;
157 : }
158 : // done with xShape -> get next shape
159 :
160 : // test if it's a group
161 0 : uno::Reference< drawing::XShapes > xGroupShape( xShape, uno::UNO_QUERY );
162 0 : if( xGroupShape.is() && ( xGroupShape->getCount() > 0 ) )
163 : {
164 0 : pContext = new SearchContext_impl( xGroupShape, pContext );
165 0 : xShape = pContext->firstShape();
166 : }
167 : else
168 : {
169 0 : if( pContext )
170 0 : xShape = pContext->nextShape();
171 : else
172 0 : xShape = NULL;
173 : }
174 :
175 : // test parent contexts for next shape if none
176 : // is found in the current context
177 0 : while( pContext && !xShape.is() )
178 : {
179 0 : if( pContext->getParent() )
180 : {
181 0 : SearchContext_impl* pOldContext = pContext;
182 0 : pContext = pContext->getParent();
183 0 : delete pOldContext;
184 0 : xShape = pContext->nextShape();
185 : }
186 : else
187 : {
188 0 : delete pContext;
189 0 : pContext = NULL;
190 0 : xShape = NULL;
191 : }
192 : }
193 0 : }
194 :
195 0 : return nFound;
196 : }
197 :
198 : // XSearchable
199 0 : uno::Reference< ::com::sun::star::util::XSearchDescriptor > SAL_CALL SdUnoSearchReplaceShape::createSearchDescriptor( )
200 : throw(::com::sun::star::uno::RuntimeException, std::exception)
201 : {
202 0 : return new SdUnoSearchReplaceDescriptor(sal_False);
203 : }
204 :
205 0 : uno::Reference< ::com::sun::star::container::XIndexAccess > SAL_CALL SdUnoSearchReplaceShape::findAll( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XSearchDescriptor >& xDesc )
206 : throw(::com::sun::star::uno::RuntimeException, std::exception)
207 : {
208 0 : SdUnoSearchReplaceDescriptor* pDescr = SdUnoSearchReplaceDescriptor::getImplementation( xDesc );
209 0 : if( pDescr == NULL )
210 0 : return uno::Reference< container::XIndexAccess > ();
211 :
212 :
213 0 : sal_Int32 nSequence = 32;
214 0 : sal_Int32 nFound = 0;
215 :
216 0 : uno::Sequence < uno::Reference< uno::XInterface > > aSeq( nSequence );
217 :
218 0 : uno::Reference< uno::XInterface > * pArray = aSeq.getArray();
219 :
220 0 : uno::Reference< drawing::XShapes > xShapes;
221 0 : uno::Reference< drawing::XShape > xShape;
222 :
223 0 : SearchContext_impl* pContext = NULL;
224 0 : if(mpPage)
225 : {
226 0 : uno::Reference< drawing::XDrawPage > xPage( mpPage );
227 0 : xShapes.set( xPage, uno::UNO_QUERY );
228 :
229 0 : if( xShapes.is() && xShapes->getCount() > 0 )
230 : {
231 0 : pContext = new SearchContext_impl( xShapes );
232 0 : xShape = pContext->firstShape();
233 : }
234 : else
235 : {
236 0 : xShapes = NULL;
237 0 : }
238 : }
239 : else
240 : {
241 0 : xShape = mpShape;
242 : }
243 0 : while( xShape.is() )
244 : {
245 : // find in xShape
246 0 : uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY);
247 0 : uno::Reference< text::XTextRange > xRange(xText, uno::UNO_QUERY);
248 0 : uno::Reference< text::XTextRange > xFound;
249 :
250 0 : while( xRange.is() )
251 : {
252 0 : xFound = Search( xRange, pDescr );
253 0 : if( !xFound.is() )
254 0 : break;
255 :
256 0 : if( nFound >= nSequence )
257 : {
258 0 : nSequence += 32;
259 0 : aSeq.realloc( nSequence );
260 0 : pArray = aSeq.getArray();
261 : }
262 :
263 0 : pArray[nFound++] = xFound;
264 :
265 0 : xRange = xFound->getEnd();
266 : }
267 : // done with shape -> get next shape
268 :
269 : // test if it's a group
270 0 : uno::Reference< drawing::XShapes > xGroupShape;
271 0 : xGroupShape.set( xShape, uno::UNO_QUERY );
272 :
273 0 : if( xGroupShape.is() && xGroupShape->getCount() > 0 )
274 : {
275 0 : pContext = new SearchContext_impl( xGroupShape, pContext );
276 0 : xShape = pContext->firstShape();
277 : }
278 : else
279 : {
280 0 : if( pContext )
281 0 : xShape = pContext->nextShape();
282 : else
283 0 : xShape = NULL;
284 : }
285 :
286 : // test parent contexts for next shape if none
287 : // is found in the current context
288 0 : while( pContext && !xShape.is() )
289 : {
290 0 : if( pContext->getParent() )
291 : {
292 0 : SearchContext_impl* pOldContext = pContext;
293 0 : pContext = pContext->getParent();
294 0 : delete pOldContext;
295 0 : xShape = pContext->nextShape();
296 : }
297 : else
298 : {
299 0 : delete pContext;
300 0 : pContext = NULL;
301 0 : xShape = NULL;
302 : }
303 : }
304 0 : }
305 :
306 0 : if( nFound != nSequence )
307 0 : aSeq.realloc( nFound );
308 :
309 0 : return (container::XIndexAccess*)new SdUnoFindAllAccess( aSeq );
310 : }
311 :
312 0 : uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SdUnoSearchReplaceShape::findFirst( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XSearchDescriptor >& xDesc )
313 : throw(::com::sun::star::uno::RuntimeException, std::exception)
314 : {
315 0 : uno::Reference< text::XTextRange > xRange( GetCurrentShape(), uno::UNO_QUERY );
316 0 : if( xRange.is() )
317 0 : return findNext( xRange, xDesc );
318 :
319 0 : return uno::Reference< uno::XInterface > ();
320 : }
321 :
322 0 : uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetCurrentShape() const throw()
323 : {
324 0 : uno::Reference< drawing::XShape > xShape;
325 :
326 0 : if( mpPage )
327 : {
328 0 : uno::Reference< drawing::XDrawPage > xPage( mpPage );
329 0 : uno::Reference< container::XIndexAccess > xShapes( xPage, uno::UNO_QUERY );
330 0 : if( xShapes.is() )
331 : {
332 0 : if(xShapes->getCount() > 0)
333 : {
334 0 : xShapes->getByIndex(0) >>= xShape;
335 : }
336 0 : }
337 : }
338 0 : else if( mpShape )
339 : {
340 0 : xShape = mpShape;
341 : }
342 :
343 0 : return xShape;
344 :
345 : }
346 :
347 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 )
348 : throw(::com::sun::star::uno::RuntimeException, std::exception)
349 : {
350 0 : SdUnoSearchReplaceDescriptor* pDescr = SdUnoSearchReplaceDescriptor::getImplementation( xDesc );
351 :
352 0 : uno::Reference< uno::XInterface > xFound;
353 :
354 0 : uno::Reference< text::XTextRange > xRange( xStartAt, uno::UNO_QUERY );
355 0 : if(pDescr && xRange.is() )
356 : {
357 :
358 0 : uno::Reference< text::XTextRange > xCurrentRange( xStartAt, uno::UNO_QUERY );
359 :
360 0 : uno::Reference< drawing::XShape > xCurrentShape( GetShape( xCurrentRange ) );
361 :
362 0 : while(!xFound.is() && xRange.is())
363 : {
364 0 : xFound = Search( xRange, pDescr );
365 0 : if(!xFound.is())
366 : {
367 : // we need a new starting range now
368 0 : xRange = NULL;
369 :
370 0 : if(mpPage)
371 : {
372 0 : uno::Reference< drawing::XDrawPage > xPage( mpPage );
373 :
374 : // we do a page wide search, so skip to the next shape here
375 0 : uno::Reference< container::XIndexAccess > xShapes( xPage, uno::UNO_QUERY );
376 :
377 : // get next shape on our page
378 0 : if( xShapes.is() )
379 : {
380 0 : uno::Reference< drawing::XShape > xFound2( GetNextShape( xShapes, xCurrentShape ) );
381 0 : if( xFound2.is() && (xFound2.get() != xCurrentShape.get()) )
382 0 : xCurrentShape = xFound2;
383 : else
384 0 : xCurrentShape = NULL;
385 :
386 0 : xRange.set( xCurrentShape, uno::UNO_QUERY );
387 0 : if(!(xCurrentShape.is() && (xRange.is())))
388 0 : xRange = NULL;
389 0 : }
390 : }
391 : else
392 : {
393 : // we search only in this shape, so end search if we have
394 : // not found anything
395 : }
396 : }
397 0 : }
398 : }
399 0 : return xFound;
400 : }
401 :
402 : /** this method returns the shape that follows xCurrentShape in the shape collection xShapes.
403 : It steps recursive into groupshapes and returns the xCurrentShape if it is the last
404 : shape in this collection */
405 0 : uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetNextShape( uno::Reference< container::XIndexAccess > xShapes, uno::Reference< drawing::XShape > xCurrentShape ) throw()
406 : {
407 0 : uno::Reference< drawing::XShape > xFound;
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[nStartPos-1] > ' ') ||
650 0 : (nEndPos < aText.getLength() && aText[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, std::exception)
728 : {
729 0 : return maSearchStr;
730 : }
731 :
732 0 : void SAL_CALL SdUnoSearchReplaceDescriptor::setSearchString( const OUString& aString )
733 : throw(::com::sun::star::uno::RuntimeException, std::exception)
734 : {
735 0 : maSearchStr = aString;
736 0 : }
737 :
738 : // XReplaceDescriptor
739 0 : OUString SAL_CALL SdUnoSearchReplaceDescriptor::getReplaceString()
740 : throw(::com::sun::star::uno::RuntimeException, std::exception)
741 : {
742 0 : return maReplaceStr;
743 : }
744 :
745 0 : void SAL_CALL SdUnoSearchReplaceDescriptor::setReplaceString( const OUString& aReplaceString )
746 : throw(::com::sun::star::uno::RuntimeException, std::exception)
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, std::exception)
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, std::exception)
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, std::exception)
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, std::exception) {}
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, std::exception) {}
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, std::exception) {}
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, std::exception) {}
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, std::exception)
834 : {
835 0 : return cppu::UnoType<text::XTextRange>::get();
836 : }
837 :
838 0 : sal_Bool SAL_CALL SdUnoFindAllAccess::hasElements()
839 : throw(::com::sun::star::uno::RuntimeException, std::exception)
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, std::exception)
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, std::exception)
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 : }
864 :
865 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|