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