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 .
21 #include <vcl/xtextedt.hxx>
22 #include <vcl/svapp.hxx> // International
23 #include <unotools/textsearch.hxx>
24 #include <com/sun/star/util/SearchOptions.hpp>
25 #include <com/sun/star/util/SearchFlags.hpp>
27 using namespace ::com::sun::star
;
30 ExtTextEngine::ExtTextEngine() : maGroupChars(OUString("(){}[]"))
34 ExtTextEngine::~ExtTextEngine()
38 TextSelection
ExtTextEngine::MatchGroup( const TextPaM
& rCursor
) const
40 TextSelection
aSel( rCursor
);
41 sal_uInt16 nPos
= rCursor
.GetIndex();
42 sal_uLong nPara
= rCursor
.GetPara();
43 sal_uLong nParas
= GetParagraphCount();
44 if ( ( nPara
< nParas
) && ( nPos
< GetTextLen( nPara
) ) )
46 sal_uInt16 nMatchChar
= maGroupChars
.Search( GetText( rCursor
.GetPara() ).GetChar( nPos
) );
47 if ( nMatchChar
!= STRING_NOTFOUND
)
49 if ( ( nMatchChar
% 2 ) == 0 )
52 sal_Unicode nSC
= maGroupChars
.GetChar( nMatchChar
);
53 sal_Unicode nEC
= maGroupChars
.GetChar( nMatchChar
+1 );
55 sal_uInt16 nCur
= nPos
+1;
56 sal_uInt16 nLevel
= 1;
57 while ( nLevel
&& ( nPara
< nParas
) )
59 XubString aStr
= GetText( nPara
);
60 while ( nCur
< aStr
.Len() )
62 if ( aStr
.GetChar( nCur
) == nSC
)
64 else if ( aStr
.GetChar( nCur
) == nEC
)
68 break; // while nCur...
79 if ( nLevel
== 0 ) // found
81 aSel
.GetStart() = rCursor
;
82 aSel
.GetEnd() = TextPaM( nPara
, nCur
+1 );
88 sal_Unicode nEC
= maGroupChars
.GetChar( nMatchChar
);
89 sal_Unicode nSC
= maGroupChars
.GetChar( nMatchChar
-1 );
91 sal_uInt16 nCur
= rCursor
.GetIndex()-1;
92 sal_uInt16 nLevel
= 1;
95 if ( GetTextLen( nPara
) )
97 XubString aStr
= GetText( nPara
);
100 if ( aStr
.GetChar( nCur
) == nSC
)
104 break; // while nCur...
106 else if ( aStr
.GetChar( nCur
) == nEC
)
118 nCur
= GetTextLen( nPara
)-1; // no matter if negativ, as if Len()
125 if ( nLevel
== 0 ) // found
127 aSel
.GetStart() = rCursor
;
128 aSel
.GetStart().GetIndex()++; // behind the char
129 aSel
.GetEnd() = TextPaM( nPara
, nCur
);
137 sal_Bool
ExtTextEngine::Search( TextSelection
& rSel
, const util::SearchOptions
& rSearchOptions
, sal_Bool bForward
)
139 TextSelection
aSel( rSel
);
142 bool bSearchInSelection
= (0 != (rSearchOptions
.searchFlag
& util::SearchFlags::REG_NOT_BEGINOFLINE
) );
144 TextPaM
aStartPaM( aSel
.GetEnd() );
145 if ( aSel
.HasRange() && ( ( bSearchInSelection
&& bForward
) || ( !bSearchInSelection
&& !bForward
) ) )
147 aStartPaM
= aSel
.GetStart();
151 sal_uLong nStartNode
, nEndNode
;
153 if ( bSearchInSelection
)
154 nEndNode
= bForward
? aSel
.GetEnd().GetPara() : aSel
.GetStart().GetPara();
156 nEndNode
= bForward
? (GetParagraphCount()-1) : 0;
158 nStartNode
= aStartPaM
.GetPara();
160 util::SearchOptions
aOptions( rSearchOptions
);
161 aOptions
.Locale
= Application::GetSettings().GetLanguageTag().getLocale();
162 utl::TextSearch
aSearcher( rSearchOptions
);
164 // iterate over the paragraphs
165 for ( sal_uLong nNode
= nStartNode
;
166 bForward
? ( nNode
<= nEndNode
) : ( nNode
>= nEndNode
);
167 bForward
? nNode
++ : nNode
-- )
169 String aText
= GetText( nNode
);
170 sal_uInt16 nStartPos
= 0;
171 sal_uInt16 nEndPos
= aText
.Len();
172 if ( nNode
== nStartNode
)
175 nStartPos
= aStartPaM
.GetIndex();
177 nEndPos
= aStartPaM
.GetIndex();
179 if ( ( nNode
== nEndNode
) && bSearchInSelection
)
182 nEndPos
= aSel
.GetEnd().GetIndex();
184 nStartPos
= aSel
.GetStart().GetIndex();
188 bFound
= aSearcher
.SearchFrwrd( aText
, &nStartPos
, &nEndPos
);
190 bFound
= aSearcher
.SearchBkwrd( aText
, &nEndPos
, &nStartPos
);
194 rSel
.GetStart().GetPara() = nNode
;
195 rSel
.GetStart().GetIndex() = nStartPos
;
196 rSel
.GetEnd().GetPara() = nNode
;
197 rSel
.GetEnd().GetIndex() = nEndPos
;
198 // Select over the paragraph?
199 // FIXME This should be max long...
200 if( nEndPos
== sal::static_int_cast
<sal_uInt16
>(-1) ) // sal_uInt16 for 0 and -1 !
202 if ( (rSel
.GetEnd().GetPara()+1) < GetParagraphCount() )
204 rSel
.GetEnd().GetPara()++;
205 rSel
.GetEnd().GetIndex() = 0;
209 rSel
.GetEnd().GetIndex() = nStartPos
;
217 if ( !bForward
&& !nNode
) // if searching backwards, if nEndNode == 0:
225 // -------------------------------------------------------------------------
227 // -------------------------------------------------------------------------
228 ExtTextView::ExtTextView( ExtTextEngine
* pEng
, Window
* pWindow
)
229 : TextView( pEng
, pWindow
)
233 ExtTextView::~ExtTextView()
237 sal_Bool
ExtTextView::MatchGroup()
239 TextSelection
aTmpSel( GetSelection() );
241 if ( ( aTmpSel
.GetStart().GetPara() != aTmpSel
.GetEnd().GetPara() ) ||
242 ( ( aTmpSel
.GetEnd().GetIndex() - aTmpSel
.GetStart().GetIndex() ) > 1 ) )
247 TextSelection aMatchSel
= ((ExtTextEngine
*)GetTextEngine())->MatchGroup( aTmpSel
.GetStart() );
248 if ( aMatchSel
.HasRange() )
249 SetSelection( aMatchSel
);
251 return aMatchSel
.HasRange() ? sal_True
: sal_False
;
254 sal_Bool
ExtTextView::Search( const util::SearchOptions
& rSearchOptions
, sal_Bool bForward
)
256 sal_Bool bFound
= sal_False
;
257 TextSelection
aSel( GetSelection() );
258 if ( ((ExtTextEngine
*)GetTextEngine())->Search( aSel
, rSearchOptions
, bForward
) )
261 // First add the beginning of the word to the selection,
262 // so that the whole word is in the visible region.
263 SetSelection( aSel
.GetStart() );
264 ShowCursor( sal_True
, sal_False
);
268 aSel
= GetSelection().GetEnd();
271 SetSelection( aSel
);
277 sal_uInt16
ExtTextView::Replace( const util::SearchOptions
& rSearchOptions
, sal_Bool bAll
, sal_Bool bForward
)
279 sal_uInt16 nFound
= 0;
283 if ( GetSelection().HasRange() )
285 InsertText( rSearchOptions
.replaceString
);
287 Search( rSearchOptions
, bForward
); // right away to the next
291 if( Search( rSearchOptions
, bForward
) )
297 // the writer replaces all, from beginning to end
299 ExtTextEngine
* pTextEngine
= (ExtTextEngine
*)GetTextEngine();
304 bool bSearchInSelection
= (0 != (rSearchOptions
.searchFlag
& util::SearchFlags::REG_NOT_BEGINOFLINE
) );
305 if ( bSearchInSelection
)
307 aSel
= GetSelection();
311 TextSelection
aSearchSel( aSel
);
313 sal_Bool bFound
= pTextEngine
->Search( aSel
, rSearchOptions
, sal_True
);
315 pTextEngine
->UndoActionStart();
320 TextPaM aNewStart
= pTextEngine
->ImpInsertText( aSel
, rSearchOptions
.replaceString
);
322 aSel
.GetStart() = aNewStart
;
323 bFound
= pTextEngine
->Search( aSel
, rSearchOptions
, sal_True
);
327 SetSelection( aSel
.GetStart() );
328 pTextEngine
->FormatAndUpdate( this );
329 pTextEngine
->UndoActionEnd();
335 sal_Bool
ExtTextView::ImpIndentBlock( sal_Bool bRight
)
337 sal_Bool bDone
= sal_False
;
339 TextSelection aSel
= GetSelection();
343 GetTextEngine()->UndoActionStart();
345 sal_uLong nStartPara
= aSel
.GetStart().GetPara();
346 sal_uLong nEndPara
= aSel
.GetEnd().GetPara();
347 if ( aSel
.HasRange() && !aSel
.GetEnd().GetIndex() )
349 nEndPara
--; // do not indent
352 for ( sal_uLong nPara
= nStartPara
; nPara
<= nEndPara
; nPara
++ )
357 GetTextEngine()->ImpInsertText( TextPaM( nPara
, 0 ), '\t' );
362 // remove Tabs/Blanks
363 String aText
= GetTextEngine()->GetText( nPara
);
364 if ( aText
.Len() && (
365 ( aText
.GetChar( 0 ) == '\t' ) ||
366 ( aText
.GetChar( 0 ) == ' ' ) ) )
368 GetTextEngine()->ImpDeleteText( TextSelection( TextPaM( nPara
, 0 ), TextPaM( nPara
, 1 ) ) );
374 GetTextEngine()->UndoActionEnd();
376 sal_Bool bRange
= aSel
.HasRange();
379 aSel
.GetStart().GetIndex()++;
380 if ( bRange
&& ( aSel
.GetEnd().GetPara() == nEndPara
) )
381 aSel
.GetEnd().GetIndex()++;
385 if ( aSel
.GetStart().GetIndex() )
386 aSel
.GetStart().GetIndex()--;
387 if ( bRange
&& aSel
.GetEnd().GetIndex() )
388 aSel
.GetEnd().GetIndex()--;
391 ImpSetSelection( aSel
);
392 GetTextEngine()->FormatAndUpdate( this );
397 sal_Bool
ExtTextView::IndentBlock()
399 return ImpIndentBlock( sal_True
);
402 sal_Bool
ExtTextView::UnindentBlock()
404 return ImpIndentBlock( sal_False
);
407 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */