bump product version to 6.4.0.3
[LibreOffice.git] / sd / source / ui / unoidl / unosrch.cxx
blob45177d2adfd4c3bb0236b6ef5e2667f9f198c799
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <memory>
21 #include <sal/config.h>
23 #include <com/sun/star/drawing/XShapes.hpp>
24 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
25 #include <vcl/svapp.hxx>
27 #include <svx/svdobj.hxx>
28 #include <svx/svdpool.hxx>
29 #include <editeng/unoipset.hxx>
30 #include <editeng/unotext.hxx>
31 #include <tools/debug.hxx>
33 #include <unoprnms.hxx>
34 #include <unosrch.hxx>
36 using namespace ::com::sun::star;
38 #define WID_SEARCH_BACKWARDS 0
39 #define WID_SEARCH_CASE 1
40 #define WID_SEARCH_WORDS 2
42 static const SfxItemPropertyMapEntry* ImplGetSearchPropertyMap()
44 static const SfxItemPropertyMapEntry aSearchPropertyMap_Impl[] =
46 { OUString(UNO_NAME_SEARCH_BACKWARDS), WID_SEARCH_BACKWARDS, cppu::UnoType<bool>::get(), 0, 0 },
47 { OUString(UNO_NAME_SEARCH_CASE), WID_SEARCH_CASE, cppu::UnoType<bool>::get(), 0, 0 },
48 { OUString(UNO_NAME_SEARCH_WORDS), WID_SEARCH_WORDS, cppu::UnoType<bool>::get(), 0, 0 },
49 { OUString(), 0, css::uno::Type(), 0, 0 }
52 return aSearchPropertyMap_Impl;
55 class SearchContext_impl
57 uno::Reference< drawing::XShapes > mxShapes;
58 sal_Int32 mnIndex;
60 public:
61 SearchContext_impl(uno::Reference<drawing::XShapes> const& xShapes)
62 : mxShapes( xShapes ), mnIndex( -1 ) {}
64 uno::Reference< drawing::XShape > firstShape()
66 mnIndex = -1;
67 return nextShape();
70 uno::Reference< drawing::XShape > nextShape()
72 uno::Reference< drawing::XShape > xShape;
73 mnIndex++;
74 if( mxShapes.is() && mxShapes->getCount() > mnIndex )
76 mxShapes->getByIndex( mnIndex ) >>= xShape;
78 return xShape;
82 /* ================================================================= */
83 /** this class implements a search or replace operation on a given
84 page or a given sdrobj
87 SdUnoSearchReplaceShape::SdUnoSearchReplaceShape( drawing::XDrawPage* pPage ) throw()
88 : mpPage(pPage)
92 SdUnoSearchReplaceShape::~SdUnoSearchReplaceShape() throw()
96 // util::XReplaceable
97 uno::Reference< util::XReplaceDescriptor > SAL_CALL SdUnoSearchReplaceShape::createReplaceDescriptor()
99 return new SdUnoSearchReplaceDescriptor;
102 sal_Int32 SAL_CALL SdUnoSearchReplaceShape::replaceAll( const uno::Reference< util::XSearchDescriptor >& xDesc )
104 SdUnoSearchReplaceDescriptor* pDescr = comphelper::getUnoTunnelImplementation<SdUnoSearchReplaceDescriptor>( xDesc );
105 if( pDescr == nullptr )
106 return 0;
108 sal_Int32 nFound = 0;
110 uno::Reference< drawing::XShapes > xShapes;
111 uno::Reference< drawing::XShape > xShape;
113 std::vector<SearchContext_impl> aContexts;
114 if(mpPage)
116 uno::Reference< drawing::XDrawPage > xPage( mpPage );
118 xShapes.set( xPage, uno::UNO_QUERY );
120 if( xShapes.is() && (xShapes->getCount() > 0) )
122 aContexts.push_back(SearchContext_impl(xShapes));
123 xShape = aContexts.back().firstShape();
125 else
127 xShapes = nullptr;
131 while( xShape.is() )
133 // replace in xShape
134 uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY);
135 uno::Reference< text::XTextRange > xRange = xText;
136 uno::Reference< text::XTextRange > xFound;
138 while( xRange.is() )
140 xFound = Search( xRange, pDescr );
141 if( !xFound.is() )
142 break;
144 xFound->setString( pDescr->getReplaceString() );
145 xRange = xFound->getEnd();
146 nFound++;
148 // done with xShape -> get next shape
150 // test if it's a group
151 uno::Reference< drawing::XShapes > xGroupShape( xShape, uno::UNO_QUERY );
152 if( xGroupShape.is() && ( xGroupShape->getCount() > 0 ) )
154 aContexts.push_back(SearchContext_impl(xGroupShape));
155 xShape = aContexts.back().firstShape();
157 else
159 if (!aContexts.empty())
160 xShape = aContexts.back().nextShape();
161 else
162 xShape = nullptr;
165 // test parent contexts for next shape if none
166 // is found in the current context
167 while (!aContexts.empty() && !xShape.is())
169 aContexts.pop_back();
170 if (!aContexts.empty())
171 xShape = aContexts.back().nextShape();
175 return nFound;
178 // XSearchable
179 uno::Reference< css::util::XSearchDescriptor > SAL_CALL SdUnoSearchReplaceShape::createSearchDescriptor( )
181 return new SdUnoSearchReplaceDescriptor;
184 uno::Reference< css::container::XIndexAccess > SAL_CALL SdUnoSearchReplaceShape::findAll( const css::uno::Reference< css::util::XSearchDescriptor >& xDesc )
186 SdUnoSearchReplaceDescriptor* pDescr = comphelper::getUnoTunnelImplementation<SdUnoSearchReplaceDescriptor>( xDesc );
187 if( pDescr == nullptr )
188 return uno::Reference< container::XIndexAccess > ();
190 sal_Int32 nSequence = 32;
191 sal_Int32 nFound = 0;
193 uno::Sequence < uno::Reference< uno::XInterface > > aSeq( nSequence );
195 uno::Reference< uno::XInterface > * pArray = aSeq.getArray();
197 uno::Reference< drawing::XShapes > xShapes;
198 uno::Reference< drawing::XShape > xShape;
200 std::vector<SearchContext_impl> aContexts;
201 if(mpPage)
203 uno::Reference< drawing::XDrawPage > xPage( mpPage );
204 xShapes.set( xPage, uno::UNO_QUERY );
206 if( xShapes.is() && xShapes->getCount() > 0 )
208 aContexts.push_back(SearchContext_impl(xShapes));
209 xShape = aContexts.back().firstShape();
211 else
213 xShapes = nullptr;
217 while( xShape.is() )
219 // find in xShape
220 uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY);
221 uno::Reference< text::XTextRange > xRange = xText;
222 uno::Reference< text::XTextRange > xFound;
224 while( xRange.is() )
226 xFound = Search( xRange, pDescr );
227 if( !xFound.is() )
228 break;
230 if( nFound >= nSequence )
232 nSequence += 32;
233 aSeq.realloc( nSequence );
234 pArray = aSeq.getArray();
237 pArray[nFound++] = xFound;
239 xRange = xFound->getEnd();
241 // done with shape -> get next shape
243 // test if it's a group
244 uno::Reference< drawing::XShapes > xGroupShape;
245 xGroupShape.set( xShape, uno::UNO_QUERY );
247 if( xGroupShape.is() && xGroupShape->getCount() > 0 )
249 aContexts.push_back(SearchContext_impl(xGroupShape));
250 xShape = aContexts.back().firstShape();
252 else
254 if (!aContexts.empty())
255 xShape = aContexts.back().nextShape();
256 else
257 xShape = nullptr;
260 // test parent contexts for next shape if none
261 // is found in the current context
262 while (!aContexts.empty() && !xShape.is())
264 aContexts.pop_back();
265 if (!aContexts.empty())
266 xShape = aContexts.back().nextShape();
270 if( nFound != nSequence )
271 aSeq.realloc( nFound );
273 uno::Reference<css::container::XIndexAccess> xRet(new SdUnoFindAllAccess(aSeq));
274 return xRet;
277 uno::Reference< css::uno::XInterface > SAL_CALL SdUnoSearchReplaceShape::findFirst( const css::uno::Reference< css::util::XSearchDescriptor >& xDesc )
279 uno::Reference< text::XTextRange > xRange( GetCurrentShape(), uno::UNO_QUERY );
280 if( xRange.is() )
281 return findNext( xRange, xDesc );
283 return uno::Reference< uno::XInterface > ();
286 uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetCurrentShape() const throw()
288 uno::Reference< drawing::XShape > xShape;
290 if( mpPage )
292 uno::Reference< drawing::XDrawPage > xPage( mpPage );
293 uno::Reference< container::XIndexAccess > xShapes( xPage, uno::UNO_QUERY );
294 if( xShapes.is() )
296 if(xShapes->getCount() > 0)
298 xShapes->getByIndex(0) >>= xShape;
303 return xShape;
307 uno::Reference< css::uno::XInterface > SAL_CALL SdUnoSearchReplaceShape::findNext( const css::uno::Reference< css::uno::XInterface >& xStartAt, const css::uno::Reference< css::util::XSearchDescriptor >& xDesc )
309 SdUnoSearchReplaceDescriptor* pDescr = comphelper::getUnoTunnelImplementation<SdUnoSearchReplaceDescriptor>( xDesc );
311 uno::Reference< uno::XInterface > xFound;
313 uno::Reference< text::XTextRange > xRange( xStartAt, uno::UNO_QUERY );
314 if(pDescr && xRange.is() )
317 uno::Reference< text::XTextRange > xCurrentRange( xStartAt, uno::UNO_QUERY );
319 uno::Reference< drawing::XShape > xCurrentShape( GetShape( xCurrentRange ) );
321 while(!xFound.is() && xRange.is())
323 xFound = Search( xRange, pDescr );
324 if(!xFound.is())
326 // we need a new starting range now
327 xRange = nullptr;
329 if(mpPage)
331 uno::Reference< drawing::XDrawPage > xPage( mpPage );
333 // we do a page wide search, so skip to the next shape here
334 uno::Reference< container::XIndexAccess > xShapes( xPage, uno::UNO_QUERY );
336 // get next shape on our page
337 if( xShapes.is() )
339 uno::Reference< drawing::XShape > xFound2( GetNextShape( xShapes, xCurrentShape ) );
340 if( xFound2.is() && (xFound2.get() != xCurrentShape.get()) )
341 xCurrentShape = xFound2;
342 else
343 xCurrentShape = nullptr;
345 xRange.set( xCurrentShape, uno::UNO_QUERY );
346 if(!(xCurrentShape.is() && (xRange.is())))
347 xRange = nullptr;
350 else
352 // we search only in this shape, so end search if we have
353 // not found anything
358 return xFound;
361 /** this method returns the shape that follows xCurrentShape in the shape collection xShapes.
362 It steps recursive into groupshapes and returns the xCurrentShape if it is the last
363 shape in this collection */
364 uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetNextShape( const uno::Reference< container::XIndexAccess >& xShapes, const uno::Reference< drawing::XShape >& xCurrentShape ) throw()
366 uno::Reference< drawing::XShape > xFound;
368 if(xShapes.is() && xCurrentShape.is())
370 const sal_Int32 nCount = xShapes->getCount();
371 for( sal_Int32 i = 0; i < nCount; i++ )
373 uno::Reference< drawing::XShape > xSearchShape;
374 xShapes->getByIndex(i) >>= xSearchShape;
376 if( xSearchShape.is() )
378 uno::Reference< container::XIndexAccess > xGroup( xSearchShape, uno::UNO_QUERY );
380 if( xCurrentShape.get() == xSearchShape.get() )
382 if( xGroup.is() && xGroup->getCount() > 0 )
384 xGroup->getByIndex( 0 ) >>= xFound;
386 else
388 i++;
389 if( i < nCount )
390 xShapes->getByIndex( i ) >>= xFound;
391 else
392 xFound = xCurrentShape;
395 break;
397 else if( xGroup.is() )
399 xFound = GetNextShape( xGroup, xCurrentShape );
400 if( xFound.is() )
402 if( xFound.get() == xCurrentShape.get() )
404 // the current shape was found at the end of the group
405 i++;
406 if( i < nCount )
408 xShapes->getByIndex(i) >>= xFound;
411 break;
418 return xFound;
421 uno::Reference< text::XTextRange > SdUnoSearchReplaceShape::Search( const uno::Reference< text::XTextRange >& xText, SdUnoSearchReplaceDescriptor* pDescr )
423 if(!xText.is())
424 return uno::Reference< text::XTextRange > ();
426 uno::Reference< text::XText > xParent( xText->getText() );
428 if( !xParent.is() )
430 xParent.set( xText, uno::UNO_QUERY );
433 const OUString aText( xParent->getString() );
435 const sal_Int32 nTextLen = aText.getLength();
437 std::unique_ptr<sal_Int32[]> pConvertPos( new sal_Int32[nTextLen+2] );
438 std::unique_ptr<sal_Int32[]> pConvertPara( new sal_Int32[nTextLen+2] );
440 const sal_Unicode* pText = aText.getStr();
442 sal_Int32* pPos = pConvertPos.get();
443 sal_Int32* pPara = pConvertPara.get();
445 sal_Int32 nLastPos = 0, nLastPara = 0;
447 uno::Reference< container::XEnumerationAccess > xEnumAccess( xParent, uno::UNO_QUERY );
449 // first we fill the arrays with the position and paragraph for every character
450 // inside the text
451 if( xEnumAccess.is() )
453 uno::Reference< container::XEnumeration > xParaEnum( xEnumAccess->createEnumeration() );
455 while(xParaEnum->hasMoreElements())
457 int ndbg = 0;
458 uno::Reference< text::XTextContent > xParagraph( xParaEnum->nextElement(), uno::UNO_QUERY );
459 if( xParagraph.is() )
460 xEnumAccess.set(xParagraph, css::uno::UNO_QUERY);
461 else
462 xEnumAccess.clear();
464 if( xEnumAccess.is() )
466 uno::Reference< container::XEnumeration > xPortionEnum( xEnumAccess->createEnumeration() );
467 if( xPortionEnum.is() )
469 while(xPortionEnum->hasMoreElements())
471 uno::Reference< text::XTextRange > xPortion( xPortionEnum->nextElement(), uno::UNO_QUERY );
472 if( xPortion.is() )
474 const OUString aPortion( xPortion->getString() );
475 const sal_Int32 nLen = aPortion.getLength();
477 ESelection aStartSel( GetSelection( xPortion->getStart() ) );
478 ESelection aEndSel( GetSelection( xPortion->getEnd() ) );
480 // special case for empty portions with content or length one portions with content (fields)
481 if( (aStartSel.nStartPos == aEndSel.nStartPos) || ( (aStartSel.nStartPos == (aEndSel.nStartPos - 1)) && (nLen > 1) ) )
483 for( sal_Int32 i = 0; i < nLen; i++ )
485 if( ndbg < (nTextLen+2) )
487 *pPos++ = aStartSel.nStartPos;
488 *pPara++ = aStartSel.nStartPara;
490 ndbg += 1;
491 pText++;
493 else
495 OSL_FAIL( "array overflow while searching" );
499 nLastPos = aStartSel.nStartPos;
501 // normal case
502 else
504 for( sal_Int32 i = 0; i < nLen; i++ )
506 if( ndbg < (nTextLen+2) )
508 *pPos++ = aStartSel.nStartPos++;
509 *pPara++ = aStartSel.nStartPara;
511 ndbg += 1;
512 pText++;
514 else
516 OSL_FAIL( "array overflow while searching" );
520 nLastPos = aStartSel.nStartPos - 1;
521 DBG_ASSERT( aEndSel.nStartPos == aStartSel.nStartPos, "Search is not working" );
523 nLastPara = aStartSel.nStartPara;
529 if( ndbg < (nTextLen+2) )
531 *pPos++ = nLastPos + 1;
532 *pPara++ = nLastPara;
534 pText++;
536 else
538 OSL_FAIL( "array overflow while searching" );
543 uno::Reference< text::XTextRange > xFound;
544 ESelection aSel;
546 if( xText.is() )
547 aSel = GetSelection( xText );
549 sal_Int32 nStartPos;
550 sal_Int32 nEndPos = 0;
551 for( nStartPos = 0; nStartPos < nTextLen; nStartPos++ )
553 if( pConvertPara[nStartPos] == aSel.nStartPara && pConvertPos[nStartPos] == aSel.nStartPos )
554 break;
557 if( Search( aText, nStartPos, nEndPos, pDescr ) )
559 if( nStartPos <= nTextLen && nEndPos <= nTextLen )
561 ESelection aSelection( pConvertPara[nStartPos], pConvertPos[nStartPos],
562 pConvertPara[nEndPos], pConvertPos[nEndPos] );
563 SvxUnoTextRange *pRange;
565 SvxUnoTextBase* pParent = comphelper::getUnoTunnelImplementation<SvxUnoTextBase>( xParent );
567 if(pParent)
569 pRange = new SvxUnoTextRange( *pParent );
570 xFound = pRange;
571 pRange->SetSelection(aSelection);
575 else
577 OSL_FAIL("Array overflow while searching!");
581 return xFound;
584 bool SdUnoSearchReplaceShape::Search( const OUString& rText, sal_Int32& nStartPos, sal_Int32& nEndPos, SdUnoSearchReplaceDescriptor* pDescr ) throw()
586 OUString aSearchStr( pDescr->getSearchString() );
587 OUString aText( rText );
589 if( !pDescr->IsCaseSensitive() )
591 aText = aText.toAsciiLowerCase();
592 aSearchStr = aSearchStr.toAsciiLowerCase();
595 sal_Int32 nFound = aText.indexOf( aSearchStr, nStartPos );
596 if( nFound != -1 )
598 nStartPos = nFound;
599 nEndPos = nFound + aSearchStr.getLength();
601 if(pDescr->IsWords())
603 if( (nStartPos > 0 && aText[nStartPos-1] > ' ') ||
604 (nEndPos < aText.getLength() && aText[nEndPos] > ' ') )
606 nStartPos++;
607 return Search( aText, nStartPos, nEndPos, pDescr );
611 return true;
613 else
614 return false;
617 ESelection SdUnoSearchReplaceShape::GetSelection( const uno::Reference< text::XTextRange >& xTextRange ) throw()
619 ESelection aSel;
620 SvxUnoTextRangeBase* pRange = comphelper::getUnoTunnelImplementation<SvxUnoTextRangeBase>( xTextRange );
622 if(pRange)
623 aSel = pRange->GetSelection();
625 return aSel;
628 uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetShape( const uno::Reference< text::XTextRange >& xTextRange ) throw()
630 uno::Reference< drawing::XShape > xShape;
632 if(xTextRange.is())
634 uno::Reference< text::XText > xText( xTextRange->getText() );
636 if(xText.is())
640 xShape.set( xText, uno::UNO_QUERY );
641 if(!xShape.is())
643 uno::Reference< text::XText > xParent( xText->getText() );
644 if(!xParent.is() || xText.get() == xParent.get())
645 return xShape;
647 xText = xParent;
649 } while( !xShape.is() );
653 return xShape;
656 /* ================================================================= */
657 /** this class holds the parameters and status of a search or replace
658 operation performed by class SdUnoSearchReplaceShape
661 UNO3_GETIMPLEMENTATION_IMPL( SdUnoSearchReplaceDescriptor );
663 SdUnoSearchReplaceDescriptor::SdUnoSearchReplaceDescriptor()
665 mpPropSet.reset( new SvxItemPropertySet(ImplGetSearchPropertyMap(), SdrObject::GetGlobalDrawObjectItemPool()) );
667 mbBackwards = false;
668 mbCaseSensitive = false;
669 mbWords = false;
672 SdUnoSearchReplaceDescriptor::~SdUnoSearchReplaceDescriptor() throw()
676 // XSearchDescriptor
677 OUString SAL_CALL SdUnoSearchReplaceDescriptor::getSearchString()
679 return maSearchStr;
682 void SAL_CALL SdUnoSearchReplaceDescriptor::setSearchString( const OUString& aString )
684 maSearchStr = aString;
687 // XReplaceDescriptor
688 OUString SAL_CALL SdUnoSearchReplaceDescriptor::getReplaceString()
690 return maReplaceStr;
693 void SAL_CALL SdUnoSearchReplaceDescriptor::setReplaceString( const OUString& aReplaceString )
695 maReplaceStr = aReplaceString;
698 // XPropertySet
699 uno::Reference< css::beans::XPropertySetInfo > SAL_CALL SdUnoSearchReplaceDescriptor::getPropertySetInfo()
701 SolarMutexGuard aGuard;
702 return mpPropSet->getPropertySetInfo();
705 void SAL_CALL SdUnoSearchReplaceDescriptor::setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue )
707 SolarMutexGuard aGuard;
709 const SfxItemPropertySimpleEntry* pEntry = mpPropSet->getPropertyMapEntry(aPropertyName);
711 bool bOk = false;
713 switch( pEntry ? pEntry->nWID : -1 )
715 case WID_SEARCH_BACKWARDS:
716 bOk = (aValue >>= mbBackwards);
717 break;
718 case WID_SEARCH_CASE:
719 bOk = (aValue >>= mbCaseSensitive);
720 break;
721 case WID_SEARCH_WORDS:
722 bOk = (aValue >>= mbWords);
723 break;
724 default:
725 throw beans::UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this));
728 if( !bOk )
729 throw lang::IllegalArgumentException();
732 uno::Any SAL_CALL SdUnoSearchReplaceDescriptor::getPropertyValue( const OUString& PropertyName )
734 SolarMutexGuard aGuard;
736 uno::Any aAny;
738 const SfxItemPropertySimpleEntry* pEntry = mpPropSet->getPropertyMapEntry(PropertyName);
740 switch( pEntry ? pEntry->nWID : -1 )
742 case WID_SEARCH_BACKWARDS:
743 aAny <<= mbBackwards;
744 break;
745 case WID_SEARCH_CASE:
746 aAny <<= mbCaseSensitive;
747 break;
748 case WID_SEARCH_WORDS:
749 aAny <<= mbWords;
750 break;
751 default:
752 throw beans::UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this));
755 return aAny;
758 void SAL_CALL SdUnoSearchReplaceDescriptor::addPropertyChangeListener( const OUString& , const css::uno::Reference< css::beans::XPropertyChangeListener >& ) {}
759 void SAL_CALL SdUnoSearchReplaceDescriptor::removePropertyChangeListener( const OUString& , const css::uno::Reference< css::beans::XPropertyChangeListener >& ) {}
760 void SAL_CALL SdUnoSearchReplaceDescriptor::addVetoableChangeListener( const OUString& , const css::uno::Reference< css::beans::XVetoableChangeListener >& ) {}
761 void SAL_CALL SdUnoSearchReplaceDescriptor::removeVetoableChangeListener( const OUString& , const css::uno::Reference< css::beans::XVetoableChangeListener >& ) {}
763 /* ================================================================= */
765 SdUnoFindAllAccess::SdUnoFindAllAccess( uno::Sequence< uno::Reference< uno::XInterface > > const & rSequence ) throw()
766 :maSequence( rSequence )
770 SdUnoFindAllAccess::~SdUnoFindAllAccess() throw()
774 // XElementAccess
775 uno::Type SAL_CALL SdUnoFindAllAccess::getElementType()
777 return cppu::UnoType<text::XTextRange>::get();
780 sal_Bool SAL_CALL SdUnoFindAllAccess::hasElements()
782 return maSequence.hasElements();
785 // XIndexAccess
786 sal_Int32 SAL_CALL SdUnoFindAllAccess::getCount()
788 return maSequence.getLength();
791 uno::Any SAL_CALL SdUnoFindAllAccess::getByIndex( sal_Int32 Index )
793 if( Index < 0 || Index >= getCount() )
794 throw lang::IndexOutOfBoundsException();
796 uno::Any aAny;
797 aAny <<= maSequence[Index];
798 return aAny;
801 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */