Skip to content

Commit af7b48f

Browse files
Merge pull request #386 from sillsdev/hotfix/9.2.10
Cherry-picks for hotfix/9.2.10
2 parents 1274822 + fb0b7ab commit af7b48f

19 files changed

Lines changed: 321 additions & 80 deletions

Src/Common/Controls/Widgets/FontHeightAdjuster.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public static LgCharRenderProps GetChrpForStyle(string styleName, IVwStylesheet
165165
}
166166
}
167167

168-
IVwPropertyStore vwps = VwPropertyStoreClass.Create();
168+
VwPropertyStoreManaged vwps = new VwPropertyStoreManaged();
169169
vwps.Stylesheet = styleSheet;
170170
vwps.WritingSystemFactory = writingSystemFactory;
171171

Src/Common/FwUtils/FwUtilsTests/TestFwStylesheetTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ public void TestOverrideFontForWritingSystem_ForStyleWithNullProps()
127127
stylesheet.OverrideFontsForWritingSystems("FirstStyle", fontOverrides);
128128

129129
//check results
130-
IVwPropertyStore vwps = VwPropertyStoreClass.Create();
130+
VwPropertyStoreManaged vwps = new VwPropertyStoreManaged();
131131
vwps.Stylesheet = stylesheet;
132132
vwps.WritingSystemFactory = wsf;
133133

@@ -190,7 +190,7 @@ public void TestOverrideFontsForWritingSystems_ForStyleWithProps()
190190
stylesheet.OverrideFontsForWritingSystems("FirstStyle", fontOverrides);
191191

192192
//check results
193-
IVwPropertyStore vwps = VwPropertyStoreClass.Create();
193+
VwPropertyStoreManaged vwps = new VwPropertyStoreManaged();
194194
vwps.Stylesheet = stylesheet;
195195
vwps.WritingSystemFactory = wsf;
196196

Src/Common/SimpleRootSite/EditingHelper.cs

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
using SIL.Reporting;
2323
using SIL.LCModel.Utils;
2424
using SIL.Windows.Forms.Keyboarding;
25+
using SIL.LCModel;
2526

