LibreOffice Module vcl (master)  1
xtextedt.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 
20 #include <i18nutil/searchopt.hxx>
22 #include <vcl/textdata.hxx>
23 #include <vcl/xtextedt.hxx>
24 #include <vcl/svapp.hxx>
25 #include <vcl/settings.hxx>
26 #include <unotools/textsearch.hxx>
27 #include <com/sun/star/util/SearchFlags.hpp>
28 
29 using namespace ::com::sun::star;
30 
31 static const std::wstring gaGroupChars = L"(){}[]";
32 
34 {
35 }
36 
38 {
39 }
40 
42 {
43  TextSelection aSel( rCursor );
44  const sal_Int32 nPos = rCursor.GetIndex();
45  sal_uInt32 nPara = rCursor.GetPara();
46  const sal_uInt32 nParas = GetParagraphCount();
47  if ( ( nPara < nParas ) && ( nPos < GetTextLen( nPara ) ) )
48  {
49  size_t nMatchIndex = gaGroupChars.find( GetText( rCursor.GetPara() )[ nPos ] );
50  if ( nMatchIndex != std::wstring::npos )
51  {
52  if ( ( nMatchIndex % 2 ) == 0 )
53  {
54  // search forwards
55  sal_Unicode nSC = gaGroupChars[ nMatchIndex ];
56  sal_Unicode nEC = gaGroupChars[ nMatchIndex+1 ];
57 
58  sal_Int32 nCur = nPos+1;
59  sal_uInt16 nLevel = 1;
60  while ( nLevel && ( nPara < nParas ) )
61  {
62  OUString aStr = GetText( nPara );
63  while ( nCur < aStr.getLength() )
64  {
65  if ( aStr[nCur] == nSC )
66  nLevel++;
67  else if ( aStr[nCur] == nEC )
68  {
69  nLevel--;
70  if ( !nLevel )
71  break; // while nCur...
72  }
73  nCur++;
74  }
75 
76  if ( nLevel )
77  {
78  nPara++;
79  nCur = 0;
80  }
81  }
82  if ( nLevel == 0 ) // found
83  {
84  aSel.GetStart() = rCursor;
85  aSel.GetEnd() = TextPaM( nPara, nCur+1 );
86  }
87  }
88  else
89  {
90  // search backwards
91  sal_Unicode nEC = gaGroupChars[ nMatchIndex ];
92  sal_Unicode nSC = gaGroupChars[ nMatchIndex-1 ];
93 
94  sal_Int32 nCur = rCursor.GetIndex()-1;
95  sal_uInt16 nLevel = 1;
96  while ( nLevel )
97  {
98  if ( GetTextLen( nPara ) )
99  {
100  OUString aStr = GetText( nPara );
101  while ( nCur )
102  {
103  if ( aStr[nCur] == nSC )
104  {
105  nLevel--;
106  if ( !nLevel )
107  break; // while nCur...
108  }
109  else if ( aStr[nCur] == nEC )
110  nLevel++;
111 
112  nCur--;
113  }
114  }
115 
116  if ( nLevel )
117  {
118  if ( nPara )
119  {
120  nPara--;
121  nCur = GetTextLen( nPara )-1; // no matter if negative, as if Len()
122  }
123  else
124  break;
125  }
126  }
127 
128  if ( nLevel == 0 ) // found
129  {
130  aSel.GetStart() = rCursor;
131  ++aSel.GetStart().GetIndex(); // behind the char
132  aSel.GetEnd() = TextPaM( nPara, nCur );
133  }
134  }
135  }
136  }
137  return aSel;
138 }
139 
140 bool ExtTextEngine::Search( TextSelection& rSel, const i18nutil::SearchOptions& rSearchOptions, bool bForward )
141 {
142  TextSelection aSel( rSel );
143  aSel.Justify();
144 
145  bool bSearchInSelection = (0 != (rSearchOptions.searchFlag & util::SearchFlags::REG_NOT_BEGINOFLINE) );
146 
147  TextPaM aStartPaM( aSel.GetEnd() );
148  if ( aSel.HasRange() && ( ( bSearchInSelection && bForward ) || ( !bSearchInSelection && !bForward ) ) )
149  {
150  aStartPaM = aSel.GetStart();
151  }
152 
153  bool bFound = false;
154  sal_uInt32 nEndNode;
155 
156  if ( bSearchInSelection )
157  nEndNode = bForward ? aSel.GetEnd().GetPara() : aSel.GetStart().GetPara();
158  else
159  nEndNode = bForward ? (GetParagraphCount()-1) : 0;
160 
161  const sal_uInt32 nStartNode = aStartPaM.GetPara();
162 
163  i18nutil::SearchOptions aOptions( rSearchOptions );
166 
167  // iterate over the paragraphs
168  for ( sal_uInt32 nNode = nStartNode;
169  bForward ? ( nNode <= nEndNode) : ( nNode >= nEndNode );
170  bForward ? nNode++ : nNode-- )
171  {
172  OUString aText = GetText( nNode );
173  sal_Int32 nStartPos = 0;
174  sal_Int32 nEndPos = aText.getLength();
175  if ( nNode == nStartNode )
176  {
177  if ( bForward )
178  nStartPos = aStartPaM.GetIndex();
179  else
180  nEndPos = aStartPaM.GetIndex();
181  }
182  if ( ( nNode == nEndNode ) && bSearchInSelection )
183  {
184  if ( bForward )
185  nEndPos = aSel.GetEnd().GetIndex();
186  else
187  nStartPos = aSel.GetStart().GetIndex();
188  }
189 
190  if ( bForward )
191  bFound = aSearcher.SearchForward( aText, &nStartPos, &nEndPos );
192  else
193  bFound = aSearcher.SearchBackward( aText, &nEndPos, &nStartPos );
194 
195  if ( bFound )
196  {
197  rSel.GetStart().GetPara() = nNode;
198  rSel.GetStart().GetIndex() = nStartPos;
199  rSel.GetEnd().GetPara() = nNode;
200  rSel.GetEnd().GetIndex() = nEndPos;
201  // Select over the paragraph?
202  // FIXME This should be max long...
203  if( nEndPos == -1)
204  {
205  if ( (rSel.GetEnd().GetPara()+1) < GetParagraphCount() )
206  {
207  rSel.GetEnd().GetPara()++;
208  rSel.GetEnd().GetIndex() = 0;
209  }
210  else
211  {
212  rSel.GetEnd().GetIndex() = nStartPos;
213  bFound = false;
214  }
215  }
216 
217  break;
218  }
219 
220  if ( !bForward && !nNode ) // if searching backwards, if nEndNode == 0:
221  break;
222  }
223 
224  return bFound;
225 }
226 
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool HasRange() const
Definition: textdata.hxx:99
OUString GetText(LineEnd aSeparator=LINEEND_LF) const
Definition: texteng.cxx:255
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:705
const TextPaM & GetEnd() const
Definition: textdata.hxx:94
virtual ~ExtTextEngine() override
Definition: xtextedt.cxx:37
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
sal_uInt16 sal_Unicode
static i18nutil::SearchOptions2 UpgradeToSearchOptions2(const i18nutil::SearchOptions &rOptions)
sal_uInt32 GetParagraphCount() const
Definition: texteng.cxx:1272
const LanguageTag & GetLanguageTag() const
css::lang::Locale Locale
bool SearchForward(const OUString &rStr, sal_Int32 *pStart, sal_Int32 *pEnd, css::util::SearchResult *pRes=nullptr)
TextSelection MatchGroup(const TextPaM &rCursor) const
Definition: xtextedt.cxx:41
const TextPaM & GetStart() const
Definition: textdata.hxx:91
sal_Int32 GetTextLen() const
Definition: texteng.cxx:286
bool SearchBackward(const OUString &rStr, sal_Int32 *pStart, sal_Int32 *pEnd, css::util::SearchResult *pRes=nullptr)
sal_Int32 GetIndex() const
Definition: textdata.hxx:49
void Justify()
Definition: textdata.cxx:44
bool Search(TextSelection &rSel, const i18nutil::SearchOptions &rSearchOptions, bool bForward=true)
Definition: xtextedt.cxx:140
static const std::wstring gaGroupChars
Definition: xtextedt.cxx:31
sal_Int32 nPos
aStr
sal_uInt32 GetPara() const
Definition: textdata.hxx:46