diff options
author | Kohei Yoshida <kohei@libreoffice.org> | 2022-05-06 19:37:14 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei@libreoffice.org> | 2022-05-07 04:52:50 +0200 |
commit | f15e6293cf78d67963a6e512f60a11ae58da72c5 (patch) | |
tree | 777fd99553c788309747c539a0d5f49565bd2225 | |
parent | 431c692e4e58a4861e4ab7b4d30b1edf0aab0496 (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.cxx | 8 | ||||
-rw-r--r-- | editeng/source/editeng/editview.cxx | 6 | ||||
-rw-r--r-- | editeng/source/editeng/edtspell.cxx | 4 | ||||
-rw-r--r-- | editeng/source/editeng/impedit.hxx | 2 | ||||
-rw-r--r-- | editeng/source/editeng/impedit3.cxx | 4 | ||||
-rw-r--r-- | editeng/source/editeng/impedit4.cxx | 43 | ||||
-rw-r--r-- | editeng/source/editeng/textconv.cxx | 2 | ||||
-rw-r--r-- | editeng/source/outliner/outlin2.cxx | 2 | ||||
-rw-r--r-- | editeng/source/outliner/outlvw.cxx | 2 | ||||
-rw-r--r-- | editeng/source/uno/unofored.cxx | 2 | ||||
-rw-r--r-- | include/editeng/editdata.hxx | 13 | ||||
-rw-r--r-- | include/editeng/editeng.hxx | 4 | ||||
-rw-r--r-- | sc/source/ui/view/spelleng.cxx | 29 | ||||
-rw-r--r-- | svx/source/dialog/weldeditview.cxx | 2 |
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 |