2627
namespace SIL.FieldWorks.Common.RootSites
2728
{
@@ -1535,7 +1536,7 @@ public static Font GetFontForNormalStyle(int hvoWs, IVwStylesheet styleSheet,
15351536
ttpBldr.SetIntPropValues((int)FwTextPropType.ktptWs, 0, hvoWs);
15361537
ITsTextProps ttp = ttpBldr.GetTextProps();
15371538

1538-
IVwPropertyStore vwps = VwPropertyStoreClass.Create();
1539+
VwPropertyStoreManaged vwps = new VwPropertyStoreManaged();
15391540
vwps.Stylesheet = styleSheet;
15401541
vwps.WritingSystemFactory = wsf;
15411542
LgCharRenderProps chrps = vwps.get_ChrpFor(ttp);
@@ -3426,6 +3427,18 @@ public string GetClipboardAsString()
34263427
/// <returns>True if the paste succeeded, false otherwise</returns>
34273428
/// ------------------------------------------------------------------------------------
34283429
public virtual bool PasteClipboard()
3430+
{
3431+
return PasteClipboard(null);
3432+
}
3433+
3434+
/// ------------------------------------------------------------------------------------
3435+
/// <summary>
3436+
/// Paste data from the clipboard into the view. Caller is reponsible to make UOW.
3437+
/// </summary>
3438+
/// <param name="cache">The LcmCache.</param>
3439+
/// <returns>True if the paste succeeded, false otherwise</returns>
3440+
/// ------------------------------------------------------------------------------------
3441+
public virtual bool PasteClipboard(LcmCache cache)
34293442
{
34303443
CheckDisposed();
34313444
// Do nothing if command is not enabled. Needed for Ctrl-V keypress.
@@ -3450,23 +3463,25 @@ public virtual bool PasteClipboard()
34503463
ChangeStyleForPaste(vwsel, ref vttp);
34513464

34523465
ITsString tss = GetTextFromClipboard(vwsel, vwsel.CanFormatChar, vttp[0]);
3453-
return PasteCore(tss);
3466+
return PasteCore(tss, cache);
34543467
}
34553468

34563469
/// ------------------------------------------------------------------------------------
34573470
/// <summary>
34583471
/// Core logic for Paste command (without modifying the clipboard, to support testing).
34593472
/// </summary>
34603473
/// <param name="tss">The TsString to paste.</param>
3474+
/// <param name="cache">The LcmCache.</param>
34613475
/// <returns>True if that paste succeeded, false otherwise</returns>
34623476
/// ------------------------------------------------------------------------------------
3463-
public bool PasteCore(ITsString tss)
3477+
public bool PasteCore(ITsString tss, LcmCache cache)
34643478
{
34653479
IVwSelection vwsel = EditedRootBox.Selection;
34663480
try
34673481
{
34683482
if (tss != null)
34693483
{
3484+
tss = ReplaceExternalWritingSystems(tss, vwsel, cache);
34703485
// At this point, we may need to override internal formatting values
34713486
// for certain target rootsites. We do this with an event handler that the
34723487
// rootsite can register for its editing helper. (See LT-1445.)
@@ -3507,6 +3522,58 @@ public bool PasteCore(ITsString tss)
35073522
return true;
35083523
}
35093524

3525+
private ITsString ReplaceExternalWritingSystems(ITsString tss, IVwSelection vwsel, LcmCache cache)
3526+
{
3527+
if (cache == null)
3528+
// Can't tell whether writing systems are external.
3529+
return tss;
3530+
3531+
// Check for external writing systems.
3532+
bool hasExternalWritingSystem = false;
3533+
for (int i = 0; i < tss.RunCount; i++)
3534+
{
3535+
int ws = tss.get_WritingSystem(i);
3536+
if (IsExternalWritingSystem(ws, cache))
3537+
{
3538+
hasExternalWritingSystem = true;
3539+
break;
3540+
}
3541+
}
3542+
if (!hasExternalWritingSystem)
3543+
return tss;
3544+
3545+
// Replace external writing systems with selection's writing system.
3546+
ITsString selTss;
3547+
vwsel.GetSelectionString(out selTss, string.Empty);
3548+
ITsStrBldr stringBldr = TsStringUtils.MakeStrBldr();
3549+
TsRunInfo runInfo;
3550+
for (int irun = 0; irun < tss.RunCount; irun++)
3551+
{
3552+
int ttv, ws;
3553+
ITsTextProps props = tss.FetchRunInfo(irun, out runInfo);
3554+
ws = props.GetIntPropValues((int)FwTextPropType.ktptWs, out ttv);
3555+
if (IsExternalWritingSystem(ws, cache))
3556+
{
3557+
ws = selTss.get_WritingSystemAt(0);
3558+
ITsPropsBldr propsBldr = props.GetBldr();
3559+
propsBldr.SetIntPropValues((int)FwTextPropType.ktptWs, ttv, ws);
3560+
props = propsBldr.GetTextProps();
3561+
}
3562+
stringBldr.Replace(runInfo.ichMin, runInfo.ichMin, tss.get_RunText(irun), props);
3563+
}
3564+
return stringBldr.GetString();
3565+
}
3566+
3567+
private bool IsExternalWritingSystem(int ws, LcmCache cache)
3568+
{
3569+
foreach (CoreWritingSystemDefinition writingSystem in cache.LanguageProject.AllWritingSystems)
3570+
{
3571+
if (writingSystem.Handle == ws)
3572+
return false;
3573+
}
3574+
return true;
3575+
}
3576+
35103577
/// ------------------------------------------------------------------------------------
35113578
/// <summary>
35123579
/// Gets the text from clipboard.

Src/Common/ViewsInterfaces/ViewsInterfaces.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="Current">
33
<PropertyGroup>
44
<ProjectType>Local</ProjectType>
@@ -163,6 +163,7 @@
163163
<Compile Include="AssemblyInfo.cs">
164164
<SubType>Code</SubType>
165165
</Compile>
166+
<Compile Include="VwPropertyStoreManaged.cs" />
166167
<None Include="BuildInclude.targets">
167168
<SubType>Designer</SubType>
168169
</None>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright (c) 2002-2025 SIL International
2+
// This software is licensed under the LGPL, version 2.1 or later
3+
// (http://www.gnu.org/licenses/lgpl-2.1.html)
4+
5+
using System;
6+
using System.Runtime.InteropServices;
7+
using System.Threading;
8+
using SIL.LCModel.Core.KernelInterfaces;
9+
10+
namespace SIL.FieldWorks.Common.ViewsInterfaces
11+
{
12+
/// <summary/>
13+
public sealed class VwPropertyStoreManaged : IDisposable
14+
{
15+
private const string _viewsDllPath = "views.dll";
16+
private IntPtr pVwPropStore;
17+
18+
// Detect redundant Dispose() calls in a thread-safe manner.
19+
// _isDisposed == 0 means Dispose(bool) has not been called yet.
20+
// _isDisposed == 1 means Dispose(bool) has already been called.
21+
private int _isDisposed;
22+
23+
/// <summary/>
24+
public VwPropertyStoreManaged()
25+
{
26+
pVwPropStore = VwPropertyStore_Create();
27+
}
28+
29+
/// <summary/>
30+
public IVwStylesheet Stylesheet
31+
{
32+
set
33+
{
34+
VwPropertyStore_Stylesheet(pVwPropStore, value);
35+
}
36+
}
37+
38+
/// <summary/>
39+
public ILgWritingSystemFactory WritingSystemFactory
40+
{
41+
set
42+
{
43+
VwPropertyStore_WritingSystemFactory(pVwPropStore, value);
44+
}
45+
}
46+
47+
/// <summary/>
48+
public LgCharRenderProps get_ChrpFor(ITsTextProps ttp)
49+
{
50+
IntPtr pInt = VwPropertyStore_get_ChrpFor(pVwPropStore, ttp);
51+
return (LgCharRenderProps)Marshal.PtrToStructure(pInt, typeof(LgCharRenderProps));
52+
}
53+
54+
#region Disposable stuff
55+
/// <summary/>
56+
~VwPropertyStoreManaged() => Dispose(false);
57+
58+
/// <summary/>
59+
public void Dispose()
60+
{
61+
Dispose(true);
62+
GC.SuppressFinalize(this);
63+
}
64+
65+
/// <summary/>
66+
private void Dispose(bool disposing)
67+
{
68+
if (Interlocked.CompareExchange(ref _isDisposed, 1, 0) == 0)
69+
{
70+
// Dispose managed resources (if there are any).
71+
if (disposing)
72+
{
73+
}
74+
75+
// Dispose unmanaged resources.
76+
VwPropertyStore_Delete(pVwPropStore);
77+
}
78+
}
79+
#endregion
80+
81+
#region DLLImport stuff
82+
[DllImport(_viewsDllPath, CallingConvention = CallingConvention.Cdecl)]
83+
private static extern IntPtr VwPropertyStore_Create();
84+
85+
[DllImport(_viewsDllPath, CallingConvention = CallingConvention.Cdecl)]
86+
private static extern void VwPropertyStore_Delete(IntPtr pVwPropStore);
87+
88+
[DllImport(_viewsDllPath, CallingConvention = CallingConvention.Cdecl)]
89+
private static extern void VwPropertyStore_Stylesheet(IntPtr pVwPropStore,
90+
[MarshalAs(UnmanagedType.Interface)] IVwStylesheet pss);
91+
92+
[DllImport(_viewsDllPath, CallingConvention = CallingConvention.Cdecl)]
93+
private static extern void VwPropertyStore_WritingSystemFactory(IntPtr pVwPropStore,
94+
[MarshalAs(UnmanagedType.Interface)] ILgWritingSystemFactory pwsf);
95+
96+
[DllImport(_viewsDllPath, CallingConvention = CallingConvention.Cdecl)]
97+
private static extern IntPtr VwPropertyStore_get_ChrpFor(IntPtr pVwPropStore,
98+
[MarshalAs(UnmanagedType.Interface)] ITsTextProps _ttp);
99+
#endregion
100+
}
101+
}

Src/FwCoreDlgs/FwStylesDlg.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,15 @@ private void m_btnOk_Click(object sender, EventArgs e)
863863

864864
try
865865
{
866+
// Preprocess deletions (For LT-22002).
867+
foreach (string deleted in m_deletedStyleNames)
868+
{
869+
if (m_styleTable.ContainsKey(deleted))
870+
m_styleTable.Remove(deleted);
871+
}
872+
if (m_deletedStyleNames.Contains(m_styleListHelper.SelectedStyleName))
873+
m_deletedStyleNames.Remove(m_styleListHelper.SelectedStyleName);
874+
866875
// Check to make sure new styles are not going to result in duplicates
867876
// in the database
868877
m_styleSheet.CheckForDuplicates(m_styleTable);
@@ -1223,6 +1232,9 @@ private void DeleteAndRenameStylesInDB()
12231232
foreach (var kvp in m_renamedStyles)
12241233
replaceSpec[kvp.Value] = kvp.Key;
12251234
StringServices.ReplaceStyles(m_cache, replaceSpec);
1235+
// Don't process again.
1236+
m_deletedStyleNames.Clear();
1237+
m_renamedStyles.Clear();
12261238

12271239
m_changeType |= StyleChangeType.RenOrDel;
12281240
}

Src/FwCoreDlgs/FwWritingSystemSetupModel.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,8 @@ public FwWritingSystemSetupModel(IWritingSystemContainer container, ListType typ
215215
private List<WSListItemModel> BuildWorkingList(ICollection<CoreWritingSystemDefinition> allForType, IList<CoreWritingSystemDefinition> currentForType)
216216
{
217217
var list = new List<WSListItemModel>();
218-
// We prefer to display the current ones first, because that's what the code that orders them
219-
// in the lexical data fields does. Usually this happens automatically, but there have
220-
// been cases where the order is different in the two lists, even if they have the same items.
221-
var wssInPreferredOrder = currentForType.Concat(allForType.Except(currentForType));
218+
// Don't reorder the writing systems here even though the lexical data fields are reordered (cf. LT-22136).
219+
var wssInPreferredOrder = allForType;
222220
foreach (var ws in wssInPreferredOrder)
223221
{
224222
list.Add(new WSListItemModel(currentForType.Contains(ws), ws, new CoreWritingSystemDefinition(ws, true)));

Src/LexText/Lexicon/ReversalListener.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,15 @@ private void ChangeOwningObject(Guid newGuid)
417417
var layoutFinder = ((Sorter as GenRecordSorter)?.Comparer as StringFinderCompare)?.Finder as LayoutFinder;
418418
if (layoutFinder?.Vc != null)
419419
{
420-
layoutFinder.Vc.OverrideWs = WritingSystemServices.CurrentReversalWsId;
420+
var wsComparer = ((Sorter as GenRecordSorter)?.Comparer as StringFinderCompare)?.SubComparer as WritingSystemComparer;
421+
if (wsComparer != null)
422+
{
423+
layoutFinder.Vc.OverrideWs = Cache.WritingSystemFactory.GetWsFromStr(wsComparer.WsId);
424+
}
425+
else
426+
{
427+
layoutFinder.Vc.OverrideWs = WritingSystemServices.CurrentReversalWsId;
428+
}
421429
}
422430

423431
try

Src/LexText/Morphology/InflAffixTemplateControl.cs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -627,8 +627,8 @@ private SimpleListChooser MakeChooserWithExtantSlots(bool fIsPrefixSlot)
627627
chooser.TextParamHvo = m_template.Owner.Hvo;
628628
chooser.Title = m_sSlotChooserTitle;
629629
chooser.InstructionalText = m_sSlotChooserInstructionalText;
630-
string sTopPOS;
631-
var pos = GetHighestPOS(m_template.OwnerOfClass<IPartOfSpeech>(), out sTopPOS);
630+
IPartOfSpeech pos = m_template.OwnerOfClass<IPartOfSpeech>();
631+
string sTopPOS = pos.ShortName;
632632
string sLabel = String.Format(m_sObligatorySlot, sTopPOS);
633633
chooser.AddLink(sLabel, SimpleListChooser.LinkType.kSimpleLink,
634634
new MakeInflAffixSlotChooserCommand(Cache, true, sLabel, pos.Hvo,
@@ -641,20 +641,6 @@ private SimpleListChooser MakeChooserWithExtantSlots(bool fIsPrefixSlot)
641641
return chooser;
642642
}
643643

644-
private IPartOfSpeech GetHighestPOS(IPartOfSpeech pos, out string sTopPOS)
645-
{
646-
IPartOfSpeech result = null;
647-
sTopPOS = MEStrings.ksQuestions;
648-
ICmObject obj = pos;
649-
while (obj.ClassID == PartOfSpeechTags.kClassId)
650-
{
651-
result = obj as IPartOfSpeech;
652-
sTopPOS = obj.ShortName;
653-
obj = obj.Owner;
654-
}
655-
return result;
656-
}
657-
658644
private bool IsRTL()
659645
{
660646
return Cache.ServiceLocator.WritingSystems.DefaultVernacularWritingSystem.RightToLeftScript;

Src/LexText/ParserCore/FwXmlTraceManager.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ private static XElement CreateParseCompleteElement(Word word, XElement reasonEle
388388

389389
private static XElement CreateInflFeaturesElement(string name, FeatureStruct fs)
390390
{
391-
return new XElement(name, fs.Head().ToString().Replace(",", ""));
391+
string feat = (fs.Head() == null) ? "" : fs.Head().ToString().Replace(",", "");
392+
return new XElement(name, feat);
392393
}
393394

394395
private static XElement CreateWordElement(string name, Word word, bool analysis, bool bracketed = false)

0 commit comments

Comments
 (0)