Skip to content

Commit aebae99

Browse files
jtmaxwell3jasonleenaylorJakeOliver28
authored
Makes changes for LT-21947 requested by Andy Black (#266)
Co-authored-by: Jason Naylor <jasonleenaylor@users.noreply.github.com> Co-authored-by: Jake Oliver <jeoliver97@gmail.com>
1 parent c117685 commit aebae99

5 files changed

Lines changed: 447 additions & 2 deletions

File tree

Src/LexText/ParserCore/ParserCore.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@
281281
<SubType>Code</SubType>
282282
</Compile>
283283
<Compile Include="XAmpleParser.cs" />
284+
<Compile Include="XAmplePropertiesPreparer.cs" />
285+
<Compile Include="XAmplePropertiesXAmpleDataFilesAugmenter.cs" />
284286
</ItemGroup>
285287
<ItemGroup>
286288
<EmbeddedResource Include="ParserCoreStrings.resx">

Src/LexText/ParserCore/XAmpleParser.cs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2015-2017 SIL International
1+
// Copyright (c) 2015-2024 SIL International
22
// This software is licensed under the LGPL, version 2.1 or later
33
// (http://www.gnu.org/licenses/lgpl-2.1.html)
44

@@ -30,6 +30,7 @@ public class XAmpleParser : DisposableBase, IParser
3030
private readonly M3ToXAmpleTransformer m_transformer;
3131
private readonly string m_database;
3232
private bool m_forceUpdate;
33+
private XElement xampleAddonFileRoot;
3334

3435
public XAmpleParser(LcmCache cache, string dataDir)
3536
{
@@ -41,8 +42,26 @@ public XAmpleParser(LcmCache cache, string dataDir)
4142
m_database = ConvertNameToUseAnsiCharacters(m_cache.ProjectId.Name);
4243
m_transformer = new M3ToXAmpleTransformer(m_database);
4344
m_forceUpdate = true;
45+
InitXAmpleAddonDataInfo();
46+
}
47+
private void InitXAmpleAddonDataInfo()
48+
{
49+
string supportingFilesDir = LcmFileHelper.GetSupportingFilesDir(m_cache.ProjectId.ProjectFolder);
50+
if (supportingFilesDir != null)
51+
{
52+
string xampleAddonFile = Path.Combine(supportingFilesDir, "XAmpleAddonData.xml");
53+
if (File.Exists(xampleAddonFile))
54+
{
55+
XDocument doc = XDocument.Load(xampleAddonFile);
56+
if (doc != null)
57+
{
58+
xampleAddonFileRoot = doc.Root;
59+
var preparer = new XAmplePropertiesPreparer(m_cache, xampleAddonFileRoot, false);
60+
preparer.AddListsAndFields();
61+
}
62+
}
63+
}
4464
}
45-
4665
/// <summary>
4766
/// Convert any characters in the name which are higher than 0x00FF to hex.
4867
/// Neither XAmple nor PC-PATR can read a file name containing letters above 0x00FF.
@@ -97,6 +116,11 @@ public void Update()
97116
foreach (XElement element in model.Elements())
98117
RemoveDottedCircles(element);
99118
m_transformer.MakeAmpleFiles(model);
119+
if (xampleAddonFileRoot != null)
120+
{
121+
var augmenter = XAmplePropertiesXAmpleDataFilesAugmenter.Instance;
122+
augmenter.Process(m_cache, m_database, xampleAddonFileRoot);
123+
}
100124

101125
int maxAnalCount = 20;
102126
XElement maxAnalCountElem = model.Elements("M3Dump").Elements("ParserParameters").Elements("ParserParameters").Elements("XAmple").Elements("MaxAnalysesToReturn").FirstOrDefault();
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
// Copyright (c) 2024 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 SIL.LCModel;
6+
using SIL.LCModel.Core.Cellar;
7+
using SIL.LCModel.DomainServices;
8+
using SIL.LCModel.Infrastructure;
9+
using System;
10+
using System.Collections.Generic;
11+
using System.Linq;
12+
using System.Xml.Linq;
13+
using System.Collections;
14+
using System.Xml.XPath;
15+
16+
namespace SIL.FieldWorks.WordWorks.Parser
17+
{
18+
// Class to prepare custom XAmple properties
19+
public class XAmplePropertiesPreparer
20+
{
21+
public LcmCache Cache { get; set; }
22+
private bool ShowMessages { get; set; }
23+
private string entryCustomFieldName = "";
24+
private string formCustomFieldName = "";
25+
private string customListName = "";
26+
private XElement Root { get; set; }
27+
public XAmplePropertiesPreparer(LcmCache cache, XElement root, bool fShowMessages = true)
28+
{
29+
this.Cache = cache;
30+
this.Root = root;
31+
this.ShowMessages = fShowMessages;
32+
InitStringItems();
33+
}
34+
35+
private void InitStringItems()
36+
{
37+
if (Root != null) {
38+
customListName = findElementValue("CustomList/Name");
39+
entryCustomFieldName = findElementValue("EntryLevelCustomField/Name");
40+
formCustomFieldName = findElementValue("FormLevelCustomField/Name");
41+
}
42+
}
43+
private string findElementValue(string xpath)
44+
{
45+
string result = "";
46+
var item = Root.XPathSelectElement(xpath);
47+
if (item != null)
48+
{
49+
result = item.Value;
50+
}
51+
return result;
52+
}
53+
public List<FieldDescription> GetListOfCustomFields()
54+
{
55+
return (from fd in FieldDescription.FieldDescriptors(Cache)
56+
where fd.IsCustomField
57+
select fd).ToList();
58+
}
59+
60+
public void AddListsAndFields()
61+
{
62+
if (Root == null)
63+
{
64+
return;
65+
}
66+
67+
AddXAmplePropertiesList();
68+
var customFields = GetListOfCustomFields();
69+
AddXAmplePropertiesCustomField(entryCustomFieldName, LexEntryTags.kClassId);
70+
AddXAmplePropertiesCustomField(formCustomFieldName, MoFormTags.kClassId);
71+
}
72+
73+
/// <summary>
74+
/// Creates a new custom field for properties.
75+
/// </summary>
76+
public void AddXAmplePropertiesCustomField(string fieldName, int fieldClassId)
77+
{
78+
var customFields = GetListOfCustomFields();
79+
if (customFields.Find(fd => fd.Name == fieldName) != null)
80+
{
81+
// already done; quit
82+
return;
83+
}
84+
var possListRepository = Cache.ServiceLocator.GetInstance<ICmPossibilityListRepository>();
85+
var customList = possListRepository.AllInstances().FirstOrDefault(list => list.Name.BestAnalysisAlternative.Text == customListName);
86+
if (customList == null)
87+
{
88+
// need the master possibility list and it does not exist
89+
if (ShowMessages)
90+
{
91+
Console.WriteLine("Need to create the master list of possibilities first.");
92+
}
93+
return;
94+
}
95+
NonUndoableUnitOfWorkHelper.Do(Cache.ActionHandlerAccessor, () =>
96+
{
97+
int ws = Cache.DefaultAnalWs;
98+
// create new custom field
99+
var fd = new FieldDescription(Cache)
100+
{
101+
Name = fieldName,
102+
Userlabel = fieldName,
103+
HelpString = string.Empty,
104+
Class = fieldClassId
105+
};
106+
fd.Type = CellarPropertyType.ReferenceCollection;
107+
fd.DstCls = CmCustomItemTags.kClassId;
108+
fd.WsSelector = WritingSystemServices.kwsAnal;
109+
110+
fd.ListRootId = customList.Guid;
111+
fd.UpdateCustomField();
112+
FieldDescription.ClearDataAbout();
113+
});
114+
}
115+
/// <summary>
116+
/// Creates a new possibility list for Quechua properties.
117+
/// </summary>
118+
public void AddXAmplePropertiesList()
119+
{
120+
if (Root == null)
121+
{
122+
// nothing to do
123+
return;
124+
}
125+
var possListRepository = Cache.ServiceLocator.GetInstance<ICmPossibilityListRepository>();
126+
var customList = possListRepository.AllInstances().FirstOrDefault(list => list.Name.BestAnalysisAlternative.Text == customListName);
127+
if (customList != null)
128+
{
129+
return;
130+
}
131+
NonUndoableUnitOfWorkHelper.Do(Cache.ActionHandlerAccessor, () =>
132+
{
133+
int ws = WritingSystemServices.kwsAnal;
134+
Cache.ServiceLocator.GetInstance<ICmPossibilityListFactory>().CreateUnowned(customListName, ws);
135+
customList = possListRepository.AllInstances().Last();
136+
var propPoss = Cache.ServiceLocator.GetInstance<ICmCustomItemFactory>();
137+
ws = Cache.DefaultAnalWs;
138+
var elements = Root.XPathSelectElements("CustomList/Contents/Element");
139+
foreach (var element in elements)
140+
{
141+
var name = element.XPathSelectElement("Name").Value;
142+
var poss = CreateNewPropertyPossibility(ws, customList, propPoss, name);
143+
if (poss != null)
144+
{
145+
XElement item = element.XPathSelectElement("Abbreviation");
146+
string value = "";
147+
if (item != null)
148+
{
149+
value = item.Value;
150+
if (!String.IsNullOrEmpty(value))
151+
{
152+
poss.Abbreviation.set_String(ws, value);
153+
}
154+
}
155+
item = element.XPathSelectElement("Description");
156+
if (item != null)
157+
{
158+
value = item.Value;
159+
if (!String.IsNullOrEmpty(value))
160+
{
161+
poss.Description.set_String(ws, value);
162+
}
163+
}
164+
}
165+
}
166+
});
167+
}
168+
169+
private ICmCustomItem CreateNewPropertyPossibility(int ws, ICmPossibilityList newList, ICmCustomItemFactory propPoss, string name)
170+
{
171+
var poss = propPoss.Create();
172+
newList.PossibilitiesOS.Add(poss);
173+
poss.Name.set_String(ws, name);
174+
return poss;
175+
}
176+
177+
178+
}
179+
}

0 commit comments

Comments
 (0)