1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
19 #include "vbafind.hxx"
20 #include "vbareplacement.hxx"
21 #include <ooo/vba/word/WdFindWrap.hpp>
22 #include <ooo/vba/word/WdReplace.hpp>
23 #include <com/sun/star/frame/XModel.hpp>
24 #include <com/sun/star/text/XTextRangeCompare.hpp>
27 #include "wordvbahelper.hxx"
28 #include <rtl/ref.hxx>
29 #include <sal/log.hxx>
31 using namespace ::ooo::vba
;
32 using namespace ::com::sun::star
;
34 SwVbaFind::SwVbaFind( const uno::Reference
< ooo::vba::XHelperInterface
>& rParent
, const uno::Reference
< uno::XComponentContext
>& rContext
, uno::Reference
< frame::XModel
> xModel
) :
35 SwVbaFind_BASE( rParent
, rContext
), mxModel( std::move(xModel
) ), mbReplace( false ), mnReplaceType( word::WdReplace::wdReplaceOne
), mnWrap( word::WdFindWrap::wdFindStop
)
37 mxReplaceable
.set( mxModel
, uno::UNO_QUERY_THROW
);
38 mxPropertyReplace
.set( mxReplaceable
->createReplaceDescriptor(), uno::UNO_QUERY_THROW
);
39 mxTVC
= word::getXTextViewCursor( mxModel
);
40 mxSelSupp
.set( mxModel
->getCurrentController(), uno::UNO_QUERY_THROW
);
43 SwVbaFind::~SwVbaFind()
47 uno::Reference
< word::XFind
> SwVbaFind::GetOrCreateFind(const uno::Reference
< ooo::vba::XHelperInterface
>& rParent
,
48 const uno::Reference
< uno::XComponentContext
>& rContext
,
49 const uno::Reference
< frame::XModel
>& xModel
,
50 const uno::Reference
< text::XTextRange
>& xTextRange
)
52 rtl::Reference
< SwVbaFind
> xFind
;
53 SwDoc
* pDoc
= word::getDocShell( xModel
)->GetDoc();
55 xFind
= dynamic_cast<SwVbaFind
*>( pDoc
->getVbaFind().get() );
58 xFind
= new SwVbaFind( rParent
, rContext
, xModel
);
60 pDoc
->setVbaFind( xFind
);
62 xFind
->mxTextRange
= xTextRange
;
68 bool SwVbaFind::InRange( const uno::Reference
< text::XTextRange
>& xCurrentRange
)
70 uno::Reference
< text::XTextRangeCompare
> xTRC( mxTextRange
->getText(), uno::UNO_QUERY_THROW
);
71 return xTRC
->compareRegionStarts( mxTextRange
, xCurrentRange
) >= 0 && xTRC
->compareRegionEnds( mxTextRange
, xCurrentRange
) <= 0;
74 bool SwVbaFind::InEqualRange( const uno::Reference
< text::XTextRange
>& xCurrentRange
)
76 uno::Reference
< text::XTextRangeCompare
> xTRC( mxTextRange
->getText(), uno::UNO_QUERY_THROW
);
77 return xTRC
->compareRegionStarts( mxTextRange
, xCurrentRange
) == 0 && xTRC
->compareRegionEnds( mxTextRange
, xCurrentRange
) == 0;
80 void SwVbaFind::SetReplaceWith( const OUString
& rText
)
82 mxPropertyReplace
->setReplaceString( rText
);
86 OUString
SwVbaFind::GetReplaceWith()
88 return mxPropertyReplace
->getReplaceString();
90 void SwVbaFind::SetReplace( sal_Int32 type
)
95 uno::Reference
< text::XTextRange
> SwVbaFind::FindOneElement()
97 uno::Reference
< text::XTextRange
> xFoundOne
;
98 if( !mxTVC
->getString().isEmpty() )
102 xFoundOne
.set( mxReplaceable
->findNext( mxTextRange
->getStart(), uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) ), uno::UNO_QUERY
);
106 xFoundOne
.set( mxReplaceable
->findNext( mxTextRange
->getEnd(), uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) ), uno::UNO_QUERY
);
109 if( xFoundOne
.is() && InEqualRange( xFoundOne
) )
111 xFoundOne
.set( mxReplaceable
->findNext( xFoundOne
, uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) ), uno::UNO_QUERY
);
113 else if( xFoundOne
.is() && !InRange( xFoundOne
) )
120 xFoundOne
.set( mxReplaceable
->findNext( mxTextRange
, uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) ), uno::UNO_QUERY
);
123 if( !xFoundOne
.is() && ( getWrap() == word::WdFindWrap::wdFindContinue
|| getWrap() == word::WdFindWrap::wdFindAsk
) )
127 mxTVC
->gotoStart(false);
128 xFoundOne
.set( mxReplaceable
->findNext( mxTextRange
->getStart(), uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) ), uno::UNO_QUERY
);
132 mxTVC
->gotoEnd( false );
133 xFoundOne
.set( mxReplaceable
->findNext( mxTextRange
->getEnd(), uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) ), uno::UNO_QUERY
);
140 bool SwVbaFind::SearchReplace()
144 // TODO: map wildcards in area to OOo wildcards
148 switch( mnReplaceType
)
150 case word::WdReplace::wdReplaceNone
:
155 case word::WdReplace::wdReplaceOne
:
157 uno::Reference
< text::XTextRange
> xFindOne
= FindOneElement();
160 xFindOne
->setString( GetReplaceWith() );
161 result
= mxSelSupp
->select( uno::Any( xFindOne
) );
165 case word::WdReplace::wdReplaceAll
:
167 uno::Reference
< container::XIndexAccess
> xIndexAccess
= mxReplaceable
->findAll( uno::Reference
< util::XSearchDescriptor
>( mxPropertyReplace
, uno::UNO_QUERY_THROW
) );
168 if( xIndexAccess
->getCount() > 0 )
170 for( sal_Int32 i
= 0; i
< xIndexAccess
->getCount(); i
++ )
172 uno::Reference
< text::XTextRange
> xTextRange( xIndexAccess
->getByIndex( i
), uno::UNO_QUERY_THROW
);
173 if( mnWrap
== word::WdFindWrap::wdFindContinue
|| mnWrap
== word::WdFindWrap::wdFindAsk
|| InRange( xTextRange
) )
175 xTextRange
->setString( GetReplaceWith() );
190 uno::Reference
< text::XTextRange
> xFindOne
= FindOneElement();
192 result
= mxSelSupp
->select( uno::Any( xFindOne
) );
198 OUString SAL_CALL
SwVbaFind::getText()
200 return mxPropertyReplace
->getSearchString();
203 void SAL_CALL
SwVbaFind::setText( const OUString
& _text
)
205 mxPropertyReplace
->setSearchString( _text
);
208 uno::Any SAL_CALL
SwVbaFind::getReplacement()
210 return uno::Any( uno::Reference
< word::XReplacement
>( new SwVbaReplacement( this, mxContext
, mxPropertyReplace
) ) );
213 void SAL_CALL
SwVbaFind::setReplacement( const uno::Any
& /*_replacement */ )
215 throw uno::RuntimeException("Not implemented" );
218 sal_Bool SAL_CALL
SwVbaFind::getForward()
220 bool bBackward
= false;
221 mxPropertyReplace
->getPropertyValue("SearchBackwards") >>= bBackward
;
225 void SAL_CALL
SwVbaFind::setForward( sal_Bool _forward
)
227 bool bBackward
= !_forward
;
228 mxPropertyReplace
->setPropertyValue("SearchBackwards", uno::Any( bBackward
) );
231 ::sal_Int32 SAL_CALL
SwVbaFind::getWrap()
233 // seems not supported in Writer
237 void SAL_CALL
SwVbaFind::setWrap( ::sal_Int32 _wrap
)
239 // seems not supported in Writer
243 sal_Bool SAL_CALL
SwVbaFind::getFormat()
245 return mxPropertyReplace
->getValueSearch();
248 void SAL_CALL
SwVbaFind::setFormat( sal_Bool _format
)
250 mxPropertyReplace
->setValueSearch( _format
);
253 sal_Bool SAL_CALL
SwVbaFind::getMatchCase()
256 mxPropertyReplace
->getPropertyValue("SearchCaseSensitive") >>= value
;
260 void SAL_CALL
SwVbaFind::setMatchCase( sal_Bool _matchcase
)
262 mxPropertyReplace
->setPropertyValue("SearchCaseSensitive", uno::Any( _matchcase
) );
265 sal_Bool SAL_CALL
SwVbaFind::getMatchWholeWord()
268 mxPropertyReplace
->getPropertyValue("SearchWords") >>= value
;
272 void SAL_CALL
SwVbaFind::setMatchWholeWord( sal_Bool _matchwholeword
)
274 mxPropertyReplace
->setPropertyValue("SearchWords", uno::Any( _matchwholeword
) );
277 sal_Bool SAL_CALL
SwVbaFind::getMatchWildcards()
280 mxPropertyReplace
->getPropertyValue("SearchRegularExpression") >>= value
;
284 void SAL_CALL
SwVbaFind::setMatchWildcards( sal_Bool _matchwildcards
)
286 mxPropertyReplace
->setPropertyValue("SearchRegularExpression", uno::Any( _matchwildcards
) );
289 sal_Bool SAL_CALL
SwVbaFind::getMatchSoundsLike()
292 mxPropertyReplace
->getPropertyValue("SearchSimilarity") >>= value
;
296 void SAL_CALL
SwVbaFind::setMatchSoundsLike( sal_Bool _matchsoundslike
)
298 // seems not accurate
299 mxPropertyReplace
->setPropertyValue("SearchSimilarity", uno::Any( _matchsoundslike
) );
302 sal_Bool SAL_CALL
SwVbaFind::getMatchAllWordForms()
305 mxPropertyReplace
->getPropertyValue("SearchSimilarity") >>= value
;
307 mxPropertyReplace
->getPropertyValue("SearchSimilarityRelax") >>= value
;
311 void SAL_CALL
SwVbaFind::setMatchAllWordForms( sal_Bool _matchallwordforms
)
313 // seems not accurate
314 mxPropertyReplace
->setPropertyValue("SearchSimilarity", uno::Any( _matchallwordforms
) );
315 mxPropertyReplace
->setPropertyValue("SearchSimilarityRelax", uno::Any( _matchallwordforms
) );
318 uno::Any SAL_CALL
SwVbaFind::getStyle()
320 throw uno::RuntimeException("Not implemented" );
323 void SAL_CALL
SwVbaFind::setStyle( const uno::Any
& /*_style */ )
325 throw uno::RuntimeException("Not implemented" );
329 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*/ )
332 if( FindText
.hasValue() )
340 if( MatchCase
.hasValue() )
342 MatchCase
>>= bValue
;
343 setMatchCase( bValue
);
346 if( MatchWholeWord
.hasValue() )
348 MatchWholeWord
>>= bValue
;
349 setMatchWholeWord( bValue
);
352 if( MatchWildcards
.hasValue() )
354 MatchWildcards
>>= bValue
;
355 setMatchWildcards( bValue
);
358 if( MatchSoundsLike
.hasValue() )
360 MatchSoundsLike
>>= bValue
;
361 setMatchSoundsLike( bValue
);
364 if( MatchAllWordForms
.hasValue() )
366 MatchAllWordForms
>>= bValue
;
367 setMatchAllWordForms( bValue
);
370 if( Forward
.hasValue() )
373 setForward( bValue
);
376 if( Wrap
.hasValue() )
378 sal_Int32 nWrapType
= 0;
380 setWrap( nWrapType
);
383 if( Format
.hasValue() )
389 if( ReplaceWith
.hasValue() )
392 ReplaceWith
>>= sValue
;
393 SetReplaceWith( sValue
);
396 if( Replace
.hasValue() )
400 SetReplace( nValue
);
403 result
= SearchReplace();
409 SwVbaFind::ClearFormatting( )
411 uno::Sequence
< beans::PropertyValue
> aSearchAttribs
;
412 mxPropertyReplace
->setSearchAttributes( aSearchAttribs
);
416 SwVbaFind::getServiceImplName()
421 uno::Sequence
< OUString
>
422 SwVbaFind::getServiceNames()
424 static uno::Sequence
< OUString
> const aServiceNames
428 return aServiceNames
;
431 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */