1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include "vbafind.hxx"
31 #include <vbahelper/vbahelper.hxx>
32 #include <tools/diagnose_ex.h>
33 #include "vbareplacement.hxx"
34 #include <ooo/vba/word/WdFindWrap.hpp>
35 #include <ooo/vba/word/WdReplace.hpp>
36 #include <com/sun/star/text/XTextRangeCompare.hpp>
37 #include "wordvbahelper.hxx"
39 using namespace ::ooo::vba
;
40 using namespace ::com::sun::star
;
42 SwVbaFind::SwVbaFind( const uno::Reference
< ooo::vba::XHelperInterface
>& rParent
, const uno::Reference
< uno::XComponentContext
>& rContext
, const uno::Reference
< frame::XModel
>& xModel
, const uno::Reference
< text::XTextRange
>& xTextRange
) throw ( uno::RuntimeException
) :
43 SwVbaFind_BASE( rParent
, rContext
), mxModel( xModel
), mxTextRange( xTextRange
), mbReplace( sal_False
), mnReplaceType( word::WdReplace::wdReplaceOne
), mnWrap( word::WdFindWrap::wdFindStop
)
45 mxReplaceable
.set( mxModel
, uno::UNO_QUERY_THROW
);
46 mxPropertyReplace
.set( mxReplaceable
->createReplaceDescriptor(), uno::UNO_QUERY_THROW
);
47 mxTVC
= word::getXTextViewCursor( mxModel
);
48 mxSelSupp
.set( mxModel
->getCurrentController(), uno::UNO_QUERY_THROW
);
51 SwVbaFind::~SwVbaFind()
55 sal_Bool
SwVbaFind::InRange( const uno::Reference
< text::XTextRange
>& xCurrentRange
) throw ( uno::RuntimeException
)
57 uno::Reference
< text::XTextRangeCompare
> xTRC( mxTextRange
->getText(), uno::UNO_QUERY_THROW
);
58 if( xTRC
->compareRegionStarts( mxTextRange
, xCurrentRange
) >= 0 && xTRC
->compareRegionEnds( mxTextRange
, xCurrentRange
) <= 0 )
63 sal_Bool
SwVbaFind::InEqualRange( const uno::Reference
< text::XTextRange
>& xCurrentRange
) throw ( uno::RuntimeException
)
65 uno::Reference
< text::XTextRangeCompare
> xTRC( mxTextRange
->getText(), uno::UNO_QUERY_THROW
);
66 if( xTRC
->compareRegionStarts( mxTextRange
, xCurrentRange
) == 0 && xTRC
->compareRegionEnds( mxTextRange
, xCurrentRange
) == 0 )
71 void SwVbaFind::SetReplaceWith( const rtl::OUString
& rText
) throw (uno::RuntimeException
)
73 mxPropertyReplace
->setReplaceString( rText
);
77 rtl::OUString
SwVbaFind::GetReplaceWith() throw (uno::RuntimeException
)
79 return mxPropertyReplace
->getReplaceString();
81 void SwVbaFind::SetReplace( sal_Int32 type
)
87 rtl::OUString
SwVbaFind::ReplaceWildcards( const rtl::OUString
& /*rText*/ ) throw ( uno::RuntimeException
)
90 return rtl::OUString();
93 uno::Reference
< text::XTextRange
> SwVbaFind::FindOneElement() throw ( uno::RuntimeException
)
95 uno::Reference
< text::XTextRange
> xFoundOne
;
96 if( mxTVC
->getString().getLength() > 0 )
100 xFoundOne
.set( mxReplaceable
->findNext( mxTextRange
->getStart(), uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) ), uno::UNO_QUERY
);
104 xFoundOne
.set( mxReplaceable
->findNext( mxTextRange
->getEnd(), uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) ), uno::UNO_QUERY
);
107 if( xFoundOne
.is() && InEqualRange( xFoundOne
) )
109 xFoundOne
.set( mxReplaceable
->findNext( xFoundOne
, uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) ), uno::UNO_QUERY
);
111 else if( xFoundOne
.is() && !InRange( xFoundOne
) )
113 xFoundOne
= uno::Reference
< text::XTextRange
>();
118 xFoundOne
.set( mxReplaceable
->findNext( mxTextRange
, uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) ), uno::UNO_QUERY
);
121 if( !xFoundOne
.is() && ( getWrap() == word::WdFindWrap::wdFindContinue
|| getWrap() == word::WdFindWrap::wdFindAsk
) )
125 mxTVC
->gotoStart(sal_False
);
126 xFoundOne
.set( mxReplaceable
->findNext( mxTextRange
->getStart(), uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) ), uno::UNO_QUERY
);
130 mxTVC
->gotoEnd( sal_False
);
131 xFoundOne
.set( mxReplaceable
->findNext( mxTextRange
->getEnd(), uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) ), uno::UNO_QUERY
);
138 sal_Bool
SwVbaFind::SearchReplace() throw (uno::RuntimeException
)
140 sal_Bool result
= sal_False
;
142 // TODO: map wildcards in area to OOo wildcards
146 switch( mnReplaceType
)
148 case word::WdReplace::wdReplaceNone
:
153 case word::WdReplace::wdReplaceOne
:
155 uno::Reference
< text::XTextRange
> xFindOne
= FindOneElement();
158 xFindOne
->setString( GetReplaceWith() );
159 result
= mxSelSupp
->select( uno::makeAny( xFindOne
) );
163 case word::WdReplace::wdReplaceAll
:
165 uno::Reference
< container::XIndexAccess
> xIndexAccess
= mxReplaceable
->findAll( uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) );
166 if( xIndexAccess
->getCount() > 0 )
168 for( sal_Int32 i
= 0; i
< xIndexAccess
->getCount(); i
++ )
170 uno::Reference
< text::XTextRange
> xTextRange( xIndexAccess
->getByIndex( i
), uno::UNO_QUERY_THROW
);
171 if( mnWrap
== word::WdFindWrap::wdFindContinue
|| mnWrap
== word::WdFindWrap::wdFindAsk
|| InRange( xTextRange
) )
173 xTextRange
->setString( GetReplaceWith() );
188 uno::Reference
< text::XTextRange
> xFindOne
= FindOneElement();
190 result
= mxSelSupp
->select( uno::makeAny( xFindOne
) );
196 ::rtl::OUString SAL_CALL
SwVbaFind::getText() throw (uno::RuntimeException
)
198 return mxPropertyReplace
->getSearchString();
201 void SAL_CALL
SwVbaFind::setText( const ::rtl::OUString
& _text
) throw (uno::RuntimeException
)
203 mxPropertyReplace
->setSearchString( _text
);
206 uno::Any SAL_CALL
SwVbaFind::getReplacement() throw (uno::RuntimeException
)
208 return uno::makeAny( uno::Reference
< word::XReplacement
>( new SwVbaReplacement( this, mxContext
, mxPropertyReplace
) ) );
211 void SAL_CALL
SwVbaFind::setReplacement( const uno::Any
& /*_replacement */ ) throw (uno::RuntimeException
)
213 throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference
< uno::XInterface
>() );
216 ::sal_Bool SAL_CALL
SwVbaFind::getForward() throw (uno::RuntimeException
)
218 sal_Bool bBackward
= sal_False
;
219 mxPropertyReplace
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchBackwards") ) ) >>= bBackward
;
223 void SAL_CALL
SwVbaFind::setForward( ::sal_Bool _forward
) throw (uno::RuntimeException
)
225 sal_Bool bBackward
= !_forward
;
226 mxPropertyReplace
->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchBackwards") ), uno::makeAny( bBackward
) );
229 ::sal_Int32 SAL_CALL
SwVbaFind::getWrap() throw (uno::RuntimeException
)
231 // seems not supported in Writer
235 void SAL_CALL
SwVbaFind::setWrap( ::sal_Int32 _wrap
) throw (uno::RuntimeException
)
237 // seems not supported in Writer
241 ::sal_Bool SAL_CALL
SwVbaFind::getFormat() throw (uno::RuntimeException
)
243 return mxPropertyReplace
->getValueSearch();
246 void SAL_CALL
SwVbaFind::setFormat( ::sal_Bool _format
) throw (uno::RuntimeException
)
248 mxPropertyReplace
->setValueSearch( _format
);
251 ::sal_Bool SAL_CALL
SwVbaFind::getMatchCase() throw (uno::RuntimeException
)
253 sal_Bool value
= sal_False
;
254 mxPropertyReplace
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchCaseSensitive") ) ) >>= value
;
258 void SAL_CALL
SwVbaFind::setMatchCase( ::sal_Bool _matchcase
) throw (uno::RuntimeException
)
260 mxPropertyReplace
->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchCaseSensitive") ), uno::makeAny( _matchcase
) );
263 ::sal_Bool SAL_CALL
SwVbaFind::getMatchWholeWord() throw (uno::RuntimeException
)
265 sal_Bool value
= sal_False
;
266 mxPropertyReplace
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchWords") ) ) >>= value
;
270 void SAL_CALL
SwVbaFind::setMatchWholeWord( ::sal_Bool _matchwholeword
) throw (uno::RuntimeException
)
272 mxPropertyReplace
->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchWords") ), uno::makeAny( _matchwholeword
) );
275 ::sal_Bool SAL_CALL
SwVbaFind::getMatchWildcards() throw (uno::RuntimeException
)
277 sal_Bool value
= sal_False
;
278 mxPropertyReplace
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchRegularExpression") ) ) >>= value
;
282 void SAL_CALL
SwVbaFind::setMatchWildcards( ::sal_Bool _matchwildcards
) throw (uno::RuntimeException
)
284 mxPropertyReplace
->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchRegularExpression") ), uno::makeAny( _matchwildcards
) );
287 ::sal_Bool SAL_CALL
SwVbaFind::getMatchSoundsLike() throw (uno::RuntimeException
)
289 sal_Bool value
= sal_False
;
290 mxPropertyReplace
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarity") ) ) >>= value
;
294 void SAL_CALL
SwVbaFind::setMatchSoundsLike( ::sal_Bool _matchsoundslike
) throw (uno::RuntimeException
)
296 // seems not accurate
297 mxPropertyReplace
->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarity") ), uno::makeAny( _matchsoundslike
) );
300 ::sal_Bool SAL_CALL
SwVbaFind::getMatchAllWordForms() throw (uno::RuntimeException
)
302 sal_Bool value
= sal_False
;
303 mxPropertyReplace
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarity") ) ) >>= value
;
305 mxPropertyReplace
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarityRelax") ) ) >>= value
;
309 void SAL_CALL
SwVbaFind::setMatchAllWordForms( ::sal_Bool _matchallwordforms
) throw (uno::RuntimeException
)
311 // seems not accurate
312 mxPropertyReplace
->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarity") ), uno::makeAny( _matchallwordforms
) );
313 mxPropertyReplace
->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarityRelax") ), uno::makeAny( _matchallwordforms
) );
316 uno::Any SAL_CALL
SwVbaFind::getStyle() throw (uno::RuntimeException
)
318 throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference
< uno::XInterface
>() );
321 void SAL_CALL
SwVbaFind::setStyle( const uno::Any
& /*_style */ ) throw (uno::RuntimeException
)
323 throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference
< uno::XInterface
>() );
327 SwVbaFind::Execute( const uno::Any
& FindText
, const uno::Any
& MatchCase
, const uno::Any
& MatchWholeWord
, const uno::Any
& MatchWildcards
, const uno::Any
& MatchSoundsLike
, const uno::Any
& MatchAllWordForms
, const uno::Any
& Forward
, const uno::Any
& Wrap
, const uno::Any
& Format
, const uno::Any
& ReplaceWith
, const uno::Any
& Replace
, const uno::Any
& /*MatchKashida*/, const uno::Any
& /*MatchDiacritics*/, const uno::Any
& /*MatchAlefHamza*/, const uno::Any
& /*MatchControl*/, const uno::Any
& /*MatchPrefix*/, const uno::Any
& /*MatchSuffix*/, const uno::Any
& /*MatchPhrase*/, const uno::Any
& /*IgnoreSpace*/, const uno::Any
& /*IgnorePunct*/ ) throw (uno::RuntimeException
)
329 sal_Bool result
= sal_False
;
330 if( FindText
.hasValue() )
337 sal_Bool bValue
= sal_False
;
338 if( MatchCase
.hasValue() )
340 MatchCase
>>= bValue
;
341 setMatchCase( bValue
);
344 if( MatchWholeWord
.hasValue() )
346 MatchWholeWord
>>= bValue
;
347 setMatchWholeWord( bValue
);
350 if( MatchWildcards
.hasValue() )
352 MatchWildcards
>>= bValue
;
353 setMatchWildcards( bValue
);
356 if( MatchSoundsLike
.hasValue() )
358 MatchSoundsLike
>>= bValue
;
359 setMatchSoundsLike( bValue
);
362 if( MatchAllWordForms
.hasValue() )
364 MatchAllWordForms
>>= bValue
;
365 setMatchAllWordForms( bValue
);
368 if( Forward
.hasValue() )
371 setForward( bValue
);
374 if( Wrap
.hasValue() )
376 sal_Int32 nWrapType
= 0;
378 setWrap( nWrapType
);
381 if( Format
.hasValue() )
387 if( ReplaceWith
.hasValue() )
389 rtl::OUString sValue
;
390 ReplaceWith
>>= sValue
;
391 SetReplaceWith( sValue
);
394 if( Replace
.hasValue() )
398 SetReplace( nValue
);
401 result
= SearchReplace();
407 SwVbaFind::ClearFormatting( ) throw (uno::RuntimeException
)
409 uno::Sequence
< beans::PropertyValue
> aSearchAttribs
;
410 mxPropertyReplace
->setSearchAttributes( aSearchAttribs
);
414 SwVbaFind::getServiceImplName()
416 static rtl::OUString
sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaFind") );
420 uno::Sequence
< rtl::OUString
>
421 SwVbaFind::getServiceNames()
423 static uno::Sequence
< rtl::OUString
> aServiceNames
;
424 if ( aServiceNames
.getLength() == 0 )
426 aServiceNames
.realloc( 1 );
427 aServiceNames
[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.word.Find" ) );
429 return aServiceNames
;