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