From a150ba96c73a592b76a89e3bff255c7205d5ce27 Mon Sep 17 00:00:00 2001 From: John Maxwell Date: Wed, 11 Jun 2025 10:23:13 -0700 Subject: [PATCH] Fix LT-21981: Pasted text retains writing system --- Src/Common/SimpleRootSite/EditingHelper.cs | 71 +++++++++++++++++++++- Src/xWorks/FwXWindow.cs | 2 +- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/Src/Common/SimpleRootSite/EditingHelper.cs b/Src/Common/SimpleRootSite/EditingHelper.cs index 67167ed574..1b022df1dd 100644 --- a/Src/Common/SimpleRootSite/EditingHelper.cs +++ b/Src/Common/SimpleRootSite/EditingHelper.cs @@ -22,6 +22,7 @@ using SIL.Reporting; using SIL.LCModel.Utils; using SIL.Windows.Forms.Keyboarding; +using SIL.LCModel; namespace SIL.FieldWorks.Common.RootSites { @@ -3426,6 +3427,18 @@ public string GetClipboardAsString() /// True if the paste succeeded, false otherwise /// ------------------------------------------------------------------------------------ public virtual bool PasteClipboard() + { + return PasteClipboard(null); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Paste data from the clipboard into the view. Caller is reponsible to make UOW. + /// + /// The LcmCache. + /// True if the paste succeeded, false otherwise + /// ------------------------------------------------------------------------------------ + public virtual bool PasteClipboard(LcmCache cache) { CheckDisposed(); // Do nothing if command is not enabled. Needed for Ctrl-V keypress. @@ -3450,7 +3463,7 @@ public virtual bool PasteClipboard() ChangeStyleForPaste(vwsel, ref vttp); ITsString tss = GetTextFromClipboard(vwsel, vwsel.CanFormatChar, vttp[0]); - return PasteCore(tss); + return PasteCore(tss, cache); } /// ------------------------------------------------------------------------------------ @@ -3458,15 +3471,17 @@ public virtual bool PasteClipboard() /// Core logic for Paste command (without modifying the clipboard, to support testing). /// /// The TsString to paste. + /// The LcmCache. /// True if that paste succeeded, false otherwise /// ------------------------------------------------------------------------------------ - public bool PasteCore(ITsString tss) + public bool PasteCore(ITsString tss, LcmCache cache) { IVwSelection vwsel = EditedRootBox.Selection; try { if (tss != null) { + tss = ReplaceExternalWritingSystems(tss, vwsel, cache); // At this point, we may need to override internal formatting values // for certain target rootsites. We do this with an event handler that the // rootsite can register for its editing helper. (See LT-1445.) @@ -3507,6 +3522,58 @@ public bool PasteCore(ITsString tss) return true; } + private ITsString ReplaceExternalWritingSystems(ITsString tss, IVwSelection vwsel, LcmCache cache) + { + if (cache == null) + // Can't tell whether writing systems are external. + return tss; + + // Check for external writing systems. + bool hasExternalWritingSystem = false; + for (int i = 0; i < tss.RunCount; i++) + { + int ws = tss.get_WritingSystem(i); + if (IsExternalWritingSystem(ws, cache)) + { + hasExternalWritingSystem = true; + break; + } + } + if (!hasExternalWritingSystem) + return tss; + + // Replace external writing systems with selection's writing system. + ITsString selTss; + vwsel.GetSelectionString(out selTss, string.Empty); + ITsStrBldr stringBldr = TsStringUtils.MakeStrBldr(); + TsRunInfo runInfo; + for (int irun = 0; irun < tss.RunCount; irun++) + { + int ttv, ws; + ITsTextProps props = tss.FetchRunInfo(irun, out runInfo); + ws = props.GetIntPropValues((int)FwTextPropType.ktptWs, out ttv); + if (IsExternalWritingSystem(ws, cache)) + { + ws = selTss.get_WritingSystemAt(0); + ITsPropsBldr propsBldr = props.GetBldr(); + propsBldr.SetIntPropValues((int)FwTextPropType.ktptWs, ttv, ws); + props = propsBldr.GetTextProps(); + } + stringBldr.Replace(runInfo.ichMin, runInfo.ichMin, tss.get_RunText(irun), props); + } + return stringBldr.GetString(); + } + + private bool IsExternalWritingSystem(int ws, LcmCache cache) + { + foreach (CoreWritingSystemDefinition writingSystem in cache.LanguageProject.AllWritingSystems) + { + if (writingSystem.Handle == ws) + return false; + } + return true; + } + /// ------------------------------------------------------------------------------------ /// /// Gets the text from clipboard. diff --git a/Src/xWorks/FwXWindow.cs b/Src/xWorks/FwXWindow.cs index 1f5027e7d2..b413d2c3e7 100644 --- a/Src/xWorks/FwXWindow.cs +++ b/Src/xWorks/FwXWindow.cs @@ -663,7 +663,7 @@ public bool OnEditPaste(object arg) Cache.ServiceLocator.GetInstance(), stUndo, stRedo)) using (new DataUpdateMonitor(this, "EditPaste")) { - if (m_viewHelper.ActiveView.EditingHelper.PasteClipboard()) + if (m_viewHelper.ActiveView.EditingHelper.PasteClipboard(Cache)) undoHelper.RollBack = false; } return true;