Skip to content

Commit 76fad9c

Browse files
authored
Fix LT-21902: Make MoInflAffixSlot be Cloneable (#332)
* Fix LT-21902: Make MoInflAffixSlot be Cloneable * Add code to make copied names unique * Added comment requested by Jason
1 parent 9588c57 commit 76fad9c

File tree

2 files changed

+120
-1
lines changed

2 files changed

+120
-1
lines changed

src/SIL.LCModel/DomainImpl/OverridesLing_MoClasses.cs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2731,6 +2731,26 @@ public void SetCloneProperties(ICmObject clone)
27312731
{
27322732
template.StratumRA = StratumRA;
27332733
}
2734+
MakeTemplateNameUnique(template);
2735+
}
2736+
2737+
internal void MakeTemplateNameUnique(IMoInflAffixTemplate newTemplate)
2738+
{
2739+
// Get existing names.
2740+
ISet<string> names = new HashSet<string>();
2741+
IEnumerable<ICmObject> templates = Services.ObjectRepository.AllInstances(newTemplate.ClassID);
2742+
foreach (IMoInflAffixTemplate template in templates)
2743+
{
2744+
if (template == newTemplate)
2745+
continue;
2746+
for (int i = 0; i < template.Name.StringCount; i++)
2747+
{
2748+
ITsString tss = template.Name.GetStringFromIndex(i, out _);
2749+
names.Add(tss.Text);
2750+
}
2751+
}
2752+
// Make newSlot name unique.
2753+
MoInflAffixSlot.MakeNameUnique(newTemplate.Name, names);
27342754
}
27352755
#endregion
27362756
}
@@ -2882,6 +2902,105 @@ public int CompareTo(object obj)
28822902
}
28832903

28842904
#endregion
2905+
2906+
#region ICloneableCmObject Members
2907+
/// ------------------------------------------------------------------------------------
2908+
/// <summary>
2909+
/// Clones this instance.
2910+
/// </summary>
2911+
/// <param name="clone">Destination object for clone operation</param>
2912+
/// ------------------------------------------------------------------------------------
2913+
public void SetCloneProperties(ICmObject clone)
2914+
{
2915+
IMoInflAffixSlot slot = clone as IMoInflAffixSlot;
2916+
if (slot == null)
2917+
throw new ApplicationException("Failed to copy inflectional affix slot: the target is not an inflectional affix slote.");
2918+
2919+
slot.Name.CopyAlternatives(Name);
2920+
slot.Description.CopyAlternatives(Description);
2921+
slot.Optional = Optional;
2922+
// Make copies of Affixes.
2923+
foreach (IMoInflAffMsa msa in Affixes)
2924+
{
2925+
if (msa.Owner is not ILexEntry entry)
2926+
// Shouldn't happen, but just in case...
2927+
continue;
2928+
foreach (ILexSense sense in entry.SensesOS.ToList()) {
2929+
CopySensesWithMSA(entry, sense, msa, slot);
2930+
}
2931+
}
2932+
MakeSlotNameUnique(slot);
2933+
}
2934+
2935+
/// <summary>
2936+
/// Copy sense with new slot if it's MorphoSyntaxAnalysisRA equals msa.
2937+
/// Recurse on the subsenses.
2938+
/// </summary>
2939+
internal void CopySensesWithMSA(ILexEntry entry, ILexSense sense, IMoInflAffMsa msa, IMoInflAffixSlot newSlot)
2940+
{
2941+
// Recurse on subsense first.
2942+
foreach (ILexSense subsense in sense.SensesOS.ToList())
2943+
{
2944+
CopySensesWithMSA(entry, subsense, msa, newSlot);
2945+
}
2946+
if (sense.MorphoSyntaxAnalysisRA == msa)
2947+
{
2948+
// Create a new sense.
2949+
SandboxGenericMSA sandboxMsa = SandboxGenericMSA.Create(msa);
2950+
sandboxMsa.Slot = newSlot;
2951+
ILexSense newSense = Services.GetInstance<ILexSenseFactory>().Create(entry, sandboxMsa, sense.Gloss.BestAnalysisAlternative);
2952+
newSense.Gloss.MergeAlternatives(sense.Gloss);
2953+
}
2954+
}
2955+
2956+
internal void MakeSlotNameUnique(IMoInflAffixSlot newSlot)
2957+
{
2958+
// Get existing names.
2959+
ISet<string> names = new HashSet<string>();
2960+
IEnumerable<ICmObject> slots = Services.ObjectRepository.AllInstances(newSlot.ClassID);
2961+
foreach (IMoInflAffixSlot slot in slots)
2962+
{
2963+
if (slot == newSlot)
2964+
continue;
2965+
for (int i = 0; i < slot.Name.StringCount; i++)
2966+
{
2967+
ITsString tss = slot.Name.GetStringFromIndex(i, out _);
2968+
names.Add(tss.Text);
2969+
}
2970+
}
2971+
// Make newSlot name unique.
2972+
MakeNameUnique(newSlot.Name, names);
2973+
}
2974+
2975+
static internal void MakeNameUnique(IMultiUnicode name, ISet<string> names)
2976+
{
2977+
for (int i = 0; i < name.StringCount; i++)
2978+
{
2979+
int ws;
2980+
ITsString tss = name.GetStringFromIndex(i, out ws);
2981+
string text = tss.Text;
2982+
// Get existing id.
2983+
int id = 1;
2984+
int idStart = text.Length;
2985+
while (idStart > 0 && Char.IsNumber(text[idStart - 1]))
2986+
idStart = idStart - 1;
2987+
if (idStart < text.Length)
2988+
id = Int32.Parse(text.Substring(idStart));
2989+
// Look for a unique name.
2990+
while (true)
2991+
{
2992+
id += 1;
2993+
string newName = text.Substring(0, idStart) + id.ToString();
2994+
if (!names.Contains(newName))
2995+
{
2996+
// Replace name[i] with unique name.
2997+
name.set_String(ws, newName);
2998+
break;
2999+
}
3000+
}
3001+
}
3002+
}
3003+
#endregion
28853004
}
28863005

28873006
/// <summary></summary>

src/SIL.LCModel/InterfaceAdditions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2097,7 +2097,7 @@ public partial interface IMoInflAffixTemplate : ICloneableCmObject
20972097
}
20982098

20992099
/// <summary/>
2100-
public partial interface IMoInflAffixSlot
2100+
public partial interface IMoInflAffixSlot : ICloneableCmObject
21012101
{
21022102
/// <summary/>
21032103
IEnumerable<IMoInflAffMsa> Affixes { get; }

0 commit comments

Comments
 (0)