diff --git a/src/SIL.LCModel/DomainImpl/OverridesLing_MoClasses.cs b/src/SIL.LCModel/DomainImpl/OverridesLing_MoClasses.cs index b9cf612c..c27ed825 100644 --- a/src/SIL.LCModel/DomainImpl/OverridesLing_MoClasses.cs +++ b/src/SIL.LCModel/DomainImpl/OverridesLing_MoClasses.cs @@ -12,6 +12,7 @@ using System.Linq; using System.Text; using System.Xml; +using SIL.Extensions; using SIL.LCModel.Core.Cellar; using SIL.LCModel.Core.KernelInterfaces; using SIL.LCModel.Core.Text; @@ -2920,15 +2921,19 @@ public void SetCloneProperties(ICmObject clone) slot.Description.CopyAlternatives(Description); slot.Optional = Optional; // Make copies of Affixes. + Dictionary> oldToNew = new Dictionary>(); foreach (IMoInflAffMsa msa in Affixes) { if (msa.Owner is not ILexEntry entry) // Shouldn't happen, but just in case... continue; + IList newMsas = new List(); foreach (ILexSense sense in entry.SensesOS.ToList()) { - CopySensesWithMSA(entry, sense, msa, slot); + CopySensesWithMSA(entry, sense, msa, slot, newMsas); } + oldToNew[msa] = newMsas; } + SortNewAffixes(slot, oldToNew); MakeSlotNameUnique(slot); } @@ -2936,12 +2941,12 @@ public void SetCloneProperties(ICmObject clone) /// Copy sense with new slot if it's MorphoSyntaxAnalysisRA equals msa. /// Recurse on the subsenses. /// - internal void CopySensesWithMSA(ILexEntry entry, ILexSense sense, IMoInflAffMsa msa, IMoInflAffixSlot newSlot) + internal void CopySensesWithMSA(ILexEntry entry, ILexSense sense, IMoInflAffMsa msa, IMoInflAffixSlot newSlot, IList newMsas) { // Recurse on subsense first. foreach (ILexSense subsense in sense.SensesOS.ToList()) { - CopySensesWithMSA(entry, subsense, msa, newSlot); + CopySensesWithMSA(entry, subsense, msa, newSlot, newMsas); } if (sense.MorphoSyntaxAnalysisRA == msa) { @@ -2950,9 +2955,37 @@ internal void CopySensesWithMSA(ILexEntry entry, ILexSense sense, IMoInflAffMsa sandboxMsa.Slot = newSlot; ILexSense newSense = Services.GetInstance().Create(entry, sandboxMsa, sense.Gloss.BestAnalysisAlternative); newSense.Gloss.MergeAlternatives(sense.Gloss); + newMsas.Add(newSense.MorphoSyntaxAnalysisRA); } } + internal void SortNewAffixes(IMoInflAffixSlot slot, Dictionary> oldToNew) + { + // Get the old affixes and the new affixes. + int flid = Cache.DomainDataByFlid.MetaDataCache.GetFieldId2(ClassID, "Affixes", true); + IEnumerable oldAffixes = VirtualOrderingServices.GetOrderedValue(this, flid, Affixes); + List newAffixes = slot.Affixes.ToList(); + + // Sort the new affixes using the order of the old affixes. + Dictionary newToOld = new Dictionary(); + foreach (var oldMsa in oldToNew.Keys) + { + foreach (var newMsa in oldToNew[oldMsa]) + { + newToOld[newMsa] = oldAffixes.IndexOf(oldMsa); + } + } + newAffixes.Sort(delegate (ICmObject x, ICmObject y) + { + if (newToOld[x] > newToOld[y]) return 1; + if (newToOld[x] < newToOld[y]) return -1; + return 0; + }); + + // Save the new order. + VirtualOrderingServices.SetVO(slot, flid, newAffixes); + } + internal void MakeSlotNameUnique(IMoInflAffixSlot newSlot) { // Get existing names.