/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
if ( eArea == SvxSpellArea::BodyStart )
{ // Is called when Spell-forward has reached the end, and to start over if ( m_bEndDone )
{
pConvInfo->bConvToEnd = false;
pConvInfo->aConvTo = pConvInfo->aConvStart;
pConvInfo->aConvContinue = EPaM( 0, 0 );
m_pEditView->getImpl().SetEditSelection(
rEditEngine.GetEditDoc().GetStartPaM() );
} else
{
pConvInfo->bConvToEnd = true;
pConvInfo->aConvTo = rImpEditEngine.CreateEPaM(rEditEngine.GetEditDoc().GetStartPaM() );
}
} elseif ( eArea == SvxSpellArea::BodyEnd )
{ // Is called when Spell-forward starts
pConvInfo->bConvToEnd = true; if (m_aConvSel.HasRange())
{ // user selection: convert to end of selection
pConvInfo->aConvTo = m_aConvSel.end;
pConvInfo->bConvToEnd = false;
} else
{ // nothing selected: convert to end of document
pConvInfo->aConvTo = rImpEditEngine.CreateEPaM(rEditEngine.GetEditDoc().GetEndPaM() );
}
} elseif ( eArea == SvxSpellArea::Body )
{ // called by ConvNext_impl...
pConvInfo->aConvContinue = pConvInfo->aConvStart;
pConvInfo->aConvTo = rImpEditEngine.CreateEPaM(rEditEngine.GetEditDoc().GetEndPaM() );
} else
{
OSL_FAIL( "ConvStart_impl: Unknown Area!" );
}
}
bool TextConvWrapper::ConvContinue_impl()
{ // modified version of EditSpellWrapper::SpellContinue
// get next convertible text portion and its language
m_aConvText.clear();
m_nConvTextLang = LANGUAGE_NONE;
m_pEditView->getImpEditEngine().ImpConvert( m_aConvText, m_nConvTextLang,
m_pEditView, GetSourceLanguage(), m_aConvSel,
m_bAllowChange, GetTargetLanguage(), GetTargetFont() ); return !m_aConvText.isEmpty();
}
// set new language attribute
SfxItemSet aNewSet( m_pEditView->GetEmptyItemSet() );
aNewSet.Put( SvxLanguageItem( nLang, nLangWhichId ) );
// new font to be set?
DBG_ASSERT( pFont, "target font missing?" ); if (pFont)
{ // set new font attribute
SvxFontItem aFontItem = static_cast<const SvxFontItem&>( aNewSet.Get( nFontWhichId ) );
aFontItem.SetFamilyName( pFont->GetFamilyName());
aFontItem.SetFamily( pFont->GetFamilyType());
aFontItem.SetStyleName( pFont->GetStyleName());
aFontItem.SetPitch( pFont->GetPitch());
aFontItem.SetCharSet(pFont->GetCharSet());
aNewSet.Put( aFontItem );
}
// apply new attributes
m_pEditView->SetAttribs( aNewSet );
// select current unit
SelectNewUnit_impl( nUnitStart, nUnitEnd );
OUString aOrigTxt( m_pEditView->GetSelected() );
OUString aNewTxt( rReplaceWith ); switch (eAction)
{ case eExchange : break; case eReplacementBracketed :
aNewTxt = aOrigTxt + "(" + rReplaceWith + ")"; break; case eOriginalBracketed :
aNewTxt = rReplaceWith + "(" + aOrigTxt + ")"; break; case eReplacementAbove : case eOriginalAbove : case eReplacementBelow : case eOriginalBelow :
OSL_FAIL( "Rubies not supported" ); break; default:
OSL_FAIL( "unexpected case" );
}
m_nUnitOffset = m_nUnitOffset + nUnitStart + aNewTxt.getLength();
// remember current original language for later use
EditEngine& rEditEngine = m_pEditView->getEditEngine();
ESelection aOldSel = m_pEditView->GetSelection(); //EditSelection aOldEditSel = pEditView->getImpl().GetEditSelection();
// according to FT we should currently not bother about keeping // attributes in Hangul/Hanja conversion and leave that untouched. // Thus we do this only for Chinese translation... bool bIsChineseConversion = IsChinese( GetSourceLanguage() ); if (bIsChineseConversion)
ChangeText( aNewTxt, rOrigText, &rOffsets, &aOldSel ); else
ChangeText( aNewTxt, rOrigText, nullptr, nullptr );
// change language and font if necessary if (bIsChineseConversion)
{
DBG_ASSERT( GetTargetLanguage() == LANGUAGE_CHINESE_SIMPLIFIED || GetTargetLanguage() == LANGUAGE_CHINESE_TRADITIONAL, "TextConvWrapper::ReplaceUnit : unexpected target language" );
if (pNewUnitLanguage)
{ #ifdef DBG_UTIL
DBG_ASSERT(!IsSimilarChinese( *pNewUnitLanguage, nOldLang ), "similar language should not be changed!"); #endif
SetLanguageAndFont( aNewSel, *pNewUnitLanguage, EE_CHAR_LANGUAGE_CJK,
GetTargetFont(), EE_CHAR_FONTINFO_CJK );
}
}
rEditEngine.UndoActionEnd();
// adjust ConvContinue / ConvTo if necessary
ConvInfo* pConvInfo = rEditEngine.getImpl().GetConvInfo();
sal_Int32 nDelta = aNewTxt.getLength() - aOrigTxt.getLength(); if (nDelta != 0)
{ // Note: replacement is always done in the current paragraph // which is the one ConvContinue points to
pConvInfo->aConvContinue.nIndex = pConvInfo->aConvContinue.nIndex + nDelta;
// if that is the same as the one where the conversions ends // the end needs to be updated also if (pConvInfo->aConvTo.nPara == pConvInfo->aConvContinue.nPara)
pConvInfo->aConvTo.nIndex = pConvInfo->aConvTo.nIndex + nDelta;
}
}
void TextConvWrapper::ChangeText( const OUString &rNewText,
std::u16string_view rOrigText, const uno::Sequence< sal_Int32 > *pOffsets,
ESelection *pESelection )
{ //!! code is a modified copy of SwHHCWrapper::ChangeText from sw !!
DBG_ASSERT( !rNewText.isEmpty(), "unexpected empty string" ); if (rNewText.isEmpty()) return;
if (pOffsets && pESelection) // try to keep as much attributation as possible ?
{
pESelection->Adjust();
// remember cursor start position for later setting of the cursor const sal_Int32 nStartIndex = pESelection->start.nIndex;
// offset to calculate the position in the text taking into // account that text may have been replaced with new text of // different length. Negative values allowed!
sal_Int32 nCorrectionOffset = 0;
DBG_ASSERT(nIndices == 0 || nIndices == nConvTextLen, "mismatch between string length and sequence length!" );
// find all substrings that need to be replaced (and only those) while (true)
{ // get index in original text that matches nPos in new text
sal_Int32 nIndex; if (nPos < nConvTextLen)
nIndex = nPos < nIndices ? pIndices[nPos] : nPos; else
{
nPos = nConvTextLen;
nIndex = rOrigText.size();
}
// end of string also terminates non-matching char sequence if (nPos == nConvTextLen || rOrigText[nIndex] == rNewText[nPos])
{ // substring that needs to be replaced found? if (nChgPos>=0 && nConvChgPos>=0)
{ const sal_Int32 nChgLen = nIndex - nChgPos; const sal_Int32 nConvChgLen = nPos - nConvChgPos;
OUString aInNew( rNewText.copy( nConvChgPos, nConvChgLen ) );
// set selection to sub string to be replaced in original text
ESelection aSel( *pESelection );
sal_Int32 nChgInNodeStartIndex = nStartIndex + nCorrectionOffset + nChgPos;
aSel.start.nIndex = nChgInNodeStartIndex;
aSel.end.nIndex = nChgInNodeStartIndex + nChgLen;
m_pEditView->SetSelection( aSel );
// replace selected sub string with the corresponding // sub string from the new text while keeping as // much from the attributes as possible
ChangeText_impl( aInNew, true );
nCorrectionOffset += nConvChgLen - nChgLen;
nChgPos = -1;
nConvChgPos = -1;
}
} else
{ // begin of non-matching char sequence found ? if (nChgPos<0 && nConvChgPos<0)
{
nChgPos = nIndex;
nConvChgPos = nPos;
}
} if (nPos >= nConvTextLen) break;
++nPos;
}
// set cursor to the end of the inserted text // (as it would happen after ChangeText_impl (Delete and Insert) // of the whole text in the 'else' branch below)
pESelection->start.nIndex = pESelection->end.nIndex = nStartIndex + nConvTextLen;
} else
{
ChangeText_impl( rNewText, false );
}
}
void TextConvWrapper::ChangeText_impl( const OUString &rNewText, bool bKeepAttributes )
{ if (bKeepAttributes)
{ // save attributes to be restored
SfxItemSet aSet( m_pEditView->GetAttribs() );
// replace old text and select new text
m_pEditView->InsertText( rNewText, true );
// since 'SetAttribs' below function like merging with the attributes // from the itemset with any existing ones we have to get rid of all // all attributes now. (Those attributes that may take effect left // to the position where the new text gets inserted after the old text // was deleted)
m_pEditView->RemoveAttribs(EERemoveParaAttribsMode::RemoveNone, 0); // apply saved attributes to new inserted text
m_pEditView->SetAttribs( aSet );
} else
{
m_pEditView->InsertText( rNewText );
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.