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 64 : SdUnoSearchReplaceShape::SdUnoSearchReplaceShape( drawing::XDrawPage* pPage ) throw()
91 : {
92 64 : mpPage = pPage;
93 64 : }
94 :
95 59 : SdUnoSearchReplaceShape::~SdUnoSearchReplaceShape() throw()
96 : {
97 59 : }
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 : xPage->queryInterface( ITYPE( drawing::XShapes ) ) >>= xShapes;
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 : xPage->queryInterface( ITYPE( drawing::XShapes ) ) >>= xShapes;
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 : uno::Any aAny( xShape->queryInterface( ITYPE( drawing::XShapes )));
271 :
272 0 : if( (aAny >>= xGroupShape ) && 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 : xCurrentShape->queryInterface( ITYPE( text::XTextRange ) ) >>= xRange;
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 : 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 : 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 : uno::Any aAny( xText->queryInterface( ITYPE( text::XText )) );
472 0 : aAny >>= xParent;
473 : }
474 :
475 0 : const OUString aText( xParent->getString() );
476 :
477 0 : const sal_Int32 nTextLen = aText.getLength();
478 :
479 0 : sal_Int32* pConvertPos = new sal_Int32[nTextLen+2];
480 0 : sal_Int32* pConvertPara = new sal_Int32[nTextLen+2];
481 :
482 0 : int ndbg = 0;
483 0 : const sal_Unicode* pText = aText.getStr();
484 :
485 0 : sal_Int32* pPos = pConvertPos;
486 0 : sal_Int32* pPara = pConvertPara;
487 :
488 0 : sal_Int32 nLastPos = 0, nLastPara = 0;
489 :
490 0 : uno::Reference< container::XEnumerationAccess > xEnumAccess( xParent, uno::UNO_QUERY );
491 :
492 : // first we fill the arrys with the position and paragraph for every character
493 : // inside the text
494 0 : if( xEnumAccess.is() )
495 : {
496 0 : uno::Reference< container::XEnumeration > xParaEnum( xEnumAccess->createEnumeration() );
497 :
498 0 : while(xParaEnum->hasMoreElements())
499 : {
500 0 : uno::Reference< text::XTextContent > xParagraph( xParaEnum->nextElement(), uno::UNO_QUERY );
501 0 : if( xParagraph.is() )
502 0 : xEnumAccess.query( xParagraph );
503 : else
504 0 : xEnumAccess.clear();
505 :
506 0 : if( xEnumAccess.is() )
507 : {
508 0 : uno::Reference< container::XEnumeration > xPortionEnum( xEnumAccess->createEnumeration() );
509 0 : if( xPortionEnum.is() )
510 : {
511 0 : while(xPortionEnum->hasMoreElements())
512 : {
513 0 : uno::Reference< text::XTextRange > xPortion( xPortionEnum->nextElement(), uno::UNO_QUERY );
514 0 : if( xPortion.is() )
515 : {
516 0 : const OUString aPortion( xPortion->getString() );
517 0 : const sal_Int32 nLen = aPortion.getLength();
518 :
519 0 : ESelection aStartSel( GetSelection( xPortion->getStart() ) );
520 0 : ESelection aEndSel( GetSelection( xPortion->getEnd() ) );
521 :
522 : // special case for empty portions with content or length one portions with content (fields)
523 0 : if( (aStartSel.nStartPos == aEndSel.nStartPos) || ( (aStartSel.nStartPos == (aEndSel.nStartPos - 1)) && (nLen > 1) ) )
524 : {
525 0 : for( sal_Int32 i = 0; i < nLen; i++ )
526 : {
527 0 : if( ndbg < (nTextLen+2) )
528 : {
529 0 : *pPos++ = aStartSel.nStartPos;
530 0 : *pPara++ = aStartSel.nStartPara;
531 :
532 0 : ndbg += 1;
533 0 : pText++;
534 : }
535 : else
536 : {
537 : OSL_FAIL( "array overflow while searching" );
538 : }
539 : }
540 :
541 0 : nLastPos = aStartSel.nStartPos;
542 : }
543 : // normal case
544 : else
545 : {
546 0 : for( sal_Int32 i = 0; i < nLen; i++ )
547 : {
548 0 : if( ndbg < (nTextLen+2) )
549 : {
550 0 : *pPos++ = aStartSel.nStartPos++;
551 0 : *pPara++ = aStartSel.nStartPara;
552 :
553 0 : ndbg += 1;
554 0 : pText++;
555 : }
556 : else
557 : {
558 : OSL_FAIL( "array overflow while searching" );
559 : }
560 : }
561 :
562 0 : nLastPos = aStartSel.nStartPos - 1;
563 : DBG_ASSERT( aEndSel.nStartPos == aStartSel.nStartPos, "Search is not working" );
564 : }
565 0 : nLastPara = aStartSel.nStartPara;
566 : }
567 0 : }
568 0 : }
569 : }
570 :
571 0 : if( ndbg < (nTextLen+2) )
572 : {
573 0 : *pPos++ = nLastPos + 1;
574 0 : *pPara++ = nLastPara;
575 :
576 0 : ndbg += 1;
577 0 : pText++;
578 : }
579 : else
580 : {
581 : OSL_FAIL( "array overflow while searching" );
582 : }
583 0 : }
584 : }
585 :
586 0 : uno::Reference< text::XText > xFound;
587 0 : ESelection aSel;
588 :
589 0 : uno::Reference< text::XTextRange > xRangeRef( xText, uno::UNO_QUERY );
590 0 : if( xRangeRef.is() )
591 0 : aSel = GetSelection( xRangeRef );
592 :
593 : sal_Int32 nStartPos;
594 0 : sal_Int32 nEndPos = 0;
595 0 : for( nStartPos = 0; nStartPos < nTextLen; nStartPos++ )
596 : {
597 0 : if( pConvertPara[nStartPos] == aSel.nStartPara && pConvertPos[nStartPos] == aSel.nStartPos )
598 0 : break;
599 : }
600 :
601 0 : if( Search( aText, nStartPos, nEndPos, pDescr ) )
602 : {
603 0 : if( nStartPos <= nTextLen && nEndPos <= nTextLen )
604 : {
605 0 : ESelection aSelection( (sal_uInt16)pConvertPara[nStartPos], (sal_uInt16)pConvertPos[nStartPos],
606 0 : (sal_uInt16)pConvertPara[nEndPos], (sal_uInt16)pConvertPos[nEndPos] );
607 : SvxUnoTextRange *pRange;
608 :
609 0 : SvxUnoTextBase* pParent = SvxUnoTextBase::getImplementation( xParent );
610 :
611 0 : if(pParent)
612 : {
613 0 : pRange = new SvxUnoTextRange( *pParent );
614 0 : xFound = (text::XText*)pRange;
615 0 : pRange->SetSelection(aSelection);
616 :
617 : }
618 : }
619 : else
620 : {
621 : OSL_FAIL("Array overflow while searching!");
622 : }
623 : }
624 :
625 0 : delete[] pConvertPos;
626 0 : delete[] pConvertPara;
627 :
628 0 : return uno::Reference< text::XTextRange > ( xFound, uno::UNO_QUERY );
629 : }
630 :
631 0 : sal_Bool SdUnoSearchReplaceShape::Search( const OUString& rText, sal_Int32& nStartPos, sal_Int32& nEndPos, SdUnoSearchReplaceDescriptor* pDescr ) throw()
632 : {
633 0 : OUString aSearchStr( pDescr->getSearchString() );
634 0 : OUString aText( rText );
635 :
636 0 : if( !pDescr->IsCaseSensitive() )
637 : {
638 0 : aText = aText.toAsciiLowerCase();
639 0 : aSearchStr = aSearchStr.toAsciiLowerCase();
640 : }
641 :
642 0 : sal_Int32 nFound = aText.indexOf( aSearchStr, nStartPos );
643 0 : if( nFound != -1 )
644 : {
645 0 : nStartPos = nFound;
646 0 : nEndPos = nFound + aSearchStr.getLength();
647 :
648 0 : if(pDescr->IsWords())
649 : {
650 0 : if( (nStartPos > 0 && aText.getStr()[nStartPos-1] > ' ') ||
651 0 : (nEndPos < aText.getLength() && aText.getStr()[nEndPos] > ' ') )
652 : {
653 0 : nStartPos++;
654 0 : return Search( aText, nStartPos, nEndPos, pDescr );
655 : }
656 : }
657 :
658 0 : return sal_True;
659 : }
660 : else
661 0 : return sal_False;
662 : }
663 :
664 0 : ESelection SdUnoSearchReplaceShape::GetSelection( uno::Reference< text::XTextRange > xTextRange ) throw()
665 : {
666 0 : ESelection aSel;
667 0 : SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( xTextRange );
668 :
669 0 : if(pRange)
670 0 : aSel = pRange->GetSelection();
671 :
672 0 : return aSel;
673 : }
674 :
675 0 : uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetShape( uno::Reference< text::XTextRange > xTextRange ) throw()
676 : {
677 0 : uno::Reference< drawing::XShape > xShape;
678 :
679 0 : if(xTextRange.is())
680 : {
681 0 : uno::Reference< text::XText > xText( xTextRange->getText() );
682 :
683 0 : if(xText.is())
684 : {
685 0 : do
686 : {
687 0 : xText->queryInterface( ITYPE( drawing::XShape )) >>= xShape;
688 0 : if(!xShape.is())
689 : {
690 0 : uno::Reference< text::XText > xParent( xText->getText() );
691 0 : if(!xParent.is() || xText.get() == xParent.get())
692 : return xShape;
693 :
694 0 : xText = xParent;
695 : }
696 0 : } while( !xShape.is() );
697 0 : }
698 : }
699 :
700 0 : return xShape;
701 : }
702 :
703 : /* ================================================================= */
704 : /** this class holds the parameters and status of a search or replace
705 : operation performed by class SdUnoSearchReplaceShape
706 : */
707 :
708 0 : UNO3_GETIMPLEMENTATION_IMPL( SdUnoSearchReplaceDescriptor );
709 :
710 0 : SdUnoSearchReplaceDescriptor::SdUnoSearchReplaceDescriptor( sal_Bool bReplace ) throw()
711 : {
712 0 : mpPropSet = new SvxItemPropertySet(ImplGetSearchPropertyMap(), SdrObject::GetGlobalDrawObjectItemPool());
713 :
714 0 : mbBackwards = sal_False;
715 0 : mbCaseSensitive = sal_False;
716 0 : mbWords = sal_False;
717 :
718 0 : mbReplace = bReplace;
719 0 : }
720 :
721 0 : SdUnoSearchReplaceDescriptor::~SdUnoSearchReplaceDescriptor() throw()
722 : {
723 0 : delete mpPropSet;
724 0 : }
725 :
726 : // XSearchDescriptor
727 0 : OUString SAL_CALL SdUnoSearchReplaceDescriptor::getSearchString()
728 : throw(::com::sun::star::uno::RuntimeException)
729 : {
730 0 : return maSearchStr;
731 : }
732 :
733 0 : void SAL_CALL SdUnoSearchReplaceDescriptor::setSearchString( const OUString& aString )
734 : throw(::com::sun::star::uno::RuntimeException)
735 : {
736 0 : maSearchStr = aString;
737 0 : }
738 :
739 : // XReplaceDescriptor
740 0 : OUString SAL_CALL SdUnoSearchReplaceDescriptor::getReplaceString()
741 : throw(::com::sun::star::uno::RuntimeException)
742 : {
743 0 : return maReplaceStr;
744 : }
745 :
746 0 : void SAL_CALL SdUnoSearchReplaceDescriptor::setReplaceString( const ::rtl::OUString& aReplaceString )
747 : throw(::com::sun::star::uno::RuntimeException)
748 : {
749 0 : maReplaceStr = aReplaceString;
750 0 : }
751 :
752 : // XPropertySet
753 0 : uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL SdUnoSearchReplaceDescriptor::getPropertySetInfo()
754 : throw(::com::sun::star::uno::RuntimeException)
755 : {
756 0 : SolarMutexGuard aGuard;
757 0 : return mpPropSet->getPropertySetInfo();
758 : }
759 :
760 0 : void SAL_CALL SdUnoSearchReplaceDescriptor::setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue )
761 : 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)
762 : {
763 0 : SolarMutexGuard aGuard;
764 :
765 0 : const SfxItemPropertySimpleEntry* pEntry = mpPropSet->getPropertyMapEntry(aPropertyName);
766 :
767 0 : sal_Bool bOk = sal_False;
768 :
769 0 : switch( pEntry ? pEntry->nWID : -1 )
770 : {
771 : case WID_SEARCH_BACKWARDS:
772 0 : bOk = (aValue >>= mbBackwards);
773 0 : break;
774 : case WID_SEARCH_CASE:
775 0 : bOk = (aValue >>= mbCaseSensitive);
776 0 : break;
777 : case WID_SEARCH_WORDS:
778 0 : bOk = (aValue >>= mbWords);
779 0 : break;
780 : default:
781 0 : throw beans::UnknownPropertyException();
782 : }
783 :
784 0 : if( !bOk )
785 0 : throw lang::IllegalArgumentException();
786 0 : }
787 :
788 0 : uno::Any SAL_CALL SdUnoSearchReplaceDescriptor::getPropertyValue( const ::rtl::OUString& PropertyName )
789 : throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
790 : {
791 0 : SolarMutexGuard aGuard;
792 :
793 0 : uno::Any aAny;
794 :
795 0 : const SfxItemPropertySimpleEntry* pEntry = mpPropSet->getPropertyMapEntry(PropertyName);
796 :
797 0 : switch( pEntry ? pEntry->nWID : -1 )
798 : {
799 : case WID_SEARCH_BACKWARDS:
800 0 : aAny <<= (sal_Bool)mbBackwards;
801 0 : break;
802 : case WID_SEARCH_CASE:
803 0 : aAny <<= (sal_Bool)mbCaseSensitive;
804 0 : break;
805 : case WID_SEARCH_WORDS:
806 0 : aAny <<= (sal_Bool)mbWords;
807 0 : break;
808 : default:
809 0 : throw beans::UnknownPropertyException();
810 : }
811 :
812 0 : return aAny;
813 : }
814 :
815 0 : void SAL_CALL SdUnoSearchReplaceDescriptor::addPropertyChangeListener( const ::rtl::OUString& , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) {}
816 0 : void SAL_CALL SdUnoSearchReplaceDescriptor::removePropertyChangeListener( const ::rtl::OUString& , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) {}
817 0 : void SAL_CALL SdUnoSearchReplaceDescriptor::addVetoableChangeListener( const ::rtl::OUString& , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) {}
818 0 : void SAL_CALL SdUnoSearchReplaceDescriptor::removeVetoableChangeListener( const ::rtl::OUString& , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) {}
819 :
820 :
821 : /* ================================================================= */
822 :
823 0 : SdUnoFindAllAccess::SdUnoFindAllAccess( uno::Sequence< uno::Reference< uno::XInterface > >& rSequence ) throw()
824 0 : :maSequence( rSequence )
825 : {
826 0 : }
827 :
828 0 : SdUnoFindAllAccess::~SdUnoFindAllAccess() throw()
829 : {
830 0 : }
831 :
832 : // XElementAccess
833 0 : uno::Type SAL_CALL SdUnoFindAllAccess::getElementType()
834 : throw(::com::sun::star::uno::RuntimeException)
835 : {
836 0 : return ITYPE( text::XTextRange );
837 : }
838 :
839 0 : sal_Bool SAL_CALL SdUnoFindAllAccess::hasElements()
840 : throw(::com::sun::star::uno::RuntimeException)
841 : {
842 0 : return maSequence.getLength() > 0;
843 : }
844 :
845 : // XIndexAccess
846 0 : sal_Int32 SAL_CALL SdUnoFindAllAccess::getCount()
847 : throw(::com::sun::star::uno::RuntimeException)
848 : {
849 0 : return maSequence.getLength();
850 : }
851 :
852 0 : uno::Any SAL_CALL SdUnoFindAllAccess::getByIndex( sal_Int32 Index )
853 : throw(::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
854 : {
855 0 : uno::Any aAny;
856 :
857 0 : if( Index < 0 || Index >= getCount() )
858 0 : throw lang::IndexOutOfBoundsException();
859 :
860 0 : const uno::Reference< uno::XInterface > *pRefs = maSequence.getConstArray();
861 0 : if(pRefs)
862 0 : aAny <<= pRefs[ Index ];
863 0 : return aAny;
864 : }
865 :
866 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|