summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei@libreoffice.org>2022-05-06 19:37:14 -0400
committerKohei Yoshida <kohei@libreoffice.org>2022-05-07 04:52:50 +0200
commitf15e6293cf78d67963a6e512f60a11ae58da72c5 (patch)
tree777fd99553c788309747c539a0d5f49565bd2225
parent431c692e4e58a4861e4ab7b4d30b1edf0aab0496 (diff)
tdf#107765: Check the updated language and apply it to the cell.
During the normal spell-checking in Calc, the user may change the language on the string segment with a spelling error, which is supposed to be applied back to that segment in the cell, but was not. This change should fix it. In case the new language is applied to the entire cell string, we will set the new lanuage to the cell as a cell attribute and keep the string as a simple string. Otherwise, the new language gets applied to the edit engine string. This commit also changes the return value of EditEngine::GetLanguage() to include the string span information in addition to the language value. Change-Id: I713ec7aefe571f721321cd8ea687f616ab4dd61a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133966 Tested-by: Jenkins Reviewed-by: Kohei Yoshida <kohei@libreoffice.org>
-rw-r--r--editeng/source/editeng/editeng.cxx8
-rw-r--r--editeng/source/editeng/editview.cxx6
-rw-r--r--editeng/source/editeng/edtspell.cxx4
-rw-r--r--editeng/source/editeng/impedit.hxx2
-rw-r--r--editeng/source/editeng/impedit3.cxx4
-rw-r--r--editeng/source/editeng/impedit4.cxx43
-rw-r--r--editeng/source/editeng/textconv.cxx2
-rw-r--r--editeng/source/outliner/outlin2.cxx2
-rw-r--r--editeng/source/outliner/outlvw.cxx2
-rw-r--r--editeng/source/uno/unofored.cxx2
-rw-r--r--include/editeng/editdata.hxx13
-rw-r--r--include/editeng/editeng.hxx4
-rw-r--r--sc/source/ui/view/spelleng.cxx29
-rw-r--r--svx/source/dialog/weldeditview.cxx2
14 files changed, 86 insertions, 37 deletions
diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
index 4e87300fd006..5869bcdeeeb4 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -478,16 +478,16 @@ SvtScriptType EditEngine::GetScriptType( const ESelection& rSelection ) const
return pImpEditEngine->GetItemScriptType( aSel );
}
-LanguageType EditEngine::GetLanguage(const EditPaM& rPaM) const
+editeng::LanguageSpan EditEngine::GetLanguage(const EditPaM& rPaM) const
{
return pImpEditEngine->GetLanguage(rPaM);
}
-LanguageType EditEngine::GetLanguage( sal_Int32 nPara, sal_Int32 nPos ) const
+editeng::LanguageSpan EditEngine::GetLanguage( sal_Int32 nPara, sal_Int32 nPos ) const
{
ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( nPara );
DBG_ASSERT( pNode, "GetLanguage - nPara is invalid!" );
- return pNode ? pImpEditEngine->GetLanguage( EditPaM( pNode, nPos ) ) : LANGUAGE_DONTKNOW;
+ return pNode ? pImpEditEngine->GetLanguage( EditPaM( pNode, nPos ) ) : editeng::LanguageSpan{};
}
@@ -1328,7 +1328,7 @@ bool EditEngine::PostKeyEvent( const KeyEvent& rKeyEvent, EditView* pEditView, v
{
OUString aComplete;
- LanguageType eLang = pImpEditEngine->GetLanguage( EditPaM( aStart.GetNode(), aStart.GetIndex()+1));
+ LanguageType eLang = pImpEditEngine->GetLanguage( EditPaM( aStart.GetNode(), aStart.GetIndex()+1)).nLang;
LanguageTag aLanguageTag( eLang);
if (!pImpEditEngine->xLocaleDataWrapper.isInitialized())
diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx
index 8f199b79ea89..320fd52eab8c 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -1022,7 +1022,7 @@ bool EditView::ExecuteSpellPopup(const Point& rPosPixel, const Link<SpellCallbac
// Are there any replace suggestions?
Reference< linguistic2::XSpellAlternatives > xSpellAlt =
- xSpeller->spell( aSelected, static_cast<sal_uInt16>(pImpEditView->pEditEngine->pImpEditEngine->GetLanguage( aPaM2 )), aPropVals );
+ xSpeller->spell( aSelected, static_cast<sal_uInt16>(pImpEditView->pEditEngine->pImpEditEngine->GetLanguage( aPaM2 ).nLang), aPropVals );
Reference< linguistic2::XLanguageGuessing > xLangGuesser( EditDLL::Get().GetGlobalData()->GetLanguageGuesser() );
@@ -1102,7 +1102,7 @@ bool EditView::ExecuteSpellPopup(const Point& rPosPixel, const Link<SpellCallbac
aDics = xDicList->getDictionaries();
pDic = aDics.getConstArray();
- LanguageType nCheckedLanguage = pImpEditView->pEditEngine->pImpEditEngine->GetLanguage( aPaM2 );
+ LanguageType nCheckedLanguage = pImpEditView->pEditEngine->pImpEditEngine->GetLanguage( aPaM2 ).nLang;
sal_uInt16 nDicCount = static_cast<sal_uInt16>(aDics.getLength());
for (sal_uInt16 i = 0; i < nDicCount; i++)
{
@@ -1254,7 +1254,7 @@ bool EditView::ExecuteSpellPopup(const Point& rPosPixel, const Link<SpellCallbac
OUString aWord = pAlt[sId.toInt32() - MN_AUTOSTART];
SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
if ( pAutoCorrect )
- pAutoCorrect->PutText( aSelected, aWord, pImpEditView->pEditEngine->pImpEditEngine->GetLanguage( aPaM2 ) );
+ pAutoCorrect->PutText( aSelected, aWord, pImpEditView->pEditEngine->pImpEditEngine->GetLanguage( aPaM2 ).nLang );
InsertText( aWord );
}
else if ( sId.toInt32() >= MN_ALTSTART ) // Replace
diff --git a/editeng/source/editeng/edtspell.cxx b/editeng/source/editeng/edtspell.cxx
index 5ff6beb29b8f..c07361bd196b 100644
--- a/editeng/source/editeng/edtspell.cxx
+++ b/editeng/source/editeng/edtspell.cxx
@@ -654,7 +654,7 @@ bool EdtAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos,
if( aShort.isEmpty() )
return bRet;
- LanguageTag aLanguageTag( mpEditEngine->GetLanguage( EditPaM( pCurNode, rSttPos+1 ) ));
+ LanguageTag aLanguageTag( mpEditEngine->GetLanguage( EditPaM( pCurNode, rSttPos+1 ) ).nLang );
const SvxAutocorrWord* pFnd = rACorrect.SearchWordsInList(
pCurNode->GetString(), rSttPos, nEndPos, *this, aLanguageTag);
if( pFnd && pFnd->IsTextOnly() )
@@ -693,7 +693,7 @@ bool EdtAutoCorrDoc::TransliterateRTLWord( sal_Int32& /*rSttPos*/,
LanguageType EdtAutoCorrDoc::GetLanguage( sal_Int32 nPos ) const
{
- return mpEditEngine->GetLanguage( EditPaM( pCurNode, nPos+1 ) );
+ return mpEditEngine->GetLanguage( EditPaM( pCurNode, nPos+1 ) ).nLang;
}
void EdtAutoCorrDoc::ImplStartUndoAction()
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index 4a0134b785ba..11993511372d 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -1017,7 +1017,7 @@ public:
void SetDefaultLanguage( LanguageType eLang ) { eDefLanguage = eLang; }
LanguageType GetDefaultLanguage() const { return eDefLanguage; }
- LanguageType GetLanguage( const EditPaM& rPaM, sal_Int32* pEndPos = nullptr ) const;
+ editeng::LanguageSpan GetLanguage( const EditPaM& rPaM, sal_Int32* pEndPos = nullptr ) const;
css::lang::Locale GetLocale( const EditPaM& rPaM ) const;
void DoOnlineSpelling( ContentNode* pThisNodeOnly = nullptr, bool bSpellAtCursorPos = false, bool bInterruptible = true );
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index 83eb93066baf..34caef587297 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -2116,7 +2116,7 @@ void ImpEditEngine::ImpAdjustBlocks( ParaPortion* pParaPortion, EditLine* pLine,
for ( sal_Int32 nChar = nFirstChar; nChar <= nLastChar; nChar++ )
{
EditPaM aPaM( pNode, nChar+1 );
- LanguageType eLang = GetLanguage(aPaM);
+ LanguageType eLang = GetLanguage(aPaM).nLang;
sal_uInt16 nScript = GetI18NScriptType(aPaM);
if ( MsLangId::getPrimaryLanguage( eLang) == LANGUAGE_ARABIC_PRIMARY_ONLY )
// Arabic script is handled later.
@@ -2155,7 +2155,7 @@ void ImpEditEngine::ImpAdjustBlocks( ParaPortion* pParaPortion, EditLine* pLine,
// The width must be distributed to the blockers in front...
// But not if it is the only one.
if ( ( pNode->GetChar( nLastChar ) == ' ' ) && ( aPositions.size() > 1 ) &&
- ( MsLangId::getPrimaryLanguage( GetLanguage( EditPaM( pNode, nLastChar ) ) ) != LANGUAGE_ARABIC_PRIMARY_ONLY ) )
+ ( MsLangId::getPrimaryLanguage( GetLanguage( EditPaM( pNode, nLastChar ) ).nLang ) != LANGUAGE_ARABIC_PRIMARY_ONLY ) )
{
aPositions.pop_back();
sal_Int32 nPortionStart, nPortion;
diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx
index f8b2c3767ce8..03b8d511e5c3 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -1377,25 +1377,34 @@ void ImpEditEngine::SetAllMisspellRanges( const std::vector<editeng::MisspellRan
}
}
-LanguageType ImpEditEngine::GetLanguage( const EditPaM& rPaM, sal_Int32* pEndPos ) const
+editeng::LanguageSpan ImpEditEngine::GetLanguage( const EditPaM& rPaM, sal_Int32* pEndPos ) const
{
short nScriptTypeI18N = GetI18NScriptType( rPaM, pEndPos ); // pEndPos will be valid now, pointing to ScriptChange or NodeLen
SvtScriptType nScriptType = SvtLanguageOptions::FromI18NToSvtScriptType(nScriptTypeI18N);
sal_uInt16 nLangId = GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType );
const SvxLanguageItem* pLangItem = &static_cast<const SvxLanguageItem&>(rPaM.GetNode()->GetContentAttribs().GetItem( nLangId ));
const EditCharAttrib* pAttr = rPaM.GetNode()->GetCharAttribs().FindAttrib( nLangId, rPaM.GetIndex() );
+
+ editeng::LanguageSpan aLang;
+
if ( pAttr )
+ {
pLangItem = static_cast<const SvxLanguageItem*>(pAttr->GetItem());
+ aLang.nStart = pAttr->GetStart();
+ aLang.nEnd = pAttr->GetEnd();
+ }
if ( pEndPos && pAttr && ( pAttr->GetEnd() < *pEndPos ) )
*pEndPos = pAttr->GetEnd();
- return pLangItem->GetLanguage();
+ aLang.nLang = pLangItem->GetLanguage();
+
+ return aLang;
}
css::lang::Locale ImpEditEngine::GetLocale( const EditPaM& rPaM ) const
{
- return LanguageTag( GetLanguage( rPaM ) ).getLocale();
+ return LanguageTag( GetLanguage( rPaM ).nLang ).getLocale();
}
Reference< XSpellChecker1 > const & ImpEditEngine::GetSpeller()
@@ -1486,7 +1495,7 @@ bool ImpEditEngine::HasConvertibleTextPortion( LanguageType nSrcLang )
// specified position is evaluated.
if (nEnd > nStart) // empty para?
++nStart;
- LanguageType nLangFound = pEditEngine->GetLanguage( k, nStart );
+ LanguageType nLangFound = pEditEngine->GetLanguage( k, nStart ).nLang;
#ifdef DEBUG
lang::Locale aLocale( LanguageTag::convertToLocale( nLangFound ) );
#endif
@@ -1671,7 +1680,7 @@ void ImpEditEngine::ImpConvert( OUString &rConvTxt, LanguageType &rConvTxtLang,
// thus we usually have to add 1 in order to get the language
// of the text right to the cursor position
const sal_Int32 nLangIdx = nEnd > nStart ? nStart + 1 : nStart;
- LanguageType nLangFound = pEditEngine->GetLanguage( aCurStart.nPara, nLangIdx );
+ LanguageType nLangFound = pEditEngine->GetLanguage( aCurStart.nPara, nLangIdx ).nLang;
#ifdef DEBUG
lang::Locale aLocale( LanguageTag::convertToLocale( nLangFound ) );
#endif
@@ -1834,7 +1843,7 @@ Reference< XSpellAlternatives > ImpEditEngine::ImpSpell( EditView* pEditView )
if ( !aWord.isEmpty() )
{
- LanguageType eLang = GetLanguage( aCurSel.Max() );
+ LanguageType eLang = GetLanguage( aCurSel.Max() ).nLang;
SvxSpellWrapper::CheckSpellLang( xSpeller, eLang );
xSpellAlt = xSpeller->spell( aWord, static_cast<sal_uInt16>(eLang), aEmptySeq );
}
@@ -1883,7 +1892,7 @@ Reference< XSpellAlternatives > ImpEditEngine::ImpFindNextError(EditSelection& r
}
if ( !aWord.isEmpty() )
- xSpellAlt = xSpeller->spell( aWord, static_cast<sal_uInt16>(GetLanguage( aCurSel.Max() )), aEmptySeq );
+ xSpellAlt = xSpeller->spell( aWord, static_cast<sal_uInt16>(GetLanguage( aCurSel.Max() ).nLang), aEmptySeq );
if ( !xSpellAlt.is() )
aCurSel = WordRight( aCurSel.Min(), css::i18n::WordType::DICTIONARY_WORD );
@@ -1967,7 +1976,7 @@ void ImpEditEngine::AddPortion(
svx::SpellPortion aPortion;
aPortion.sText = GetSelected( rSel );
- aPortion.eLanguage = GetLanguage( rSel.Min() );
+ aPortion.eLanguage = GetLanguage( rSel.Min() ).nLang;
aPortion.xAlternatives = xAlt;
aPortion.bIsField = bIsField;
rToFill.push_back(aPortion);
@@ -2002,7 +2011,7 @@ void ImpEditEngine::AddPortionIterated(
//set the mark equal to the point
EditPaM aCursor(aStart);
rEditView.pImpEditView->SetEditSelection( aCursor );
- LanguageType eStartLanguage = GetLanguage( aCursor );
+ LanguageType eStartLanguage = GetLanguage( aCursor ).nLang;
//search for a field attribute at the beginning - only the end position
//of this field is kept to end a portion at that position
const EditCharAttrib* pFieldAttr = aCursor.GetNode()->GetCharAttribs().
@@ -2028,7 +2037,7 @@ void ImpEditEngine::AddPortionIterated(
if (bIsField)
nEndField = _pFieldAttr->GetEnd();
- LanguageType eCurLanguage = GetLanguage( aCursor );
+ LanguageType eCurLanguage = GetLanguage( aCursor ).nLang;
if(eCurLanguage != eStartLanguage || bIsField || bIsEndField)
{
eStartLanguage = eCurLanguage;
@@ -2130,7 +2139,7 @@ void ImpEditEngine::ApplyChangedSentence(EditView const & rEditView,
for(const auto& rCurrentNewPortion : rNewPortions)
{
//set the language attribute
- LanguageType eCurLanguage = GetLanguage( aCurrentPaM );
+ LanguageType eCurLanguage = GetLanguage( aCurrentPaM ).nLang;
if(eCurLanguage != rCurrentNewPortion.eLanguage)
{
SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( rCurrentNewPortion.eLanguage );
@@ -2254,7 +2263,7 @@ void ImpEditEngine::DoOnlineSpelling( ContentNode* pThisNodeOnly, bool bSpellAtC
{
const sal_Int32 nWStart = aSel.Min().GetIndex();
const sal_Int32 nWEnd = aSel.Max().GetIndex();
- if ( !xSpeller->isValid( aWord, static_cast<sal_uInt16>(GetLanguage( EditPaM( aSel.Min().GetNode(), nWStart+1 ) )), aEmptySeq ) )
+ if ( !xSpeller->isValid( aWord, static_cast<sal_uInt16>(GetLanguage( EditPaM( aSel.Min().GetNode(), nWStart+1 ) ).nLang), aEmptySeq ) )
{
// Check if already marked correctly...
const sal_Int32 nXEnd = bDottAdded ? nWEnd -1 : nWEnd;
@@ -2400,7 +2409,7 @@ EESpellState ImpEditEngine::HasSpellErrors()
aWord = GetSelected( aCurSel );
if ( !aWord.isEmpty() )
{
- LanguageType eLang = GetLanguage( aCurSel.Max() );
+ LanguageType eLang = GetLanguage( aCurSel.Max() ).nLang;
SvxSpellWrapper::CheckSpellLang( xSpeller, eLang );
xSpellAlt = xSpeller->spell( aWord, static_cast<sal_uInt16>(eLang), aEmptySeq );
}
@@ -2428,7 +2437,7 @@ EESpellState ImpEditEngine::StartThesaurus(EditView* pEditView, weld::Widget* pD
EditAbstractDialogFactory* pFact = EditAbstractDialogFactory::Create();
ScopedVclPtr<AbstractThesaurusDialog> xDlg(pFact->CreateThesaurusDialog(pDialogParent, xThes,
- aWord, GetLanguage( aCurSel.Max() ) ));
+ aWord, GetLanguage( aCurSel.Max() ).nLang ));
if (xDlg->Execute() == RET_OK)
{
// Replace Word...
@@ -2759,7 +2768,7 @@ EditSelection ImpEditEngine::TransliterateText( const EditSelection& rSelection,
Sequence< sal_Int32 > aOffsets;
OUString aNewText( aTransliterationWrapper.transliterate(aNodeStr,
- GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ),
+ GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ).nLang,
nCurrentStart, nLen, &aOffsets ));
if (aNodeStr != aNewText)
@@ -2850,7 +2859,7 @@ EditSelection ImpEditEngine::TransliterateText( const EditSelection& rSelection,
Sequence< sal_Int32 > aOffsets;
OUString aNewText( aTransliterationWrapper.transliterate( aNodeStr,
- GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ),
+ GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ).nLang,
nCurrentStart, nLen, &aOffsets ));
if (aNodeStr != aNewText)
@@ -2880,7 +2889,7 @@ EditSelection ImpEditEngine::TransliterateText( const EditSelection& rSelection,
{
if ( bConsiderLanguage )
{
- nLanguage = GetLanguage( EditPaM( pNode, nCurrentStart+1 ), &nCurrentEnd );
+ nLanguage = GetLanguage( EditPaM( pNode, nCurrentStart+1 ), &nCurrentEnd ).nLang;
if ( nCurrentEnd > nEndPos )
nCurrentEnd = nEndPos;
}
diff --git a/editeng/source/editeng/textconv.cxx b/editeng/source/editeng/textconv.cxx
index 7c4ed9ddd89d..a4d5386ea18e 100644
--- a/editeng/source/editeng/textconv.cxx
+++ b/editeng/source/editeng/textconv.cxx
@@ -346,7 +346,7 @@ void TextConvWrapper::ReplaceUnit(
//EditSelection aOldEditSel = pEditView->GetImpEditView()->GetEditSelection();
#ifdef DBG_UTIL
- LanguageType nOldLang = pImpEditEng->GetLanguage( pImpEditEng->CreateSel( aOldSel ).Min() );
+ LanguageType nOldLang = pImpEditEng->GetLanguage( pImpEditEng->CreateSel( aOldSel ).Min() ).nLang;
#endif
pImpEditEng->UndoActionStart( EDITUNDO_INSERT );
diff --git a/editeng/source/outliner/outlin2.cxx b/editeng/source/outliner/outlin2.cxx
index 3d4061a82cde..951f6923563f 100644
--- a/editeng/source/outliner/outlin2.cxx
+++ b/editeng/source/outliner/outlin2.cxx
@@ -559,7 +559,7 @@ EEHorizontalTextDirection Outliner::GetDefaultHorizontalTextDirection() const
LanguageType Outliner::GetLanguage( sal_Int32 nPara, sal_Int32 nPos ) const
{
- return pEditEngine->GetLanguage( nPara, nPos );
+ return pEditEngine->GetLanguage( nPara, nPos ).nLang;
}
void Outliner::RemoveAttribs( const ESelection& rSelection, bool bRemoveParaAttribs, sal_uInt16 nWhich )
diff --git a/editeng/source/outliner/outlvw.cxx b/editeng/source/outliner/outlvw.cxx
index e4b8fd5e80f3..d5f426abbf53 100644
--- a/editeng/source/outliner/outlvw.cxx
+++ b/editeng/source/outliner/outlvw.cxx
@@ -1471,7 +1471,7 @@ bool GetStatusValueForThesaurusFromContext(
if (!isSingleScriptType(pEditEngine->GetScriptType(aTextSel)))
return false;
- LanguageType nLang = pEditEngine->GetLanguage( aTextSel.nStartPara, aTextSel.nStartPos );
+ LanguageType nLang = pEditEngine->GetLanguage( aTextSel.nStartPara, aTextSel.nStartPos ).nLang;
OUString aLangText( LanguageTag::convertToBcp47( nLang ) );
// set word and locale to look up as status value
diff --git a/editeng/source/uno/unofored.cxx b/editeng/source/uno/unofored.cxx
index 49eb5368e7a3..425e07bb8206 100644
--- a/editeng/source/uno/unofored.cxx
+++ b/editeng/source/uno/unofored.cxx
@@ -267,7 +267,7 @@ SfxItemState SvxEditEngineForwarder::GetItemState( sal_Int32 nPara, sal_uInt16 n
LanguageType SvxEditEngineForwarder::GetLanguage( sal_Int32 nPara, sal_Int32 nIndex ) const
{
- return rEditEngine.GetLanguage(nPara, nIndex);
+ return rEditEngine.GetLanguage(nPara, nIndex).nLang;
}
sal_Int32 SvxEditEngineForwarder::GetFieldCount( sal_Int32 nPara ) const
diff --git a/include/editeng/editdata.hxx b/include/editeng/editdata.hxx
index 8366b022e9b8..1762fd86e837 100644
--- a/include/editeng/editdata.hxx
+++ b/include/editeng/editdata.hxx
@@ -23,6 +23,7 @@
#include <rtl/ustring.hxx>
#include <editeng/editengdllapi.h>
+#include <i18nlangtag/lang.h>
#include <memory>
#include <ostream>
@@ -341,6 +342,18 @@ struct EENotify
{ eNotificationType = eType; nParagraph = EE_PARA_NOT_FOUND; nParam1 = 0; nParam2 = 0; }
};
+namespace editeng
+{
+
+struct LanguageSpan
+{
+ LanguageType nLang = LANGUAGE_DONTKNOW;
+ sal_Int32 nStart = -1;
+ sal_Int32 nEnd = -1;
+};
+
+}
+
#endif // INCLUDED_EDITENG_EDITDATA_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index 9bce76b98031..a0ce29ca26d1 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -253,8 +253,8 @@ public:
EEHorizontalTextDirection GetDefaultHorizontalTextDirection() const;
SvtScriptType GetScriptType( const ESelection& rSelection ) const;
- LanguageType GetLanguage(const EditPaM& rPaM) const;
- LanguageType GetLanguage( sal_Int32 nPara, sal_Int32 nPos ) const;
+ editeng::LanguageSpan GetLanguage(const EditPaM& rPaM) const;
+ editeng::LanguageSpan GetLanguage( sal_Int32 nPara, sal_Int32 nPos ) const;
void TransliterateText( const ESelection& rSelection, TransliterationFlags nTransliterationMode );
EditSelection TransliterateText( const EditSelection& rSelection, TransliterationFlags nTransliterationMode );
diff --git a/sc/source/ui/view/spelleng.cxx b/sc/source/ui/view/spelleng.cxx
index 1f6f649f0464..615960ff0703 100644
--- a/sc/source/ui/view/spelleng.cxx
+++ b/sc/source/ui/view/spelleng.cxx
@@ -25,6 +25,7 @@
#include <editeng/langitem.hxx>
#include <editeng/editobj.hxx>
#include <editeng/editview.hxx>
+#include <editeng/eeitem.hxx>
#include <sfx2/viewfrm.hxx>
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>
@@ -40,6 +41,7 @@
#include <globstr.hrc>
#include <scresid.hxx>
#include <markdata.hxx>
+#include <docpool.hxx>
#include <memory>
@@ -91,7 +93,18 @@ bool ScConversionEngineBase::FindNextConversionCell()
OUString aNewStr = GetText();
+ // Check if the user has changed the language. If the new language is
+ // applied to the entire string length, we will set the language as cell
+ // attribute. Otherwise we will commit this as an edit-engine string.
+ editeng::LanguageSpan aLang = GetLanguage(0, 0);
+
+ bool bSimpleString = GetParagraphCount() == 1 &&
+ aLang.nLang != LANGUAGE_DONTKNOW &&
+ aLang.nStart == 0 &&
+ aLang.nEnd == aNewStr.getLength();
+
bool bMultiTab = (rMark.GetSelectCount() > 1);
+
OUString aVisibleStr;
if( bMultiTab )
aVisibleStr = mrDoc.GetString(mnCurrCol, mnCurrRow, mnStartTab);
@@ -111,14 +124,28 @@ bool ScConversionEngineBase::FindNextConversionCell()
if (mpUndoDoc && !bEmptyCell)
mrDoc.CopyCellToDocument(aPos, aPos, *mpUndoDoc);
- if (eCellType == CELLTYPE_EDIT)
+ if (!bSimpleString || eCellType == CELLTYPE_EDIT)
{
std::unique_ptr<EditTextObject> pEditObj(CreateTextObject());
mrDoc.SetEditText(aPos, *pEditObj, GetEditTextObjectPool());
}
else
+ {
+ // Set the new string and update the language with the cell.
mrDoc.SetString(aPos, aNewStr);
+ const ScPatternAttr* pAttr = mrDoc.GetPattern(mnCurrCol, mnCurrRow, mnStartTab);
+ std::unique_ptr<ScPatternAttr> pNewAttr;
+
+ if (pAttr)
+ pNewAttr = std::make_unique<ScPatternAttr>(*pAttr);
+ else
+ pNewAttr = std::make_unique<ScPatternAttr>(mrDoc.GetPool());
+
+ pNewAttr->GetItemSet().Put(SvxLanguageItem(aLang.nLang, EE_CHAR_LANGUAGE), ATTR_FONT_LANGUAGE);
+ mrDoc.SetPattern(mnCurrCol, mnCurrRow, mnStartTab, std::move(pNewAttr));
+ }
+
if (mpRedoDoc && !bEmptyCell)
mrDoc.CopyCellToDocument(aPos, aPos, *mpRedoDoc);
diff --git a/svx/source/dialog/weldeditview.cxx b/svx/source/dialog/weldeditview.cxx
index 42eb22c12223..4d900093b044 100644
--- a/svx/source/dialog/weldeditview.cxx
+++ b/svx/source/dialog/weldeditview.cxx
@@ -1190,7 +1190,7 @@ SfxItemState WeldTextForwarder::GetItemState(sal_Int32 nPara, sal_uInt16 nWhich)
LanguageType WeldTextForwarder::GetLanguage(sal_Int32 nPara, sal_Int32 nIndex) const
{
EditEngine* pEditEngine = m_rEditAcc.GetEditEngine();
- return pEditEngine ? pEditEngine->GetLanguage(nPara, nIndex) : LANGUAGE_NONE;
+ return pEditEngine ? pEditEngine->GetLanguage(nPara, nIndex).nLang : LANGUAGE_NONE;
}
sal_Int32 WeldTextForwarder::GetFieldCount(sal_Int32 nPara) const