Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <vcl/wrkwin.hxx>
31 : : #include <vcl/dialog.hxx>
32 : : #include <vcl/msgbox.hxx>
33 : : #include <vcl/svapp.hxx>
34 : :
35 : : #include <impedit.hxx>
36 : : #include <editeng/editview.hxx>
37 : : #include <editeng/editeng.hxx>
38 : : #include <editeng/unolingu.hxx>
39 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 : : #include <com/sun/star/lang/Locale.hpp>
41 : : #include <editeng/langitem.hxx>
42 : : #include <editeng/fontitem.hxx>
43 : : #include <textconv.hxx>
44 : :
45 : :
46 : : using ::rtl::OUString;
47 : : using namespace com::sun::star;
48 : : using namespace com::sun::star::uno;
49 : : using namespace com::sun::star::beans;
50 : : using namespace com::sun::star::lang;
51 : : using namespace com::sun::star::linguistic2;
52 : :
53 : : #define C2U(cChar) OUString::createFromAscii(cChar)
54 : :
55 : : //////////////////////////////////////////////////////////////////////
56 : :
57 : 0 : TextConvWrapper::TextConvWrapper( Window* pWindow,
58 : : const Reference< XMultiServiceFactory >& rxMSF,
59 : : const Locale& rSourceLocale,
60 : : const Locale& rTargetLocale,
61 : : const Font* pTargetFont,
62 : : sal_Int32 nOptions,
63 : : sal_Bool bIsInteractive,
64 : : sal_Bool bIsStart,
65 : : EditView* pView ) :
66 : 0 : HangulHanjaConversion( pWindow, rxMSF, rSourceLocale, rTargetLocale, pTargetFont, nOptions, bIsInteractive )
67 : : {
68 : : DBG_ASSERT( pWindow, "TextConvWrapper: window missing" );
69 : :
70 : 0 : nConvTextLang = LANGUAGE_NONE;
71 : 0 : nUnitOffset = 0;
72 : :
73 : 0 : bStartChk = sal_False;
74 : 0 : bStartDone = bIsStart;
75 : 0 : bEndDone = sal_False;
76 : 0 : pWin = pWindow;
77 : 0 : pEditView = pView;
78 : :
79 [ # # ]: 0 : aConvSel = pEditView->GetSelection();
80 : 0 : aConvSel.Adjust(); // make Start <= End
81 : :
82 : 0 : bAllowChange = sal_False;
83 : 0 : }
84 : :
85 : :
86 : 0 : TextConvWrapper::~TextConvWrapper()
87 : : {
88 [ # # ]: 0 : }
89 : :
90 : :
91 : 0 : sal_Bool TextConvWrapper::ConvNext_impl()
92 : : {
93 : : // modified version of SvxSpellWrapper::SpellNext
94 : :
95 [ # # ]: 0 : if( bStartChk )
96 : 0 : bStartDone = sal_True;
97 : : else
98 : 0 : bEndDone = sal_True;
99 : :
100 [ # # ][ # # ]: 0 : if ( bStartDone && bEndDone )
101 : : {
102 [ # # ]: 0 : if ( ConvMore_impl() ) // examine another document?
103 : : {
104 : 0 : bStartDone = sal_True;
105 : 0 : bEndDone = sal_False;
106 : 0 : ConvStart_impl( SVX_SPELL_BODY );
107 : 0 : return sal_True;
108 : : }
109 : 0 : return sal_False;
110 : :
111 : : }
112 : :
113 : 0 : sal_Bool bGoOn = sal_False;
114 : :
115 [ # # ][ # # ]: 0 : if ( bStartDone && bEndDone )
116 : : {
117 [ # # ]: 0 : if ( ConvMore_impl() ) // examine another document?
118 : : {
119 : 0 : bStartDone = sal_True;
120 : 0 : bEndDone = sal_False;
121 : 0 : ConvStart_impl( SVX_SPELL_BODY );
122 : 0 : return sal_True;
123 : : }
124 : : }
125 [ # # ]: 0 : else if (!aConvSel.HasRange())
126 : : {
127 : 0 : bStartChk = !bStartDone;
128 [ # # ]: 0 : ConvStart_impl( bStartChk ? SVX_SPELL_BODY_START : SVX_SPELL_BODY_END );
129 : 0 : bGoOn = sal_True;
130 : : }
131 : 0 : return bGoOn;
132 : : }
133 : :
134 : :
135 : 0 : sal_Bool TextConvWrapper::FindConvText_impl()
136 : : {
137 : : // modified version of SvxSpellWrapper::FindSpellError
138 : :
139 : 0 : sal_Bool bFound = sal_False;
140 : :
141 : 0 : pWin->EnterWait();
142 : 0 : sal_Bool bConvert = sal_True;
143 : :
144 [ # # ]: 0 : while ( bConvert )
145 : : {
146 : 0 : bFound = ConvContinue_impl();
147 [ # # ]: 0 : if (bFound)
148 : : {
149 : 0 : bConvert = sal_False;
150 : : }
151 : : else
152 : : {
153 : 0 : ConvEnd_impl();
154 : 0 : bConvert = ConvNext_impl();
155 : : }
156 : : }
157 : 0 : pWin->LeaveWait();
158 : 0 : return bFound;
159 : : }
160 : :
161 : :
162 : 0 : sal_Bool TextConvWrapper::ConvMore_impl()
163 : : {
164 : : // modified version of SvxSpellWrapper::SpellMore
165 : :
166 : 0 : bool bMore = false;
167 : 0 : EditEngine* pEE = pEditView->GetEditEngine();
168 : 0 : ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
169 : 0 : ConvInfo* pConvInfo = pImpEE->GetConvInfo();
170 [ # # ]: 0 : if ( pConvInfo->bMultipleDoc )
171 : : {
172 : 0 : bMore = pEE->ConvertNextDocument();
173 [ # # ]: 0 : if ( bMore )
174 : : {
175 : : // The text has been entered in this engine ...
176 : : pEditView->GetImpEditView()->SetEditSelection(
177 [ # # ][ # # ]: 0 : pEE->GetEditDoc().GetStartPaM() );
178 : : }
179 : : }
180 : 0 : return bMore;
181 : : }
182 : :
183 : :
184 : 0 : void TextConvWrapper::ConvStart_impl( SvxSpellArea eArea )
185 : : {
186 : : // modified version of EditSpellWrapper::SpellStart
187 : :
188 : 0 : EditEngine* pEE = pEditView->GetEditEngine();
189 : 0 : ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
190 : 0 : ConvInfo* pConvInfo = pImpEE->GetConvInfo();
191 : :
192 [ # # ]: 0 : if ( eArea == SVX_SPELL_BODY_START )
193 : : {
194 : : // Is called when Spell-forward has reached the end, and to start over
195 [ # # ]: 0 : if ( bEndDone )
196 : : {
197 : 0 : pConvInfo->bConvToEnd = sal_False;
198 : 0 : pConvInfo->aConvTo = pConvInfo->aConvStart;
199 : 0 : pConvInfo->aConvContinue = EPaM( 0, 0 );
200 : : pEditView->GetImpEditView()->SetEditSelection(
201 [ # # ][ # # ]: 0 : pEE->GetEditDoc().GetStartPaM() );
202 : : }
203 : : else
204 : : {
205 : 0 : pConvInfo->bConvToEnd = sal_True;
206 : : pConvInfo->aConvTo = pImpEE->CreateEPaM(
207 [ # # ]: 0 : pEE->GetEditDoc().GetStartPaM() );
208 : : }
209 : : }
210 [ # # ]: 0 : else if ( eArea == SVX_SPELL_BODY_END )
211 : : {
212 : : // Is called when Spell-forward starts
213 : 0 : pConvInfo->bConvToEnd = sal_True;
214 [ # # ]: 0 : if (aConvSel.HasRange())
215 : : {
216 : : // user selection: convert to end of selection
217 : 0 : pConvInfo->aConvTo.nPara = aConvSel.nEndPara;
218 : 0 : pConvInfo->aConvTo.nIndex = aConvSel.nEndPos;
219 : 0 : pConvInfo->bConvToEnd = sal_False;
220 : : }
221 : : else
222 : : {
223 : : // nothing selected: convert to end of document
224 : : pConvInfo->aConvTo = pImpEE->CreateEPaM(
225 [ # # ]: 0 : pEE->GetEditDoc().GetEndPaM() );
226 : : }
227 : : }
228 [ # # ]: 0 : else if ( eArea == SVX_SPELL_BODY )
229 : : {
230 : : // called by ConvNext_impl...
231 : 0 : pConvInfo->aConvContinue = pConvInfo->aConvStart;
232 : : pConvInfo->aConvTo = pImpEE->CreateEPaM(
233 [ # # ]: 0 : pEE->GetEditDoc().GetEndPaM() );
234 : : }
235 : : else
236 : : {
237 : : OSL_FAIL( "ConvStart_impl: Unknown Area!" );
238 : : }
239 : 0 : }
240 : :
241 : :
242 : 0 : void TextConvWrapper::ConvEnd_impl()
243 : : {
244 : 0 : }
245 : :
246 : :
247 : 0 : sal_Bool TextConvWrapper::ConvContinue_impl()
248 : : {
249 : : // modified version of EditSpellWrapper::SpellContinue
250 : :
251 : : // get next convertible text portion and its language
252 : 0 : aConvText = rtl::OUString();
253 : 0 : nConvTextLang = LANGUAGE_NONE;
254 : : pEditView->GetImpEditEngine()->ImpConvert( aConvText, nConvTextLang,
255 : 0 : pEditView, GetSourceLanguage(), aConvSel,
256 : 0 : bAllowChange, GetTargetLanguage(), GetTargetFont() );
257 : 0 : return !aConvText.isEmpty();
258 : : }
259 : :
260 : :
261 : 0 : void TextConvWrapper::SetLanguageAndFont( const ESelection &rESel,
262 : : LanguageType nLang, sal_uInt16 nLangWhichId,
263 : : const Font *pFont, sal_uInt16 nFontWhichId )
264 : : {
265 [ # # ]: 0 : ESelection aOldSel = pEditView->GetSelection();
266 [ # # ]: 0 : pEditView->SetSelection( rESel );
267 : :
268 : : // set new language attribute
269 [ # # ][ # # ]: 0 : SfxItemSet aNewSet( pEditView->GetEmptyItemSet() );
270 [ # # ][ # # ]: 0 : aNewSet.Put( SvxLanguageItem( nLang, nLangWhichId ) );
[ # # ]
271 : :
272 : : // new font to be set?
273 : : DBG_ASSERT( pFont, "target font missing?" );
274 [ # # ]: 0 : if (pFont)
275 : : {
276 : : // set new font attribute
277 [ # # ][ # # ]: 0 : SvxFontItem aFontItem = (SvxFontItem&) aNewSet.Get( nFontWhichId );
278 [ # # ][ # # ]: 0 : aFontItem.SetFamilyName( pFont->GetName());
279 [ # # ]: 0 : aFontItem.SetFamily( pFont->GetFamily());
280 [ # # ][ # # ]: 0 : aFontItem.SetStyleName( pFont->GetStyleName());
281 [ # # ]: 0 : aFontItem.SetPitch( pFont->GetPitch());
282 [ # # ]: 0 : aFontItem.SetCharSet(pFont->GetCharSet());
283 [ # # ][ # # ]: 0 : aNewSet.Put( aFontItem );
284 : : }
285 : :
286 : : // apply new attributes
287 [ # # ]: 0 : pEditView->SetAttribs( aNewSet );
288 : :
289 [ # # ][ # # ]: 0 : pEditView->SetSelection( aOldSel );
290 : 0 : }
291 : :
292 : :
293 : 0 : void TextConvWrapper::SelectNewUnit_impl(
294 : : const sal_Int32 nUnitStart,
295 : : const sal_Int32 nUnitEnd )
296 : : {
297 [ # # ][ # # ]: 0 : sal_Bool bOK = 0 <= nUnitStart && 0 <= nUnitEnd && nUnitStart <= nUnitEnd;
[ # # ]
298 : : DBG_ASSERT( bOK, "invalid arguments" );
299 [ # # ]: 0 : if (!bOK)
300 : 0 : return;
301 : :
302 [ # # ]: 0 : ESelection aSelection = pEditView->GetSelection();
303 : : DBG_ASSERT( aSelection.nStartPara == aSelection.nEndPara,
304 : : "paragraph mismatch in selection" );
305 : 0 : aSelection.nStartPos = (sal_uInt16) (nLastPos + nUnitOffset + nUnitStart);
306 : 0 : aSelection.nEndPos = (sal_uInt16) (nLastPos + nUnitOffset + nUnitEnd);
307 [ # # ]: 0 : pEditView->SetSelection( aSelection );
308 : : }
309 : :
310 : :
311 : 0 : void TextConvWrapper::GetNextPortion(
312 : : ::rtl::OUString& /* [out] */ rNextPortion,
313 : : LanguageType& /* [out] */ rLangOfPortion,
314 : : sal_Bool /* [in] */ _bAllowImplicitChangesForNotConvertibleText )
315 : : {
316 : 0 : bAllowChange = _bAllowImplicitChangesForNotConvertibleText;
317 : :
318 [ # # ]: 0 : FindConvText_impl();
319 : 0 : rNextPortion = aConvText;
320 : 0 : rLangOfPortion = nConvTextLang;
321 : 0 : nUnitOffset = 0;
322 : :
323 [ # # ]: 0 : ESelection aSelection = pEditView->GetSelection();
324 : : DBG_ASSERT( aSelection.nStartPara == aSelection.nEndPara,
325 : : "paragraph mismatch in selection" );
326 : : DBG_ASSERT( aSelection.nStartPos <= aSelection.nEndPos,
327 : : "start pos > end pos" );
328 : 0 : nLastPos = aSelection.nStartPos;
329 : 0 : }
330 : :
331 : :
332 : 0 : void TextConvWrapper::HandleNewUnit(
333 : : const sal_Int32 nUnitStart,
334 : : const sal_Int32 nUnitEnd )
335 : : {
336 : 0 : SelectNewUnit_impl( nUnitStart, nUnitEnd );
337 : 0 : }
338 : :
339 : : #ifdef DBG_UTIL
340 : : namespace
341 : : {
342 : : sal_Bool IsSimilarChinese( LanguageType nLang1, LanguageType nLang2 )
343 : : {
344 : : using namespace editeng;
345 : : return (HangulHanjaConversion::IsTraditional(nLang1) && HangulHanjaConversion::IsTraditional(nLang2)) ||
346 : : (HangulHanjaConversion::IsSimplified(nLang1) && HangulHanjaConversion::IsSimplified(nLang2));
347 : : }
348 : : }
349 : : #endif
350 : :
351 : 0 : void TextConvWrapper::ReplaceUnit(
352 : : const sal_Int32 nUnitStart, const sal_Int32 nUnitEnd,
353 : : const ::rtl::OUString& rOrigText,
354 : : const ::rtl::OUString& rReplaceWith,
355 : : const ::com::sun::star::uno::Sequence< sal_Int32 > &rOffsets,
356 : : ReplacementAction eAction,
357 : : LanguageType *pNewUnitLanguage )
358 : : {
359 [ # # ][ # # ]: 0 : sal_Bool bOK = 0 <= nUnitStart && 0 <= nUnitEnd && nUnitStart <= nUnitEnd;
[ # # ]
360 : : DBG_ASSERT( bOK, "invalid arguments" );
361 [ # # ]: 0 : if (!bOK)
362 : 0 : return;
363 : :
364 [ # # ][ # # ]: 0 : static OUString aBracketedStart( C2U( "(" ) );
365 [ # # ][ # # ]: 0 : static OUString aBracketedEnd( C2U( ")" ) );
366 : :
367 : : // select current unit
368 [ # # ]: 0 : SelectNewUnit_impl( nUnitStart, nUnitEnd );
369 : :
370 [ # # ][ # # ]: 0 : OUString aOrigTxt( pEditView->GetSelected() );
[ # # ]
371 : 0 : OUString aNewTxt( rReplaceWith );
372 [ # # ]: 0 : String aNewOrigText;
373 [ # # # # : 0 : switch (eAction)
# ]
374 : : {
375 : : case eExchange :
376 : 0 : break;
377 : : case eReplacementBracketed :
378 : 0 : (((aNewTxt = aOrigTxt) += aBracketedStart) += rReplaceWith) += aBracketedEnd;
379 : 0 : break;
380 : : case eOriginalBracketed :
381 : 0 : (((aNewTxt = rReplaceWith) += aBracketedStart) += aOrigTxt) += aBracketedEnd;
382 : 0 : break;
383 : : case eReplacementAbove :
384 : : case eOriginalAbove :
385 : : case eReplacementBelow :
386 : : case eOriginalBelow :
387 : : OSL_FAIL( "Rubies not supported" );
388 : 0 : break;
389 : : default:
390 : : OSL_FAIL( "unexpected case" );
391 : : }
392 : : nUnitOffset = sal::static_int_cast< sal_uInt16 >(
393 : 0 : nUnitOffset + nUnitStart + aNewTxt.getLength());
394 : :
395 : : // remember current original language for kater use
396 [ # # ]: 0 : ImpEditEngine *pImpEditEng = pEditView->GetImpEditEngine();
397 [ # # ]: 0 : ESelection _aOldSel = pEditView->GetSelection();
398 : : //EditSelection aOldEditSel = pEditView->GetImpEditView()->GetEditSelection();
399 : :
400 : : #ifdef DBG_UTIL
401 : : LanguageType nOldLang = pImpEditEng->GetLanguage( pImpEditEng->CreateSel( _aOldSel ).Min() );
402 : : #endif
403 : :
404 [ # # ]: 0 : pImpEditEng->UndoActionStart( EDITUNDO_INSERT );
405 : :
406 : : // according to FT we should currently not bother about keeping
407 : : // attributes in Hangul/Hanja conversion and leave that untouched.
408 : : // Thus we do this only for Chinese translation...
409 [ # # ][ # # ]: 0 : sal_Bool bIsChineseConversion = IsChinese( GetSourceLanguage() );
410 [ # # ]: 0 : if (bIsChineseConversion)
411 [ # # ][ # # ]: 0 : ChangeText( aNewTxt, rOrigText, &rOffsets, &_aOldSel );
[ # # ]
412 : : else
413 [ # # ][ # # ]: 0 : ChangeText( aNewTxt, rOrigText, NULL, NULL );
[ # # ]
414 : :
415 : : // change language and font if necessary
416 [ # # ]: 0 : if (bIsChineseConversion)
417 : : {
418 : : DBG_ASSERT( GetTargetLanguage() == LANGUAGE_CHINESE_SIMPLIFIED || GetTargetLanguage() == LANGUAGE_CHINESE_TRADITIONAL,
419 : : "TextConvWrapper::ReplaceUnit : unexpected target language" );
420 : :
421 [ # # ]: 0 : ESelection aOldSel = pEditView->GetSelection();
422 : 0 : ESelection aNewSel( aOldSel );
423 : : aNewSel.nStartPos = sal::static_int_cast< xub_StrLen >(
424 : 0 : aNewSel.nStartPos - aNewTxt.getLength());
425 : :
426 [ # # ]: 0 : if (pNewUnitLanguage)
427 : : {
428 : : DBG_ASSERT(!IsSimilarChinese( *pNewUnitLanguage, nOldLang ),
429 : : "similar language should not be changed!");
430 : : SetLanguageAndFont( aNewSel, *pNewUnitLanguage, EE_CHAR_LANGUAGE_CJK,
431 [ # # ][ # # ]: 0 : GetTargetFont(), EE_CHAR_FONTINFO_CJK );
432 : : }
433 : : }
434 : :
435 [ # # ]: 0 : pImpEditEng->UndoActionEnd( EDITUNDO_INSERT );
436 : :
437 : : // adjust ConvContinue / ConvTo if necessary
438 [ # # ]: 0 : ImpEditEngine* pImpEE = pEditView->GetImpEditEngine();
439 : 0 : ConvInfo* pConvInfo = pImpEE->GetConvInfo();
440 : 0 : sal_Int32 nDelta = aNewTxt.getLength() - aOrigTxt.getLength();
441 [ # # ]: 0 : if (nDelta != 0)
442 : : {
443 : : // Note: replacement is always done in the current paragraph
444 : : // which is the one ConvContinue points to
445 : : pConvInfo->aConvContinue.nIndex = sal::static_int_cast< sal_uInt16 >(
446 : 0 : pConvInfo->aConvContinue.nIndex + nDelta);
447 : :
448 : : // if that is the same as the one where the conversions ends
449 : : // the end needs to be updated also
450 [ # # ]: 0 : if (pConvInfo->aConvTo.nPara == pConvInfo->aConvContinue.nPara)
451 : : pConvInfo->aConvTo.nIndex = sal::static_int_cast< sal_uInt16 >(
452 : 0 : pConvInfo->aConvTo.nIndex + nDelta);
453 [ # # ]: 0 : }
454 : : }
455 : :
456 : :
457 : 0 : void TextConvWrapper::ChangeText( const String &rNewText,
458 : : const OUString& rOrigText,
459 : : const uno::Sequence< sal_Int32 > *pOffsets,
460 : : ESelection *pESelection )
461 : : {
462 : : //!! code is a modifed copy of SwHHCWrapper::ChangeText from sw !!
463 : :
464 : : DBG_ASSERT( rNewText.Len() != 0, "unexpected empty string" );
465 [ # # ]: 0 : if (rNewText.Len() == 0)
466 : 0 : return;
467 : :
468 [ # # ][ # # ]: 0 : if (pOffsets && pESelection) // try to keep as much attributation as possible ?
469 : : {
470 : 0 : pESelection->Adjust();
471 : :
472 : : // remember cursor start position for later setting of the cursor
473 : 0 : const xub_StrLen nStartIndex = pESelection->nStartPos;
474 : :
475 : 0 : const sal_Int32 nIndices = pOffsets->getLength();
476 : 0 : const sal_Int32 *pIndices = pOffsets->getConstArray();
477 : 0 : xub_StrLen nConvTextLen = rNewText.Len();
478 : 0 : xub_StrLen nPos = 0;
479 : 0 : xub_StrLen nChgPos = STRING_NOTFOUND;
480 : 0 : xub_StrLen nChgLen = 0;
481 : 0 : xub_StrLen nConvChgPos = STRING_NOTFOUND;
482 : 0 : xub_StrLen nConvChgLen = 0;
483 : :
484 : : // offset to calculate the position in the text taking into
485 : : // account that text may have been replaced with new text of
486 : : // different length. Negative values allowed!
487 : 0 : long nCorrectionOffset = 0;
488 : :
489 : : DBG_ASSERT(nIndices == 0 || nIndices == nConvTextLen,
490 : : "mismatch between string length and sequence length!" );
491 : :
492 : : // find all substrings that need to be replaced (and only those)
493 : 0 : while (sal_True)
494 : : {
495 : : // get index in original text that matches nPos in new text
496 : : xub_StrLen nIndex;
497 [ # # ]: 0 : if (nPos < nConvTextLen)
498 [ # # ]: 0 : nIndex = (sal_Int32) nPos < nIndices ? (xub_StrLen) pIndices[nPos] : nPos;
499 : : else
500 : : {
501 : 0 : nPos = nConvTextLen;
502 : 0 : nIndex = static_cast< xub_StrLen >( rOrigText.getLength() );
503 : : }
504 : :
505 [ # # ][ # # ]: 0 : if (rOrigText.getStr()[nIndex] == rNewText.GetChar(nPos) ||
[ # # ]
506 : : nPos == nConvTextLen /* end of string also terminates non-matching char sequence */)
507 : : {
508 : : // substring that needs to be replaced found?
509 [ # # ][ # # ]: 0 : if (nChgPos != STRING_NOTFOUND && nConvChgPos != STRING_NOTFOUND)
510 : : {
511 : 0 : nChgLen = nIndex - nChgPos;
512 : 0 : nConvChgLen = nPos - nConvChgPos;
513 : : #ifdef DEBUG
514 : : String aInOrig( rOrigText.copy( nChgPos, nChgLen ) );
515 : : #endif
516 [ # # ]: 0 : String aInNew( rNewText.Copy( nConvChgPos, nConvChgLen ) );
517 : :
518 : : // set selection to sub string to be replaced in original text
519 : 0 : ESelection aSel( *pESelection );
520 : 0 : xub_StrLen nChgInNodeStartIndex = static_cast< xub_StrLen >( nStartIndex + nCorrectionOffset + nChgPos );
521 : 0 : aSel.nStartPos = nChgInNodeStartIndex;
522 : 0 : aSel.nEndPos = nChgInNodeStartIndex + nChgLen;
523 [ # # ]: 0 : pEditView->SetSelection( aSel );
524 : : #ifdef DEBUG
525 : : String aSelTxt1( pEditView->GetSelected() );
526 : : #endif
527 : :
528 : : // replace selected sub string with the corresponding
529 : : // sub string from the new text while keeping as
530 : : // much from the attributes as possible
531 [ # # ]: 0 : ChangeText_impl( aInNew, sal_True );
532 : :
533 : 0 : nCorrectionOffset += nConvChgLen - nChgLen;
534 : :
535 : 0 : nChgPos = STRING_NOTFOUND;
536 [ # # ]: 0 : nConvChgPos = STRING_NOTFOUND;
537 : : }
538 : : }
539 : : else
540 : : {
541 : : // begin of non-matching char sequence found ?
542 [ # # ][ # # ]: 0 : if (nChgPos == STRING_NOTFOUND && nConvChgPos == STRING_NOTFOUND)
543 : : {
544 : 0 : nChgPos = nIndex;
545 : 0 : nConvChgPos = nPos;
546 : : }
547 : : }
548 [ # # ]: 0 : if (nPos >= nConvTextLen)
549 : 0 : break;
550 : 0 : ++nPos;
551 : : }
552 : :
553 : : // set cursor to the end of the inserted text
554 : : // (as it would happen after ChangeText_impl (Delete and Insert)
555 : : // of the whole text in the 'else' branch below)
556 : 0 : pESelection->nStartPos = pESelection->nEndPos = nStartIndex + nConvTextLen;
557 : : }
558 : : else
559 : : {
560 : 0 : ChangeText_impl( rNewText, sal_False );
561 : : }
562 : : }
563 : :
564 : :
565 : 0 : void TextConvWrapper::ChangeText_impl( const String &rNewText, sal_Bool bKeepAttributes )
566 : : {
567 [ # # ]: 0 : if (bKeepAttributes)
568 : : {
569 : : // save attributes to be restored
570 [ # # ]: 0 : SfxItemSet aSet( pEditView->GetAttribs() );
571 : :
572 : : #ifdef DEBUG
573 : : String aSelTxt1( pEditView->GetSelected() );
574 : : #endif
575 : : // replace old text and select new text
576 [ # # ]: 0 : pEditView->InsertText( rNewText, sal_True );
577 : : #ifdef DEBUG
578 : : String aSelTxt2( pEditView->GetSelected() );
579 : : #endif
580 : :
581 : : // since 'SetAttribs' below function like merging with the attributes
582 : : // from the itemset with any existing ones we have to get rid of all
583 : : // all attributes now. (Those attributes that may take effect left
584 : : // to the position where the new text gets inserted after the old text
585 : : // was deleted)
586 [ # # ]: 0 : pEditView->RemoveAttribs();
587 : : // apply saved attributes to new inserted text
588 [ # # ][ # # ]: 0 : pEditView->SetAttribs( aSet );
589 : : }
590 : : else
591 : : {
592 : 0 : pEditView->InsertText( rNewText );
593 : : }
594 : 0 : }
595 : :
596 : :
597 : 0 : void TextConvWrapper::Convert()
598 : : {
599 : 0 : bStartChk = sal_False;
600 : 0 : ConvStart_impl( SVX_SPELL_BODY_END );
601 : 0 : ConvertDocument();
602 : 0 : ConvEnd_impl();
603 : 0 : }
604 : :
605 : :
606 : 0 : sal_Bool TextConvWrapper::HasRubySupport() const
607 : : {
608 : 0 : return sal_False;
609 : : }
610 : :
611 : : //////////////////////////////////////////////////////////////////////
612 : :
613 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|