xref: /trunk/main/sw/source/ui/vba/vbafind.cxx (revision efeef26f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #include "vbafind.hxx"
24 #include <vbahelper/vbahelper.hxx>
25 #include <tools/diagnose_ex.h>
26 #include "vbareplacement.hxx"
27 #include <ooo/vba/word/WdFindWrap.hpp>
28 #include <ooo/vba/word/WdReplace.hpp>
29 #include <com/sun/star/text/XTextRangeCompare.hpp>
30 #include "wordvbahelper.hxx"
31 
32 using namespace ::ooo::vba;
33 using namespace ::com::sun::star;
34 
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)35 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 ) :
36     SwVbaFind_BASE( rParent, rContext ), mxModel( xModel ), mxTextRange( xTextRange ), mbReplace( sal_False ), mnReplaceType( word::WdReplace::wdReplaceOne ), mnWrap( word::WdFindWrap::wdFindStop )
37 {
38     mxReplaceable.set( mxModel, uno::UNO_QUERY_THROW );
39     mxPropertyReplace.set( mxReplaceable->createReplaceDescriptor(), uno::UNO_QUERY_THROW );
40     mxTVC = word::getXTextViewCursor( mxModel );
41     mxSelSupp.set( mxModel->getCurrentController(), uno::UNO_QUERY_THROW );
42 }
43 
~SwVbaFind()44 SwVbaFind::~SwVbaFind()
45 {
46 }
47 
InRange(const uno::Reference<text::XTextRange> & xCurrentRange)48 sal_Bool SwVbaFind::InRange( const uno::Reference< text::XTextRange >& xCurrentRange ) throw ( uno::RuntimeException )
49 {
50     uno::Reference< text::XTextRangeCompare > xTRC( mxTextRange->getText(), uno::UNO_QUERY_THROW );
51     if( xTRC->compareRegionStarts( mxTextRange, xCurrentRange ) >= 0 && xTRC->compareRegionEnds( mxTextRange, xCurrentRange ) <= 0 )
52         return sal_True;
53     return sal_False;
54 }
55 
InEqualRange(const uno::Reference<text::XTextRange> & xCurrentRange)56 sal_Bool SwVbaFind::InEqualRange( const uno::Reference< text::XTextRange >& xCurrentRange ) throw ( uno::RuntimeException )
57 {
58     uno::Reference< text::XTextRangeCompare > xTRC( mxTextRange->getText(), uno::UNO_QUERY_THROW );
59     if( xTRC->compareRegionStarts( mxTextRange, xCurrentRange ) == 0 && xTRC->compareRegionEnds( mxTextRange, xCurrentRange ) == 0 )
60         return sal_True;
61     return sal_False;
62 }
63 
SetReplaceWith(const rtl::OUString & rText)64 void SwVbaFind::SetReplaceWith( const rtl::OUString& rText ) throw (uno::RuntimeException)
65 {
66     mxPropertyReplace->setReplaceString( rText );
67     mbReplace = sal_True;
68 }
69 
GetReplaceWith()70 rtl::OUString SwVbaFind::GetReplaceWith() throw (uno::RuntimeException)
71 {
72     return mxPropertyReplace->getReplaceString();
73 }
SetReplace(sal_Int32 type)74 void SwVbaFind::SetReplace( sal_Int32 type )
75 {
76     mnReplaceType = type;
77     mbReplace = sal_True;
78 }
79 #ifdef TOMORROW
ReplaceWildcards(const rtl::OUString &)80 rtl::OUString SwVbaFind::ReplaceWildcards( const rtl::OUString& /*rText*/ ) throw ( uno::RuntimeException )
81 {
82     // TODO:
83     return rtl::OUString();
84 }
85 #endif
FindOneElement()86 uno::Reference< text::XTextRange > SwVbaFind::FindOneElement() throw ( uno::RuntimeException )
87 {
88     uno::Reference< text::XTextRange > xFoundOne;
89     if( mxTVC->getString().getLength() > 0 )
90     {
91         if( getForward() )
92         {
93             xFoundOne.set( mxReplaceable->findNext( mxTextRange->getStart(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
94         }
95         else
96         {
97             xFoundOne.set( mxReplaceable->findNext( mxTextRange->getEnd(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
98         }
99 
100         if( xFoundOne.is() && InEqualRange( xFoundOne ) )
101         {
102             xFoundOne.set( mxReplaceable->findNext( xFoundOne, uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
103         }
104         else if( xFoundOne.is() && !InRange( xFoundOne ) )
105         {
106             xFoundOne = uno::Reference< text::XTextRange >();
107         }
108     }
109     else
110     {
111         xFoundOne.set( mxReplaceable->findNext( mxTextRange, uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
112     }
113 
114     if( !xFoundOne.is() && ( getWrap() == word::WdFindWrap::wdFindContinue || getWrap() == word::WdFindWrap::wdFindAsk ) )
115     {
116         if( getForward() )
117         {
118             mxTVC->gotoStart(sal_False);
119             xFoundOne.set( mxReplaceable->findNext( mxTextRange->getStart(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
120         }
121         else
122         {
123             mxTVC->gotoEnd( sal_False );
124             xFoundOne.set( mxReplaceable->findNext( mxTextRange->getEnd(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
125 
126         }
127     }
128     return xFoundOne;
129 }
130 
SearchReplace()131 sal_Bool SwVbaFind::SearchReplace() throw (uno::RuntimeException)
132 {
133     sal_Bool result = sal_False;
134 
135     // TODO: map wildcards in area to OOo wildcards
136 
137     if( mbReplace )
138     {
139         switch( mnReplaceType )
140         {
141             case word::WdReplace::wdReplaceNone:
142             {
143                 result = sal_True;
144                 break;
145             }
146             case word::WdReplace::wdReplaceOne:
147             {
148                 uno::Reference< text::XTextRange > xFindOne = FindOneElement();
149                 if( xFindOne.is() )
150                 {
151                     xFindOne->setString( GetReplaceWith() );
152                     result = mxSelSupp->select( uno::makeAny( xFindOne ) );
153                 }
154                 break;
155             }
156             case word::WdReplace::wdReplaceAll:
157             {
158                 uno::Reference< container::XIndexAccess > xIndexAccess = mxReplaceable->findAll( uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) );
159                 if( xIndexAccess->getCount() > 0 )
160                 {
161                     for( sal_Int32 i = 0; i < xIndexAccess->getCount(); i++ )
162                     {
163                         uno::Reference< text::XTextRange > xTextRange( xIndexAccess->getByIndex( i ), uno::UNO_QUERY_THROW );
164                         if( mnWrap == word::WdFindWrap::wdFindContinue || mnWrap == word::WdFindWrap::wdFindAsk || InRange( xTextRange ) )
165                         {
166                             xTextRange->setString( GetReplaceWith() );
167                             result = sal_True;
168                         }
169                     }
170                 }
171                 break;
172             }
173             default:
174             {
175                 result = sal_False;
176             }
177         }
178     }
179     else
180     {
181         uno::Reference< text::XTextRange > xFindOne = FindOneElement();
182         if( xFindOne.is() )
183             result = mxSelSupp->select( uno::makeAny( xFindOne ) );
184     }
185 
186     return result;
187 }
188 
getText()189 ::rtl::OUString SAL_CALL SwVbaFind::getText() throw (uno::RuntimeException)
190 {
191     return mxPropertyReplace->getSearchString();
192 }
193 
setText(const::rtl::OUString & _text)194 void SAL_CALL SwVbaFind::setText( const ::rtl::OUString& _text ) throw (uno::RuntimeException)
195 {
196     mxPropertyReplace->setSearchString( _text );
197 }
198 
getReplacement()199 uno::Any SAL_CALL SwVbaFind::getReplacement() throw (uno::RuntimeException)
200 {
201     return uno::makeAny( uno::Reference< word::XReplacement >( new SwVbaReplacement( this, mxContext, mxPropertyReplace ) ) );
202 }
203 
setReplacement(const uno::Any &)204 void SAL_CALL SwVbaFind::setReplacement( const uno::Any& /*_replacement */ ) throw (uno::RuntimeException)
205 {
206     throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() );
207 }
208 
getForward()209 ::sal_Bool SAL_CALL SwVbaFind::getForward() throw (uno::RuntimeException)
210 {
211     sal_Bool bBackward = sal_False;
212     mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchBackwards") ) ) >>= bBackward;
213     return !bBackward;
214 }
215 
setForward(::sal_Bool _forward)216 void SAL_CALL SwVbaFind::setForward( ::sal_Bool _forward ) throw (uno::RuntimeException)
217 {
218     sal_Bool bBackward = !_forward;
219     mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchBackwards") ), uno::makeAny( bBackward ) );
220 }
221 
getWrap()222 ::sal_Int32 SAL_CALL SwVbaFind::getWrap() throw (uno::RuntimeException)
223 {
224     // seems not supported in Writer
225     return mnWrap;
226 }
227 
setWrap(::sal_Int32 _wrap)228 void SAL_CALL SwVbaFind::setWrap( ::sal_Int32 _wrap ) throw (uno::RuntimeException)
229 {
230     // seems not supported in Writer
231     mnWrap = _wrap;
232 }
233 
getFormat()234 ::sal_Bool SAL_CALL SwVbaFind::getFormat() throw (uno::RuntimeException)
235 {
236     return mxPropertyReplace->getValueSearch();
237 }
238 
setFormat(::sal_Bool _format)239 void SAL_CALL SwVbaFind::setFormat( ::sal_Bool _format ) throw (uno::RuntimeException)
240 {
241     mxPropertyReplace->setValueSearch( _format );
242 }
243 
getMatchCase()244 ::sal_Bool SAL_CALL SwVbaFind::getMatchCase() throw (uno::RuntimeException)
245 {
246     sal_Bool value = sal_False;
247     mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchCaseSensitive") ) ) >>= value;
248     return value;
249 }
250 
setMatchCase(::sal_Bool _matchcase)251 void SAL_CALL SwVbaFind::setMatchCase( ::sal_Bool _matchcase ) throw (uno::RuntimeException)
252 {
253     mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchCaseSensitive") ), uno::makeAny( _matchcase ) );
254 }
255 
getMatchWholeWord()256 ::sal_Bool SAL_CALL SwVbaFind::getMatchWholeWord() throw (uno::RuntimeException)
257 {
258     sal_Bool value = sal_False;
259     mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchWords") ) ) >>= value;
260     return value;
261 }
262 
setMatchWholeWord(::sal_Bool _matchwholeword)263 void SAL_CALL SwVbaFind::setMatchWholeWord( ::sal_Bool _matchwholeword ) throw (uno::RuntimeException)
264 {
265     mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchWords") ), uno::makeAny( _matchwholeword ) );
266 }
267 
getMatchWildcards()268 ::sal_Bool SAL_CALL SwVbaFind::getMatchWildcards() throw (uno::RuntimeException)
269 {
270     sal_Bool value = sal_False;
271     mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchRegularExpression") ) ) >>= value;
272     return value;
273 }
274 
setMatchWildcards(::sal_Bool _matchwildcards)275 void SAL_CALL SwVbaFind::setMatchWildcards( ::sal_Bool _matchwildcards ) throw (uno::RuntimeException)
276 {
277     mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchRegularExpression") ), uno::makeAny( _matchwildcards ) );
278 }
279 
getMatchSoundsLike()280 ::sal_Bool SAL_CALL SwVbaFind::getMatchSoundsLike() throw (uno::RuntimeException)
281 {
282     sal_Bool value = sal_False;
283     mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarity") ) ) >>= value;
284     return value;
285 }
286 
setMatchSoundsLike(::sal_Bool _matchsoundslike)287 void SAL_CALL SwVbaFind::setMatchSoundsLike( ::sal_Bool _matchsoundslike ) throw (uno::RuntimeException)
288 {
289     // seems not accurate
290     mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarity") ), uno::makeAny( _matchsoundslike ) );
291 }
292 
getMatchAllWordForms()293 ::sal_Bool SAL_CALL SwVbaFind::getMatchAllWordForms() throw (uno::RuntimeException)
294 {
295     sal_Bool value = sal_False;
296     mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarity") ) ) >>= value;
297     if( value )
298         mxPropertyReplace->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarityRelax") ) ) >>= value;
299     return value;
300 }
301 
setMatchAllWordForms(::sal_Bool _matchallwordforms)302 void SAL_CALL SwVbaFind::setMatchAllWordForms( ::sal_Bool _matchallwordforms ) throw (uno::RuntimeException)
303 {
304     // seems not accurate
305     mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarity") ), uno::makeAny( _matchallwordforms ) );
306     mxPropertyReplace->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SearchSimilarityRelax") ), uno::makeAny( _matchallwordforms ) );
307 }
308 
getStyle()309 uno::Any SAL_CALL SwVbaFind::getStyle() throw (uno::RuntimeException)
310 {
311     throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() );
312 }
313 
setStyle(const uno::Any &)314 void SAL_CALL SwVbaFind::setStyle( const uno::Any& /*_style */ ) throw (uno::RuntimeException)
315 {
316     throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() );
317 }
318 
319 sal_Bool SAL_CALL
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 &,const uno::Any &,const uno::Any &,const uno::Any &,const uno::Any &,const uno::Any &,const uno::Any &,const uno::Any &,const uno::Any &)320 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)
321 {
322     sal_Bool result = sal_False;
323     if( FindText.hasValue() )
324     {
325         rtl::OUString sText;
326         FindText >>= sText;
327         setText( sText );
328     }
329 
330     sal_Bool bValue = sal_False;
331     if( MatchCase.hasValue() )
332     {
333         MatchCase >>= bValue;
334         setMatchCase( bValue );
335     }
336 
337     if( MatchWholeWord.hasValue() )
338     {
339         MatchWholeWord >>= bValue;
340         setMatchWholeWord( bValue );
341     }
342 
343     if( MatchWildcards.hasValue() )
344     {
345         MatchWildcards >>= bValue;
346         setMatchWildcards( bValue );
347     }
348 
349     if( MatchSoundsLike.hasValue() )
350     {
351         MatchSoundsLike >>= bValue;
352         setMatchSoundsLike( bValue );
353     }
354 
355     if( MatchAllWordForms.hasValue() )
356     {
357         MatchAllWordForms >>= bValue;
358         setMatchAllWordForms( bValue );
359     }
360 
361     if( Forward.hasValue() )
362     {
363         Forward >>= bValue;
364         setForward( bValue );
365     }
366 
367     if( Wrap.hasValue() )
368     {
369         sal_Int32 nWrapType = 0;
370         Wrap >>= nWrapType;
371         setWrap( nWrapType );
372     }
373 
374     if( Format.hasValue() )
375     {
376         Format >>= bValue;
377         setFormat( bValue );
378     }
379 
380     if( ReplaceWith.hasValue() )
381     {
382         rtl::OUString sValue;
383         ReplaceWith >>= sValue;
384         SetReplaceWith( sValue );
385     }
386 
387     if( Replace.hasValue() )
388     {
389         sal_Int32 nValue(0);
390         Replace >>= nValue;
391         SetReplace( nValue );
392     }
393 
394     result = SearchReplace();
395 
396     return result;
397 }
398 
399 void SAL_CALL
ClearFormatting()400 SwVbaFind::ClearFormatting(  ) throw (uno::RuntimeException)
401 {
402     uno::Sequence< beans::PropertyValue >  aSearchAttribs;
403     mxPropertyReplace->setSearchAttributes( aSearchAttribs );
404 }
405 
406 rtl::OUString&
getServiceImplName()407 SwVbaFind::getServiceImplName()
408 {
409 	static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaFind") );
410 	return sImplName;
411 }
412 
413 uno::Sequence< rtl::OUString >
getServiceNames()414 SwVbaFind::getServiceNames()
415 {
416 	static uno::Sequence< rtl::OUString > aServiceNames;
417 	if ( aServiceNames.getLength() == 0 )
418 	{
419 		aServiceNames.realloc( 1 );
420 		aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.word.Find" ) );
421 	}
422 	return aServiceNames;
423 }
424 
425