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 .
20 #include <i18nutil/searchopt.hxx>
21 #include <i18nlangtag/languagetag.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>
29 using namespace ::com::sun::star
;
31 const std::wstring gaGroupChars
= L
"(){}[]";
33 ExtTextEngine::ExtTextEngine()
37 ExtTextEngine::~ExtTextEngine()
41 TextSelection
ExtTextEngine::MatchGroup( const TextPaM
& rCursor
) const
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
) ) )
49 size_t nMatchIndex
= gaGroupChars
.find( GetText( rCursor
.GetPara() )[ nPos
] );
50 if ( nMatchIndex
!= std::wstring::npos
)
52 if ( ( nMatchIndex
% 2 ) == 0 )
55 sal_Unicode nSC
= gaGroupChars
[ nMatchIndex
];
56 sal_Unicode nEC
= gaGroupChars
[ nMatchIndex
+1 ];
58 sal_Int32 nCur
= nPos
+1;
59 sal_uInt16 nLevel
= 1;
60 while ( nLevel
&& ( nPara
< nParas
) )
62 OUString aStr
= GetText( nPara
);
63 while ( nCur
< aStr
.getLength() )
65 if ( aStr
[nCur
] == nSC
)
67 else if ( aStr
[nCur
] == nEC
)
71 break; // while nCur...
82 if ( nLevel
== 0 ) // found
84 aSel
.GetStart() = rCursor
;
85 aSel
.GetEnd() = TextPaM( nPara
, nCur
+1 );
91 sal_Unicode nEC
= gaGroupChars
[ nMatchIndex
];
92 sal_Unicode nSC
= gaGroupChars
[ nMatchIndex
-1 ];
94 sal_Int32 nCur
= rCursor
.GetIndex()-1;
95 sal_uInt16 nLevel
= 1;
98 if ( GetTextLen( nPara
) )
100 OUString aStr
= GetText( nPara
);
103 if ( aStr
[nCur
] == nSC
)
107 break; // while nCur...
109 else if ( aStr
[nCur
] == nEC
)
121 nCur
= GetTextLen( nPara
)-1; // no matter if negative, as if Len()
128 if ( nLevel
== 0 ) // found
130 aSel
.GetStart() = rCursor
;
131 ++aSel
.GetStart().GetIndex(); // behind the char
132 aSel
.GetEnd() = TextPaM( nPara
, nCur
);
140 bool ExtTextEngine::Search( TextSelection
& rSel
, const i18nutil::SearchOptions
& rSearchOptions
, bool bForward
)
142 TextSelection
aSel( rSel
);
145 bool bSearchInSelection
= (0 != (rSearchOptions
.searchFlag
& util::SearchFlags::REG_NOT_BEGINOFLINE
) );
147 TextPaM
aStartPaM( aSel
.GetEnd() );
148 if ( aSel
.HasRange() && ( ( bSearchInSelection
&& bForward
) || ( !bSearchInSelection
&& !bForward
) ) )
150 aStartPaM
= aSel
.GetStart();
156 if ( bSearchInSelection
)
157 nEndNode
= bForward
? aSel
.GetEnd().GetPara() : aSel
.GetStart().GetPara();
159 nEndNode
= bForward
? (GetParagraphCount()-1) : 0;
161 const sal_uInt32 nStartNode
= aStartPaM
.GetPara();
163 i18nutil::SearchOptions
aOptions( rSearchOptions
);
164 aOptions
.Locale
= Application::GetSettings().GetLanguageTag().getLocale();
165 utl::TextSearch
aSearcher( utl::TextSearch::UpgradeToSearchOptions2(aOptions
) );
167 // iterate over the paragraphs
168 for ( sal_uInt32 nNode
= nStartNode
;
169 bForward
? ( nNode
<= nEndNode
) : ( nNode
>= nEndNode
);
170 bForward
? nNode
++ : nNode
-- )
172 OUString aText
= GetText( nNode
);
173 sal_Int32 nStartPos
= 0;
174 sal_Int32 nEndPos
= aText
.getLength();
175 if ( nNode
== nStartNode
)
178 nStartPos
= aStartPaM
.GetIndex();
180 nEndPos
= aStartPaM
.GetIndex();
182 if ( ( nNode
== nEndNode
) && bSearchInSelection
)
185 nEndPos
= aSel
.GetEnd().GetIndex();
187 nStartPos
= aSel
.GetStart().GetIndex();
191 bFound
= aSearcher
.SearchForward( aText
, &nStartPos
, &nEndPos
);
193 bFound
= aSearcher
.SearchBackward( aText
, &nEndPos
, &nStartPos
);
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...
205 if ( (rSel
.GetEnd().GetPara()+1) < GetParagraphCount() )
207 rSel
.GetEnd().GetPara()++;
208 rSel
.GetEnd().GetIndex() = 0;
212 rSel
.GetEnd().GetIndex() = nStartPos
;
220 if ( !bForward
&& !nNode
) // if searching backwards, if nEndNode == 0:
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */