LibreOffice Module sw (master)  1
vbafind.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
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>
25 #include "wordvbahelper.hxx"
26 
27 using namespace ::ooo::vba;
28 using namespace ::com::sun::star;
29 
30 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 ) :
31  SwVbaFind_BASE( rParent, rContext ), mxModel( xModel ), mxTextRange( xTextRange ), mbReplace( false ), mnReplaceType( word::WdReplace::wdReplaceOne ), mnWrap( word::WdFindWrap::wdFindStop )
32 {
33  mxReplaceable.set( mxModel, uno::UNO_QUERY_THROW );
34  mxPropertyReplace.set( mxReplaceable->createReplaceDescriptor(), uno::UNO_QUERY_THROW );
36  mxSelSupp.set( mxModel->getCurrentController(), uno::UNO_QUERY_THROW );
37 }
38 
40 {
41 }
42 
43 bool SwVbaFind::InRange( const uno::Reference< text::XTextRange >& xCurrentRange )
44 {
45  uno::Reference< text::XTextRangeCompare > xTRC( mxTextRange->getText(), uno::UNO_QUERY_THROW );
46  return xTRC->compareRegionStarts( mxTextRange, xCurrentRange ) >= 0 && xTRC->compareRegionEnds( mxTextRange, xCurrentRange ) <= 0;
47 }
48 
49 bool SwVbaFind::InEqualRange( const uno::Reference< text::XTextRange >& xCurrentRange )
50 {
51  uno::Reference< text::XTextRangeCompare > xTRC( mxTextRange->getText(), uno::UNO_QUERY_THROW );
52  return xTRC->compareRegionStarts( mxTextRange, xCurrentRange ) == 0 && xTRC->compareRegionEnds( mxTextRange, xCurrentRange ) == 0;
53 }
54 
55 void SwVbaFind::SetReplaceWith( const OUString& rText )
56 {
57  mxPropertyReplace->setReplaceString( rText );
58  mbReplace = true;
59 }
60 
62 {
63  return mxPropertyReplace->getReplaceString();
64 }
65 void SwVbaFind::SetReplace( sal_Int32 type )
66 {
67  mnReplaceType = type;
68  mbReplace = true;
69 }
70 uno::Reference< text::XTextRange > SwVbaFind::FindOneElement()
71 {
72  uno::Reference< text::XTextRange > xFoundOne;
73  if( !mxTVC->getString().isEmpty() )
74  {
75  if( getForward() )
76  {
77  xFoundOne.set( mxReplaceable->findNext( mxTextRange->getStart(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
78  }
79  else
80  {
81  xFoundOne.set( mxReplaceable->findNext( mxTextRange->getEnd(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
82  }
83 
84  if( xFoundOne.is() && InEqualRange( xFoundOne ) )
85  {
86  xFoundOne.set( mxReplaceable->findNext( xFoundOne, uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
87  }
88  else if( xFoundOne.is() && !InRange( xFoundOne ) )
89  {
90  xFoundOne.clear();
91  }
92  }
93  else
94  {
95  xFoundOne.set( mxReplaceable->findNext( mxTextRange, uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
96  }
97 
98  if( !xFoundOne.is() && ( getWrap() == word::WdFindWrap::wdFindContinue || getWrap() == word::WdFindWrap::wdFindAsk ) )
99  {
100  if( getForward() )
101  {
102  mxTVC->gotoStart(false);
103  xFoundOne.set( mxReplaceable->findNext( mxTextRange->getStart(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
104  }
105  else
106  {
107  mxTVC->gotoEnd( false );
108  xFoundOne.set( mxReplaceable->findNext( mxTextRange->getEnd(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
109 
110  }
111  }
112  return xFoundOne;
113 }
114 
116 {
117  bool result = false;
118 
119  // TODO: map wildcards in area to OOo wildcards
120 
121  if( mbReplace )
122  {
123  switch( mnReplaceType )
124  {
125  case word::WdReplace::wdReplaceNone:
126  {
127  result = true;
128  break;
129  }
130  case word::WdReplace::wdReplaceOne:
131  {
132  uno::Reference< text::XTextRange > xFindOne = FindOneElement();
133  if( xFindOne.is() )
134  {
135  xFindOne->setString( GetReplaceWith() );
136  result = mxSelSupp->select( uno::makeAny( xFindOne ) );
137  }
138  break;
139  }
140  case word::WdReplace::wdReplaceAll:
141  {
142  uno::Reference< container::XIndexAccess > xIndexAccess = mxReplaceable->findAll( uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) );
143  if( xIndexAccess->getCount() > 0 )
144  {
145  for( sal_Int32 i = 0; i < xIndexAccess->getCount(); i++ )
146  {
147  uno::Reference< text::XTextRange > xTextRange( xIndexAccess->getByIndex( i ), uno::UNO_QUERY_THROW );
148  if( mnWrap == word::WdFindWrap::wdFindContinue || mnWrap == word::WdFindWrap::wdFindAsk || InRange( xTextRange ) )
149  {
150  xTextRange->setString( GetReplaceWith() );
151  result = true;
152  }
153  }
154  }
155  break;
156  }
157  default:
158  {
159  result = false;
160  }
161  }
162  }
163  else
164  {
165  uno::Reference< text::XTextRange > xFindOne = FindOneElement();
166  if( xFindOne.is() )
167  result = mxSelSupp->select( uno::makeAny( xFindOne ) );
168  }
169 
170  return result;
171 }
172 
173 OUString SAL_CALL SwVbaFind::getText()
174 {
175  return mxPropertyReplace->getSearchString();
176 }
177 
178 void SAL_CALL SwVbaFind::setText( const OUString& _text )
179 {
180  mxPropertyReplace->setSearchString( _text );
181 }
182 
184 {
185  return uno::makeAny( uno::Reference< word::XReplacement >( new SwVbaReplacement( this, mxContext, mxPropertyReplace ) ) );
186 }
187 
188 void SAL_CALL SwVbaFind::setReplacement( const uno::Any& /*_replacement */ )
189 {
190  throw uno::RuntimeException("Not implemented" );
191 }
192 
194 {
195  bool bBackward = false;
196  mxPropertyReplace->getPropertyValue("SearchBackwards") >>= bBackward;
197  return !bBackward;
198 }
199 
200 void SAL_CALL SwVbaFind::setForward( sal_Bool _forward )
201 {
202  bool bBackward = !_forward;
203  mxPropertyReplace->setPropertyValue("SearchBackwards", uno::makeAny( bBackward ) );
204 }
205 
206 ::sal_Int32 SAL_CALL SwVbaFind::getWrap()
207 {
208  // seems not supported in Writer
209  return mnWrap;
210 }
211 
212 void SAL_CALL SwVbaFind::setWrap( ::sal_Int32 _wrap )
213 {
214  // seems not supported in Writer
215  mnWrap = _wrap;
216 }
217 
219 {
220  return mxPropertyReplace->getValueSearch();
221 }
222 
223 void SAL_CALL SwVbaFind::setFormat( sal_Bool _format )
224 {
225  mxPropertyReplace->setValueSearch( _format );
226 }
227 
229 {
230  bool value = false;
231  mxPropertyReplace->getPropertyValue("SearchCaseSensitive") >>= value;
232  return value;
233 }
234 
235 void SAL_CALL SwVbaFind::setMatchCase( sal_Bool _matchcase )
236 {
237  mxPropertyReplace->setPropertyValue("SearchCaseSensitive", uno::makeAny( _matchcase ) );
238 }
239 
241 {
242  bool value = false;
243  mxPropertyReplace->getPropertyValue("SearchWords") >>= value;
244  return value;
245 }
246 
247 void SAL_CALL SwVbaFind::setMatchWholeWord( sal_Bool _matchwholeword )
248 {
249  mxPropertyReplace->setPropertyValue("SearchWords", uno::makeAny( _matchwholeword ) );
250 }
251 
253 {
254  bool value = false;
255  mxPropertyReplace->getPropertyValue("SearchRegularExpression") >>= value;
256  return value;
257 }
258 
259 void SAL_CALL SwVbaFind::setMatchWildcards( sal_Bool _matchwildcards )
260 {
261  mxPropertyReplace->setPropertyValue("SearchRegularExpression", uno::makeAny( _matchwildcards ) );
262 }
263 
265 {
266  bool value = false;
267  mxPropertyReplace->getPropertyValue("SearchSimilarity") >>= value;
268  return value;
269 }
270 
271 void SAL_CALL SwVbaFind::setMatchSoundsLike( sal_Bool _matchsoundslike )
272 {
273  // seems not accurate
274  mxPropertyReplace->setPropertyValue("SearchSimilarity", uno::makeAny( _matchsoundslike ) );
275 }
276 
278 {
279  bool value = false;
280  mxPropertyReplace->getPropertyValue("SearchSimilarity") >>= value;
281  if( value )
282  mxPropertyReplace->getPropertyValue("SearchSimilarityRelax") >>= value;
283  return value;
284 }
285 
286 void SAL_CALL SwVbaFind::setMatchAllWordForms( sal_Bool _matchallwordforms )
287 {
288  // seems not accurate
289  mxPropertyReplace->setPropertyValue("SearchSimilarity", uno::makeAny( _matchallwordforms ) );
290  mxPropertyReplace->setPropertyValue("SearchSimilarityRelax", uno::makeAny( _matchallwordforms ) );
291 }
292 
294 {
295  throw uno::RuntimeException("Not implemented" );
296 }
297 
298 void SAL_CALL SwVbaFind::setStyle( const uno::Any& /*_style */ )
299 {
300  throw uno::RuntimeException("Not implemented" );
301 }
302 
303 sal_Bool SAL_CALL
304 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*/ )
305 {
306  bool result = false;
307  if( FindText.hasValue() )
308  {
309  OUString sText;
310  FindText >>= sText;
311  setText( sText );
312  }
313 
314  bool bValue = false;
315  if( MatchCase.hasValue() )
316  {
317  MatchCase >>= bValue;
318  setMatchCase( bValue );
319  }
320 
321  if( MatchWholeWord.hasValue() )
322  {
323  MatchWholeWord >>= bValue;
324  setMatchWholeWord( bValue );
325  }
326 
327  if( MatchWildcards.hasValue() )
328  {
329  MatchWildcards >>= bValue;
330  setMatchWildcards( bValue );
331  }
332 
333  if( MatchSoundsLike.hasValue() )
334  {
335  MatchSoundsLike >>= bValue;
336  setMatchSoundsLike( bValue );
337  }
338 
339  if( MatchAllWordForms.hasValue() )
340  {
341  MatchAllWordForms >>= bValue;
342  setMatchAllWordForms( bValue );
343  }
344 
345  if( Forward.hasValue() )
346  {
347  Forward >>= bValue;
348  setForward( bValue );
349  }
350 
351  if( Wrap.hasValue() )
352  {
353  sal_Int32 nWrapType = 0;
354  Wrap >>= nWrapType;
355  setWrap( nWrapType );
356  }
357 
358  if( Format.hasValue() )
359  {
360  Format >>= bValue;
361  setFormat( bValue );
362  }
363 
364  if( ReplaceWith.hasValue() )
365  {
366  OUString sValue;
367  ReplaceWith >>= sValue;
368  SetReplaceWith( sValue );
369  }
370 
371  if( Replace.hasValue() )
372  {
373  sal_Int32 nValue(0);
374  Replace >>= nValue;
375  SetReplace( nValue );
376  }
377 
378  result = SearchReplace();
379 
380  return result;
381 }
382 
383 void SAL_CALL
385 {
386  uno::Sequence< beans::PropertyValue > aSearchAttribs;
387  mxPropertyReplace->setSearchAttributes( aSearchAttribs );
388 }
389 
390 OUString
392 {
393  return "SwVbaFind";
394 }
395 
396 uno::Sequence< OUString >
398 {
399  static uno::Sequence< OUString > const aServiceNames
400  {
401  "ooo.vba.word.Find"
402  };
403  return aServiceNames;
404 }
405 
406 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool hasValue()
bool SearchReplace()
Definition: vbafind.cxx:115
virtual sal_Bool SAL_CALL Execute(const css::uno::Any &FindText, const css::uno::Any &MatchCase, const css::uno::Any &MatchWholeWord, const css::uno::Any &MatchWildcards, const css::uno::Any &MatchSoundsLike, const css::uno::Any &MatchAllWordForms, const css::uno::Any &Forward, const css::uno::Any &Wrap, const css::uno::Any &Format, const css::uno::Any &ReplaceWith, const css::uno::Any &Replace, const css::uno::Any &MatchKashida, const css::uno::Any &MatchDiacritics, const css::uno::Any &MatchAlefHamza, const css::uno::Any &MatchControl, const css::uno::Any &MatchPrefix, const css::uno::Any &MatchSuffix, const css::uno::Any &MatchPhrase, const css::uno::Any &IgnoreSpace, const css::uno::Any &IgnorePunct) override
Definition: vbafind.cxx:304
virtual sal_Bool SAL_CALL getMatchWholeWord() override
Definition: vbafind.cxx:240
css::uno::Reference< css::text::XTextViewCursor > mxTVC
Definition: vbafind.hxx:39
virtual sal_Bool SAL_CALL getMatchWildcards() override
Definition: vbafind.cxx:252
virtual OUString getServiceImplName() override
Definition: vbafind.cxx:391
bool InEqualRange(const css::uno::Reference< css::text::XTextRange > &xCurrentRange)
Definition: vbafind.cxx:49
css::uno::Reference< css::frame::XModel2 > mxModel
virtual sal_Bool SAL_CALL getForward() override
Definition: vbafind.cxx:193
virtual void SAL_CALL setReplacement(const css::uno::Any &_replacement) override
Definition: vbafind.cxx:188
Sequence< OUString > aServiceNames
css::uno::Reference< css::frame::XModel > mxModel
Definition: vbafind.hxx:35
virtual void SAL_CALL ClearFormatting() override
Definition: vbafind.cxx:384
virtual ::sal_Int32 SAL_CALL getWrap() override
Definition: vbafind.cxx:206
css::uno::Reference< css::util::XReplaceable > mxReplaceable
Definition: vbafind.hxx:37
OUString GetReplaceWith()
Definition: vbafind.cxx:61
uno::Reference< text::XTextViewCursor > getXTextViewCursor(const uno::Reference< frame::XModel > &xModel)
virtual void SAL_CALL setMatchWholeWord(sal_Bool _matchwholeword) override
Definition: vbafind.cxx:247
virtual sal_Bool SAL_CALL getMatchCase() override
Definition: vbafind.cxx:228
virtual void SAL_CALL setWrap(::sal_Int32 _wrap) override
Definition: vbafind.cxx:212
sal_Int32 mnReplaceType
Definition: vbafind.hxx:42
css::uno::Reference< css::text::XTextRange > mxTextRange
Definition: vbafind.hxx:36
css::uno::Reference< css::util::XPropertyReplace > mxPropertyReplace
Definition: vbafind.hxx:38
int i
virtual void SAL_CALL setMatchAllWordForms(sal_Bool _matchallwordforms) override
Definition: vbafind.cxx:286
virtual void SAL_CALL setMatchWildcards(sal_Bool _matchwildcards) override
Definition: vbafind.cxx:259
unsigned char sal_Bool
css::uno::Reference< css::text::XTextRange > FindOneElement()
Definition: vbafind.cxx:70
virtual ~SwVbaFind() override
Definition: vbafind.cxx:39
virtual css::uno::Any SAL_CALL getStyle() override
Definition: vbafind.cxx:293
virtual sal_Bool SAL_CALL getMatchSoundsLike() override
Definition: vbafind.cxx:264
css::uno::Reference< css::view::XSelectionSupplier > mxSelSupp
Definition: vbafind.hxx:40
virtual void SAL_CALL setFormat(sal_Bool _format) override
Definition: vbafind.cxx:223
virtual css::uno::Sequence< OUString > getServiceNames() override
Definition: vbafind.cxx:397
SwVbaFind(const css::uno::Reference< ooo::vba::XHelperInterface > &rParent, const css::uno::Reference< css::uno::XComponentContext > &rContext, const css::uno::Reference< css::frame::XModel > &xModel, const css::uno::Reference< css::text::XTextRange > &xTextRange)
Definition: vbafind.cxx:30
virtual void SAL_CALL setStyle(const css::uno::Any &_style) override
Definition: vbafind.cxx:298
virtual OUString SAL_CALL getText() override
Definition: vbafind.cxx:173
css::uno::Reference< css::uno::XComponentContext > mxContext
bool mbReplace
Definition: vbafind.hxx:41
virtual sal_Bool SAL_CALL getFormat() override
Definition: vbafind.cxx:218
Any value
virtual void SAL_CALL setForward(sal_Bool _forward) override
Definition: vbafind.cxx:200
Any result
virtual void SAL_CALL setText(const OUString &_text) override
Definition: vbafind.cxx:178
virtual css::uno::Any SAL_CALL getReplacement() override
Definition: vbafind.cxx:183
virtual sal_Bool SAL_CALL getMatchAllWordForms() override
Definition: vbafind.cxx:277
void SetReplaceWith(const OUString &rText)
Definition: vbafind.cxx:55
void SetReplace(sal_Int32 type)
Definition: vbafind.cxx:65
bool InRange(const css::uno::Reference< css::text::XTextRange > &xCurrentRange)
Definition: vbafind.cxx:43
virtual void SAL_CALL setMatchSoundsLike(sal_Bool _matchsoundslike) override
Definition: vbafind.cxx:271
virtual void SAL_CALL setMatchCase(sal_Bool _matchcase) override
Definition: vbafind.cxx:235
sal_Int32 mnWrap
Definition: vbafind.hxx:43
sal_Int16 nValue