From e13dca531ff51d02848b215aabb7b272e0e34e53 Mon Sep 17 00:00:00 2001 From: mark-sil Date: Wed, 13 Aug 2025 08:37:20 -0400 Subject: [PATCH] LT-22124: Fix Sense homographs in Lexical Relations When getting a property value for a field on a ISenseOrEntry object, call the new method added to LCM that determines the specific object (Sense or Entry), and the specific field on that object, that should be queried to get the value. In this specific defect we are trying to get the HeadWordRef and the ISenseOrEntry is a LexSense. The specific field remains HeadWordRef, but the specific object we need to get the value from is the associated LexEntry. This is because the LexEntry adjusts the HeadWordRef based on the decorator, the LexSense does not. Change-Id: I51ee3b35d5b2482dda4a840e89700d14acda8994 --- Src/xWorks/ConfiguredLcmGenerator.cs | 49 ++++++++++---------- Src/xWorks/DictionaryPublicationDecorator.cs | 2 +- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/Src/xWorks/ConfiguredLcmGenerator.cs b/Src/xWorks/ConfiguredLcmGenerator.cs index f77d3fcec2..bbf9974a8d 100644 --- a/Src/xWorks/ConfiguredLcmGenerator.cs +++ b/Src/xWorks/ConfiguredLcmGenerator.cs @@ -682,26 +682,23 @@ private static IFragment GenerateContentForGroupingNode(object field, List - /// Gets the value of the requested custom field associated with the fieldOwner object + /// Gets the value of the requested field associated with the fieldOwner object /// - /// true if the custom field was valid and false otherwise - /// propertyValue can be null if the custom field is valid but no value is stored for the owning object + /// true if the field was valid and false otherwise + /// propertyValue can be null if the field is valid but no value is stored for the owning object private static bool GetPropValueForModelField(object fieldOwner, ConfigurableDictionaryNode config, - LcmCache cache, ISilDataAccess decorator, string customFieldName, ref object propertyValue, string cfOwnerClassName = null) + LcmCache cache, ISilDataAccess decorator, string fieldName, ref object propertyValue, string cfOwnerClassName = null) { - var customFieldOwnerClassName = cfOwnerClassName; + var fieldOwnerClassName = cfOwnerClassName; + var specificFieldName = fieldName; ICmObject specificObject; if (fieldOwner is ISenseOrEntry senseOrEntry) { - // assign the customFieldOwnerClassName if it was not passed in - customFieldOwnerClassName = customFieldOwnerClassName ?? senseOrEntry.Item.ClassName; - specificObject = senseOrEntry.Item; + senseOrEntry.SpecificItemAndFieldName(fieldName, out specificObject, out specificFieldName); } else if(fieldOwner is ICmObject owner) { specificObject = owner; - // assign the customFieldOwnerClassName if it was not passed in - customFieldOwnerClassName = customFieldOwnerClassName ?? specificObject.ClassName; senseOrEntry = null; } else @@ -709,23 +706,27 @@ private static bool GetPropValueForModelField(object fieldOwner, ConfigurableDic // throw an argument exception if the field owner is not a valid type throw new ArgumentException("The field owner is not a valid type", nameof(fieldOwner)); } + + // assign the fieldOwnerClassName if it was not passed in + fieldOwnerClassName = fieldOwnerClassName ?? specificObject.ClassName; + if (decorator == null) decorator = cache.DomainDataByFlid; - int customFieldFlid = GetCustomFieldFlid(config, cache, customFieldOwnerClassName, customFieldName); - if (customFieldFlid == 0) + int fieldFlid = GetCustomFieldFlid(config, cache, fieldOwnerClassName, specificFieldName); + if (fieldFlid == 0) return false; - var customFieldType = cache.MetaDataCacheAccessor.GetFieldType(customFieldFlid); + var fieldType = cache.MetaDataCacheAccessor.GetFieldType(fieldFlid); if (senseOrEntry != null) { - if (!((IFwMetaDataCacheManaged)cache.MetaDataCacheAccessor).GetFields(senseOrEntry.Item.ClassID, - true, (int)CellarPropertyTypeFilter.All).Contains(customFieldFlid)) + if (!((IFwMetaDataCacheManaged)cache.MetaDataCacheAccessor).GetFields(specificObject.ClassID, + true, (int)CellarPropertyTypeFilter.All).Contains(fieldFlid)) { return false; } } - switch (customFieldType) + switch (fieldType) { case (int)CellarPropertyType.ReferenceCollection: case (int)CellarPropertyType.OwningCollection: @@ -735,11 +736,11 @@ private static bool GetPropValueForModelField(object fieldOwner, ConfigurableDic { var sda = decorator; // This method returns the hvo of the object pointed to - var chvo = sda.get_VecSize(specificObject.Hvo, customFieldFlid); + var chvo = sda.get_VecSize(specificObject.Hvo, fieldFlid); int[] contents; using (var arrayPtr = MarshalEx.ArrayToNative(chvo)) { - sda.VecProp(specificObject.Hvo, customFieldFlid, chvo, out chvo, arrayPtr); + sda.VecProp(specificObject.Hvo, fieldFlid, chvo, out chvo, arrayPtr); contents = MarshalEx.NativeToArray(arrayPtr, chvo); } // Convert the contents to IEnumerable @@ -763,36 +764,36 @@ private static bool GetPropValueForModelField(object fieldOwner, ConfigurableDic case (int)CellarPropertyType.OwningAtomic: { // This method returns the hvo of the object pointed to - propertyValue = decorator.get_ObjectProp(specificObject.Hvo, customFieldFlid); + propertyValue = decorator.get_ObjectProp(specificObject.Hvo, fieldFlid); // if the hvo is invalid set propertyValue to null otherwise get the object propertyValue = (int)propertyValue > 0 ? cache.LangProject.Services.GetObject((int)propertyValue) : null; break; } case (int)CellarPropertyType.GenDate: { - propertyValue = new GenDate(decorator.get_IntProp(specificObject.Hvo, customFieldFlid)); + propertyValue = new GenDate(decorator.get_IntProp(specificObject.Hvo, fieldFlid)); break; } case (int)CellarPropertyType.Time: { - propertyValue = SilTime.ConvertFromSilTime(decorator.get_TimeProp(specificObject.Hvo, customFieldFlid)); + propertyValue = SilTime.ConvertFromSilTime(decorator.get_TimeProp(specificObject.Hvo, fieldFlid)); break; } case (int)CellarPropertyType.MultiUnicode: case (int)CellarPropertyType.MultiString: { - propertyValue = decorator.get_MultiStringProp(specificObject.Hvo, customFieldFlid); + propertyValue = decorator.get_MultiStringProp(specificObject.Hvo, fieldFlid); break; } case (int)CellarPropertyType.String: { - propertyValue = decorator.get_StringProp(specificObject.Hvo, customFieldFlid); + propertyValue = decorator.get_StringProp(specificObject.Hvo, fieldFlid); break; } case (int)CellarPropertyType.Integer: { - propertyValue = decorator.get_IntProp(specificObject.Hvo, customFieldFlid); + propertyValue = decorator.get_IntProp(specificObject.Hvo, fieldFlid); break; } } diff --git a/Src/xWorks/DictionaryPublicationDecorator.cs b/Src/xWorks/DictionaryPublicationDecorator.cs index f710924f57..004eb18234 100644 --- a/Src/xWorks/DictionaryPublicationDecorator.cs +++ b/Src/xWorks/DictionaryPublicationDecorator.cs @@ -246,7 +246,7 @@ private string GetSenseNumber(ILexSense sense) public override ITsMultiString get_MultiStringProp(int hvo, int tag) { - if (tag == m_mlHeadwordFlid || tag == m_headwordRefFlid) + if (tag == m_mlHeadwordFlid || tag == m_headwordRefFlid || tag == m_mlOwnerOutlineFlid) { return new PublicationAwareMultiStringAccessor(hvo, tag, this); }