diff --git a/Src/LexText/ParserCore/HCLoader.cs b/Src/LexText/ParserCore/HCLoader.cs index bbf1cc96dc..c0f2479aa7 100644 --- a/Src/LexText/ParserCore/HCLoader.cs +++ b/Src/LexText/ParserCore/HCLoader.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2023 SIL International +// Copyright (c) 2015-2025 SIL International // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) @@ -58,6 +58,7 @@ public static Language Load(LcmCache cache, IHCLoadErrorLogger logger) private readonly Dictionary m_naturalClassLookup; private readonly Dictionary m_naturalClasses; private readonly Dictionary m_charDefs; + private readonly Dictionary m_CompoundRuleLookup; private readonly bool m_noDefaultCompounding; private readonly bool m_notOnClitics; @@ -98,6 +99,17 @@ private HCLoader(LcmCache cache, IHCLoadErrorLogger logger) m_strataString = (string)hcElem.Element("Strata"); m_strata = ParseStrataString(m_strataString); } + m_CompoundRuleLookup = new Dictionary(); + XElement cRulesEelem = parserParamsElem.Element("CompoundRules"); + if (cRulesEelem != null) + { + foreach (var cRule in cRulesEelem.Elements()) + { + int maxApps = Int32.Parse(cRule.Attribute("maxApps").Value); + m_CompoundRuleLookup[cRule.Attribute("guid").Value] = maxApps; + } + } + m_entryName = new Dictionary(); m_naturalClasses = new Dictionary(); @@ -1862,6 +1874,10 @@ private CompoundingRule LoadEndoCompoundingRule(IMoEndoCompound compoundRule) Properties = { { HCParser.CRuleID, compoundRule.Hvo } } }; + int maxApps = 1; + if (m_CompoundRuleLookup.TryGetValue(compoundRule.Guid.ToString(), out maxApps)) + hcCompoundRule.MaxApplicationCount = maxApps; + var subrule = new CompoundingSubrule(); if (compoundRule.OverridingMsaOA.InflectionClassRA != null) diff --git a/Src/LexText/ParserCore/HCParser.cs b/Src/LexText/ParserCore/HCParser.cs index ef38885d27..f62b813659 100644 --- a/Src/LexText/ParserCore/HCParser.cs +++ b/Src/LexText/ParserCore/HCParser.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2021 SIL International +// Copyright (c) 2014-2025 SIL International // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) @@ -143,6 +143,9 @@ private void LoadParser() m_morpher = null; int delReapps = 0; + // For Hermit Crab, the maximum number of roots/stems allowed is between one and ten. + // The default is two in order to allow for compounding (which requires there be at least two roots/stems). + int maxStemCount = 2; string loadErrorsFile = Path.Combine(m_outputDirectory, m_cache.ProjectId.Name + "HCLoadErrors.xml"); using (XmlWriter writer = XmlWriter.Create(loadErrorsFile)) using (new WorkerThreadReadHelper(m_cache.ServiceLocator.GetInstance())) @@ -153,12 +156,16 @@ private void LoadParser() XElement parserParamsElem = XElement.Parse(m_cache.LanguageProject.MorphologicalDataOA.ParserParameters); XElement delReappsElem = parserParamsElem.Elements("HC").Elements("DelReapps").FirstOrDefault(); XElement guessRootsElem = parserParamsElem.Elements("HC").Elements("GuessRoots").FirstOrDefault(); + XElement maxRootsElem = parserParamsElem.Elements("HC").Elements("MaxRoots").FirstOrDefault(); if (delReappsElem != null) delReapps = (int) delReappsElem; if (guessRootsElem != null) m_guessRoots = (bool) guessRootsElem; + if (maxRootsElem != null) + maxStemCount = int.Parse(maxRootsElem.Value); } m_morpher = new Morpher(m_traceManager, m_language) { DeletionReapplications = delReapps }; + m_morpher.MaxStemCount = maxStemCount; } private XDocument ParseToXml(string form, bool tracing, IEnumerable selectTraceMorphs) diff --git a/Src/LexText/ParserUI/HCMaxCompoundRulesDlg.Designer.cs b/Src/LexText/ParserUI/HCMaxCompoundRulesDlg.Designer.cs new file mode 100644 index 0000000000..e91545878a --- /dev/null +++ b/Src/LexText/ParserUI/HCMaxCompoundRulesDlg.Designer.cs @@ -0,0 +1,116 @@ +using System; +using System.Diagnostics; +using System.Windows.Forms; +using XCore; + +namespace SIL.FieldWorks.LexText.Controls +{ + partial class HCMaxCompoundRulesDlg + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + protected override void Dispose(bool disposing) + { + Debug.WriteLineIf(!disposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); + // Must not be run more than once. + if (IsDisposed) + return; + + if (disposing) + { + if (m_dsCompoundRules != null) + { + m_dsCompoundRules.Dispose(); + m_dsCompoundRules = null; + } + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(HCMaxCompoundRulesDlg)); + this.m_dataGrid = new System.Windows.Forms.DataGrid(); + this.m_btnCancel = new System.Windows.Forms.Button(); + this.m_btnOK = new System.Windows.Forms.Button(); + this.m_btnHelp = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.m_dataGrid)).BeginInit(); + this.SuspendLayout(); + // + // m_dataGrid + // + this.m_dataGrid.CaptionText = "Set maximum applications for compound rules"; + this.m_dataGrid.DataMember = ""; + this.m_dataGrid.HeaderForeColor = System.Drawing.SystemColors.ControlText; + this.m_dataGrid.Location = new System.Drawing.Point(0, 0); + this.m_dataGrid.Name = "m_dataGrid"; + this.m_dataGrid.Size = new System.Drawing.Size(800, 379); + this.m_dataGrid.TabIndex = 4; + // + // m_btnCancel + // + this.m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.m_btnCancel.Location = new System.Drawing.Point(368, 400); + this.m_btnCancel.Name = "m_btnCancel"; + this.m_btnCancel.Size = new System.Drawing.Size(112, 35); + this.m_btnCancel.TabIndex = 1; + this.m_btnCancel.Text = "Cancel"; + // + // m_btnOK + // + this.m_btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; + this.m_btnOK.Location = new System.Drawing.Point(247, 400); + this.m_btnOK.Name = "m_btnOK"; + this.m_btnOK.Size = new System.Drawing.Size(112, 35); + this.m_btnOK.TabIndex = 2; + this.m_btnOK.Text = "OK"; + this.m_btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // m_btnHelp + // + this.m_btnHelp.Location = new System.Drawing.Point(489, 400); + this.m_btnHelp.Name = "m_btnHelp"; + this.m_btnHelp.Size = new System.Drawing.Size(112, 35); + this.m_btnHelp.TabIndex = 3; + this.m_btnHelp.Text = "Help"; + this.m_btnHelp.Click += new System.EventHandler(this.btnHelp_Click); + // + // HCMaxCompoundRulesDlg + // + this.AcceptButton = this.m_btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.m_btnCancel; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Controls.Add(this.m_btnOK); + this.Controls.Add(this.m_btnCancel); + this.Controls.Add(this.m_btnHelp); + this.Controls.Add(this.m_dataGrid); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "HCMaxCompoundRulesDlg"; + this.Text = "HC Max Compound Rules Applications"; + ((System.ComponentModel.ISupportInitialize)(this.m_dataGrid)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button m_btnCancel; + private System.Windows.Forms.Button m_btnOK; + private Button m_btnHelp; + } +} \ No newline at end of file diff --git a/Src/LexText/ParserUI/HCMaxCompoundRulesDlg.cs b/Src/LexText/ParserUI/HCMaxCompoundRulesDlg.cs new file mode 100644 index 0000000000..331d87f771 --- /dev/null +++ b/Src/LexText/ParserUI/HCMaxCompoundRulesDlg.cs @@ -0,0 +1,179 @@ +// Copyright (c) 2025 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) +using SIL.LCModel; +using System; +using System.Data; +using System.Linq; +using System.Windows.Forms; +using System.Xml; +using System.Xml.Linq; +using System.Xml.XPath; +using DataGrid = System.Windows.Forms.DataGrid; +using TextBox = System.Windows.Forms.TextBox; + +namespace SIL.FieldWorks.LexText.Controls +{ + public partial class HCMaxCompoundRulesDlg : ParserParametersBase + { + private const string m_Name = "Name"; + private const string m_Description = "Description"; + private const string m_MaxApps = "MaxApps"; + private const string m_Guid = "Guid"; + private const string m_CompoundRules = "CompoundRules"; + private XElement m_ParserParametersElem; + + private DataGrid m_dataGrid; + private DataSet m_dsCompoundRules; + + public HCMaxCompoundRulesDlg() + { + InitializeComponent(); + } + + /// + /// Set up the dlg in preparation to showing it. + /// + public void SetDlgInfo(string title, string parserParameters, ILcmOwningSequence compoundRules) + { + CheckDisposed(); + + XmlRep = parserParameters; + m_ParserParametersElem = XElement.Parse(parserParameters); + Text = title; + + m_dsCompoundRules = new DataSet { DataSetName = m_CompoundRules }; + + DataTable tblCompoundRules = new DataTable(); + tblCompoundRules.TableName = m_CompoundRules; + tblCompoundRules.Columns.Add(m_Name, typeof(string)); + tblCompoundRules.Columns.Add(m_Description, typeof(string)); + tblCompoundRules.Columns.Add(m_MaxApps, typeof(int)); + tblCompoundRules.Columns.Add(m_Guid, typeof(string)); + tblCompoundRules.Columns[0].ReadOnly = true; + tblCompoundRules.Columns[1].ReadOnly = true; + tblCompoundRules.Columns[3].ReadOnly = true; + m_dsCompoundRules.Tables.Add(tblCompoundRules); + + XElement cRules = new XElement(m_CompoundRules); + foreach (IMoCompoundRule rule in compoundRules) + { + var name = new XElement(m_Name, rule.Name.BestAnalysisAlternative.Text); + var description = new XElement(m_Description, rule.Description.BestAnalysisAlternative.Text); + var sGuid = rule.Guid.ToString(); + string sMaxApps = getMaxAppsFromParameters(sGuid); + var maxApps = new XElement(m_MaxApps, sMaxApps); + var guid = new XElement(m_Guid, sGuid); + cRules.Add(name, description, maxApps, guid); + using (XmlReader reader = cRules.CreateReader()) + m_dsCompoundRules.ReadXml(reader, XmlReadMode.IgnoreSchema); + cRules.RemoveAll(); + } + + m_dataGrid.SetDataBinding(m_dsCompoundRules, m_CompoundRules); + DataView view = CreateDataView(m_dsCompoundRules.Tables[m_CompoundRules]); + m_dataGrid.DataSource = view; + m_dataGrid.TableStyles.Add(new DataGridTableStyle { MappingName = m_CompoundRules, RowHeadersVisible = false, AllowSorting = false }); + foreach (DataGridTextBoxColumn col in m_dataGrid.TableStyles[0].GridColumnStyles.OfType()) + { + TextBox textBox1 = col.TextBox; + textBox1.Multiline = true; + textBox1.ScrollBars = ScrollBars.Vertical; + textBox1.WordWrap = true; + m_dataGrid.TableStyles[0].PreferredRowHeight = 25; + } + + m_dataGrid.TableStyles[0].GridColumnStyles[0].Width = 200; + m_dataGrid.TableStyles[0].GridColumnStyles[1].Width = 250; + m_dataGrid.TableStyles[0].GridColumnStyles[3].Width = 0; + } + + private string getMaxAppsFromParameters(string sGuid) + { + var sMaxApps = "1"; + var ruleElem = m_ParserParametersElem.XPathSelectElement("//CompoundRule[@guid='" + sGuid + "']"); + if (ruleElem != null) + { + var aMaxApps = ruleElem.Attribute("maxApps"); + if (aMaxApps != null) + { + sMaxApps = aMaxApps.Value; + } + } + return sMaxApps; + } + + private DataView CreateDataView(DataTable table) + { + return new DataView(table) { AllowNew = false }; + } + + private void btnOK_Click(object sender, EventArgs e) + { + XElement compoundRulesTopElem = XElement.Parse(m_dsCompoundRules.GetXml()); + ValidateValues(compoundRulesTopElem); + XElement oldParserParamsElem = XElement.Parse(XmlRep); + oldParserParamsElem.Element(m_CompoundRules)?.Remove(); + // Rework compound rules to show just GUID and max apps + var cRulesElem = CreateCompoundRulesElementToStore(compoundRulesTopElem); + oldParserParamsElem.Add(cRulesElem); + XmlRep = oldParserParamsElem.ToString(); + } + + private void ValidateValues(XElement elem) + { + var rulesElem = elem.XPathSelectElements(m_CompoundRules); + foreach (var rule in rulesElem) + { + EnforceValidValue(rule, m_MaxApps, 1, 9, true); + } + } + + private XElement CreateCompoundRulesElementToStore(XElement elem) + { + XElement cRulesElem = new XElement(m_CompoundRules); + var rulesElem = elem.XPathSelectElements(m_CompoundRules); + foreach (var rule in rulesElem) + { + var sMaxApps = rule.Element(m_MaxApps).Value; + if (sMaxApps != "1") + { + var sGuid = rule.Element(m_Guid).Value; + XElement cRule = new XElement("CompoundRule"); + XAttribute guid = new XAttribute("guid", sGuid); + XAttribute maxApps = new XAttribute("maxApps", sMaxApps); + cRule.Add(guid, maxApps); + cRulesElem.Add(cRule); + } + } + return cRulesElem; + } + + private void btnHelp_Click(object sender, EventArgs e) + { + MessageBox.Show("Help clicked"); + } + + protected void EnforceValidValue(XElement elem, string item, int min, int max, bool useMinIfZero) + { + XElement valueElem = elem.Elements(item).FirstOrDefault(); + if (valueElem != null) + { + var val = (int)valueElem; + if (val < min || (useMinIfZero && val == 0)) + { + valueElem.SetValue(min); + XmlRep = elem.ToString(); + ReportChangeOfValue(item, val, min, min, max); + } + else if (val > max) + { + valueElem.SetValue(max); + XmlRep = elem.ToString(); + ReportChangeOfValue(item, val, max, min, max); + } + } + } + + } +} diff --git a/Src/LexText/ParserUI/HCMaxCompoundRulesDlg.resx b/Src/LexText/ParserUI/HCMaxCompoundRulesDlg.resx new file mode 100644 index 0000000000..d73fc589bb --- /dev/null +++ b/Src/LexText/ParserUI/HCMaxCompoundRulesDlg.resx @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAIAEBAAAAAAAABoBQAAJgAAACAgAAAAAAAAqAgAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAAAB + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFUAAACqAAAA/wAAAAAkAABVJAAAqiQAAP8kAAAASQAAVUkAAKpJ + AAD/SQAAAG0AAFVtAACqbQAA/20AAACSAABVkgAAqpIAAP+SAAAAtgAAVbYAAKq2AAD/tgAAANsAAFXb + AACq2wAA/9sAAAD/AABV/wAAqv8AAP//AAAAACQAVQAkAKoAJAD/ACQAACQkAFUkJACqJCQA/yQkAABJ + JABVSSQAqkkkAP9JJAAAbSQAVW0kAKptJAD/bSQAAJIkAFWSJACqkiQA/5IkAAC2JABVtiQAqrYkAP+2 + JAAA2yQAVdskAKrbJAD/2yQAAP8kAFX/JACq/yQA//8kAAAASQBVAEkAqgBJAP8ASQAAJEkAVSRJAKok + SQD/JEkAAElJAFVJSQCqSUkA/0lJAABtSQBVbUkAqm1JAP9tSQAAkkkAVZJJAKqSSQD/kkkAALZJAFW2 + SQCqtkkA/7ZJAADbSQBV20kAqttJAP/bSQAA/0kAVf9JAKr/SQD//0kAAABtAFUAbQCqAG0A/wBtAAAk + bQBVJG0AqiRtAP8kbQAASW0AVUltAKpJbQD/SW0AAG1tAFVtbQCqbW0A/21tAACSbQBVkm0AqpJtAP+S + bQAAtm0AVbZtAKq2bQD/tm0AANttAFXbbQCq220A/9ttAAD/bQBV/20Aqv9tAP//bQAAAJIAVQCSAKoA + kgD/AJIAACSSAFUkkgCqJJIA/ySSAABJkgBVSZIAqkmSAP9JkgAAbZIAVW2SAKptkgD/bZIAAJKSAFWS + kgCqkpIA/5KSAAC2kgBVtpIAqraSAP+2kgAA25IAVduSAKrbkgD/25IAAP+SAFX/kgCq/5IA//+SAAAA + tgBVALYAqgC2AP8AtgAAJLYAVSS2AKoktgD/JLYAAEm2AFVJtgCqSbYA/0m2AABttgBVbbYAqm22AP9t + tgAAkrYAVZK2AKqStgD/krYAALa2AFW2tgCqtrYA/7a2AADbtgBV27YAqtu2AP/btgAA/7YAVf+2AKr/ + tgD//7YAAADbAFUA2wCqANsA/wDbAAAk2wBVJNsAqiTbAP8k2wAASdsAVUnbAKpJ2wD/SdsAAG3bAFVt + 2wCqbdsA/23bAACS2wBVktsAqpLbAP+S2wAAttsAVbbbAKq22wD/ttsAANvbAFXb2wCq29sA/9vbAAD/ + 2wBV/9sAqv/bAP//2wAAAP8AVQD/AKoA/wD/AP8AACT/AFUk/wCqJP8A/yT/AABJ/wBVSf8Aqkn/AP9J + /wAAbf8AVW3/AKpt/wD/bf8AAJL/AFWS/wCqkv8A/5L/AAC2/wBVtv8Aqrb/AP+2/wAA2/8AVdv/AKrb + /wD/2/8AAP//AFX//wCq//8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbba2tra2 + tra2tra2trYAAG3/AP//////AgL///+2AABt/wD//wAAAC//AAAAtgAAbf8A//8A//8vL////7YAAG3/ + AP//AP//AgL///+2AABt/wD//wAAAC//AAAAtgAAbf8A//8A//8vL////7YAAG3/AP8CAv////////+2 + AABt/wAAL/8AAAAAAAD/tgAAbf8A/y8v/////////7YAAG3/AP////////////+2AAACAgICAgICAgIC + AgICAgAAA5cvLy8vLy8vLy8vLy8AAAMDAwMDAwMDAwMDAwMDAAD//zExAAExMQABMTEAATExAAExMQAB + kgoAAZL/AAEAAAABMTEAAZKSAAExMQABMTEAAf//AAEKCgABkv8AAQAAKAAAACAAAABAAAAAAQAIAAAA + AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVAAAAqgAAAP8AAAAAJAAAVSQAAKokAAD/JAAAAEkAAFVJ + AACqSQAA/0kAAABtAABVbQAAqm0AAP9tAAAAkgAAVZIAAKqSAAD/kgAAALYAAFW2AACqtgAA/7YAAADb + AABV2wAAqtsAAP/bAAAA/wAAVf8AAKr/AAD//wAAAAAkAFUAJACqACQA/wAkAAAkJABVJCQAqiQkAP8k + JAAASSQAVUkkAKpJJAD/SSQAAG0kAFVtJACqbSQA/20kAACSJABVkiQAqpIkAP+SJAAAtiQAVbYkAKq2 + JAD/tiQAANskAFXbJACq2yQA/9skAAD/JABV/yQAqv8kAP//JAAAAEkAVQBJAKoASQD/AEkAACRJAFUk + SQCqJEkA/yRJAABJSQBVSUkAqklJAP9JSQAAbUkAVW1JAKptSQD/bUkAAJJJAFWSSQCqkkkA/5JJAAC2 + SQBVtkkAqrZJAP+2SQAA20kAVdtJAKrbSQD/20kAAP9JAFX/SQCq/0kA//9JAAAAbQBVAG0AqgBtAP8A + bQAAJG0AVSRtAKokbQD/JG0AAEltAFVJbQCqSW0A/0ltAABtbQBVbW0Aqm1tAP9tbQAAkm0AVZJtAKqS + bQD/km0AALZtAFW2bQCqtm0A/7ZtAADbbQBV220AqtttAP/bbQAA/20AVf9tAKr/bQD//20AAACSAFUA + kgCqAJIA/wCSAAAkkgBVJJIAqiSSAP8kkgAASZIAVUmSAKpJkgD/SZIAAG2SAFVtkgCqbZIA/22SAACS + kgBVkpIAqpKSAP+SkgAAtpIAVbaSAKq2kgD/tpIAANuSAFXbkgCq25IA/9uSAAD/kgBV/5IAqv+SAP// + kgAAALYAVQC2AKoAtgD/ALYAACS2AFUktgCqJLYA/yS2AABJtgBVSbYAqkm2AP9JtgAAbbYAVW22AKpt + tgD/bbYAAJK2AFWStgCqkrYA/5K2AAC2tgBVtrYAqra2AP+2tgAA27YAVdu2AKrbtgD/27YAAP+2AFX/ + tgCq/7YA//+2AAAA2wBVANsAqgDbAP8A2wAAJNsAVSTbAKok2wD/JNsAAEnbAFVJ2wCqSdsA/0nbAABt + 2wBVbdsAqm3bAP9t2wAAktsAVZLbAKqS2wD/ktsAALbbAFW22wCqttsA/7bbAADb2wBV29sAqtvbAP/b + 2wAA/9sAVf/bAKr/2wD//9sAAAD/AFUA/wCqAP8A/wD/AAAk/wBVJP8AqiT/AP8k/wAASf8AVUn/AKpJ + /wD/Sf8AAG3/AFVt/wCqbf8A/23/AACS/wBVkv8AqpL/AP+S/wAAtv8AVbb/AKq2/wD/tv8AANv/AFXb + /wCq2/8A/9v/AAD//wBV//8Aqv//AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAktra2tra2tra2tra2tra2tra2tra2tra + 2traAAAAAACS/////wD//////////////////////////9oAAAAAAJL/////AP////////////////// + ////////2gAAAAAAkv////8A//////////8CAgIC///////////aAAAAAACS/////wD//////////y// + /wP//////////9oAAAAAAJL/////AP////8AAAAAL///A/8AAAAAAAD/2gAAAAAAkv////8A/////wD/ + //8vLy8D///////////aAAAAAACS/////wD/////AP///////////////////9oAAAAAAJL/////AP// + //8A////////////////////2gAAAAAAkv////8A/////wD///8CAgIC///////////aAAAAAACS//// + /wD/////AP///y///wP//////////9oAAAAAAJL/////AP////8AAAAAL///A/8AAAAAAAD/2gAAAAAA + kv////8A/////wD///8vLy8D///////////aAAAAAACS/////wD/////AP///////////////////9oA + AAAAAJL/////AP////8A////////////////////2gAAAAAAkv////8A//8CAgIC//////////////// + ///aAAAAAACS/////wD//y///wP//////////////////9oAAAAAAJL/////AAAAL///A/8AAAAAAAAA + AAAA////2gAAAAAAkv////8A//8vLy8D///////////////////aAAAAAACS/////wD///////////// + /////////////9oAAAAAAJL/////AP//////////////////////////2gAAAAAAkv////////////// + ///////////////////aAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAAAAMzMy8vLy8v + Ly8vLy8vLy8vLy8vLy8vLy8vLwAAAAAAAzMzLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vAAAAAAADAwMD + AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////wAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAAD//////////8= + + + \ No newline at end of file diff --git a/Src/LexText/ParserUI/ImportWordSetListener.cs b/Src/LexText/ParserUI/ImportWordSetListener.cs index d1ae7a9420..200c810195 100644 --- a/Src/LexText/ParserUI/ImportWordSetListener.cs +++ b/Src/LexText/ParserUI/ImportWordSetListener.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2005-2017 SIL International +// Copyright (c) 2005-2025 SIL International // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) // @@ -387,7 +387,8 @@ public bool OnEditParserParameters(object argument) using (var dlg = new ParserParametersDlg(m_propertyTable.GetValue("HelpTopicProvider"))) { IMoMorphData md = cache.LangProject.MorphologicalDataOA; - dlg.SetDlgInfo(ParserUIStrings.ksParserParameters, md.ParserParameters); + ILcmOwningSequence compoundRules = md.CompoundRulesOS; + dlg.SetDlgInfo(ParserUIStrings.ksParserParameters, md.ParserParameters, compoundRules); if (dlg.ShowDialog(m_propertyTable.GetValue("window")) == DialogResult.OK) { using (var helper = new UndoableUnitOfWorkHelper( diff --git a/Src/LexText/ParserUI/ParserParametersBase.cs b/Src/LexText/ParserUI/ParserParametersBase.cs new file mode 100644 index 0000000000..3e0f93fe9c --- /dev/null +++ b/Src/LexText/ParserUI/ParserParametersBase.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2025 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) +using System; +using System.Windows.Forms; + +namespace SIL.FieldWorks.LexText.Controls +{ + public class ParserParametersBase : Form + { + + /// + /// member strings + /// + private string m_sXmlParameters; + + /// + ///Get or set the parser parameters XML text + /// + public string XmlRep + { + get + { + CheckDisposed(); + + return m_sXmlParameters; + } + set + { + CheckDisposed(); + + m_sXmlParameters = value; + } + } + + /// + /// Check to see if the object has been disposed. + /// All public Properties and Methods should call this + /// before doing anything else. + /// + public void CheckDisposed() + { + if (IsDisposed) + throw new ObjectDisposedException(String.Format("'{0}' in use after being disposed.", GetType().Name)); + } + + protected void ReportChangeOfValue(string item, int value, int newValue, int min, int max) + { + string sMessage = String.Format(ParserUIStrings.ksChangedValueReport, item, value, newValue, min, max); + MessageBox.Show(sMessage, ParserUIStrings.ksChangeValueDialogTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } +} diff --git a/Src/LexText/ParserUI/ParserParametersDlg.cs b/Src/LexText/ParserUI/ParserParametersDlg.cs index a59ffea864..64ab2f6f37 100644 --- a/Src/LexText/ParserUI/ParserParametersDlg.cs +++ b/Src/LexText/ParserUI/ParserParametersDlg.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2003-2017 SIL International +// Copyright (c) 2003-2025 SIL International // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) // @@ -16,13 +16,14 @@ using System.Data; using System.Xml.Linq; using SIL.FieldWorks.Common.FwUtils; +using SIL.LCModel; namespace SIL.FieldWorks.LexText.Controls { /// /// Summary description for ParserParametersDlg. /// - public class ParserParametersDlg : Form + public class ParserParametersDlg : ParserParametersBase { private const string HelpTopic = "khtpParserParamters"; @@ -45,14 +46,10 @@ public class ParserParametersDlg : Form #region Data members - /// - /// member strings - /// - private string m_sXmlParameters; - private readonly IHelpTopicProvider m_helpTopicProvider; private Label m_label1; private Label m_label2; + private Button m_btnHCMaxCompoundRuleApps; private Button m_btnOk; private Button m_btnCancel; private Button m_btnHelp; @@ -63,6 +60,7 @@ public class ParserParametersDlg : Form private DataSet m_dsParserParameters; + private ILcmOwningSequence m_compoundRules; #endregion Data members private ParserParametersDlg() @@ -76,36 +74,6 @@ public ParserParametersDlg(IHelpTopicProvider helpTopicProvider) : this() m_helpTopicProvider = helpTopicProvider; } - /// - ///Get or set the parser parameters XML text - /// - public string XmlRep - { - get - { - CheckDisposed(); - - return m_sXmlParameters; - } - set - { - CheckDisposed(); - - m_sXmlParameters = value; - } - } - - /// - /// Check to see if the object has been disposed. - /// All public Properties and Methods should call this - /// before doing anything else. - /// - public void CheckDisposed() - { - if (IsDisposed) - throw new ObjectDisposedException(String.Format("'{0}' in use after being disposed.", GetType().Name)); - } - /// /// Clean up any resources being used. /// @@ -137,6 +105,7 @@ private void InitializeComponent() System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ParserParametersDlg)); this.m_label1 = new System.Windows.Forms.Label(); this.m_label2 = new System.Windows.Forms.Label(); + this.m_btnHCMaxCompoundRuleApps = new System.Windows.Forms.Button(); this.m_btnOk = new System.Windows.Forms.Button(); this.m_btnCancel = new System.Windows.Forms.Button(); this.m_dataGrid1 = new System.Windows.Forms.DataGrid(); @@ -157,6 +126,12 @@ private void InitializeComponent() resources.ApplyResources(this.m_label2, "m_label2"); this.m_label2.Name = "m_label2"; // + // btnHCMaxCompoundRuleApps + // + resources.ApplyResources(this.m_btnHCMaxCompoundRuleApps, "m_btnHCMaxCompoundRuleApps"); + this.m_btnHCMaxCompoundRuleApps.Name = "m_btnHCMaxCompoundRuleApps"; + this.m_btnHCMaxCompoundRuleApps.Click += new System.EventHandler(this.btnHCMaxCompoundRuleApps_Click); + // // btnOK // this.m_btnOk.DialogResult = System.Windows.Forms.DialogResult.OK; @@ -206,6 +181,7 @@ private void InitializeComponent() this.Controls.Add(this.m_btnHelp); this.Controls.Add(this.m_dataGrid1); this.Controls.Add(this.m_btnCancel); + this.Controls.Add(this.m_btnHCMaxCompoundRuleApps); this.Controls.Add(this.m_btnOk); this.Controls.Add(this.m_label2); this.Controls.Add(this.m_label1); @@ -229,10 +205,19 @@ private void btnOK_Click(object sender, EventArgs e) XElement newParserParamsElem = XElement.Parse(m_dsParserParameters.GetXml()); XElement oldParserParamsElem = XElement.Parse(XmlRep); newParserParamsElem.Add(oldParserParamsElem.Element("ActiveParser")); + newParserParamsElem.Add(oldParserParamsElem.Element("CompoundRules")); XmlRep = newParserParamsElem.ToString(); ValidateValues(newParserParamsElem); } + private void btnHCMaxCompoundRuleApps_Click(object sender, EventArgs e) + { + // create and show compound rule max apps dialog + var dlg = new HCMaxCompoundRulesDlg(); + dlg.SetDlgInfo("MaxApps", XmlRep, m_compoundRules); + dlg.ShowDialog(this); + XmlRep = dlg.XmlRep; + } private void ValidateValues(XElement elem) { EnforceValidValue(elem, XAmple, MaxNulls, 0, 10, false); @@ -244,6 +229,9 @@ private void ValidateValues(XElement elem) EnforceValidValue(elem, XAmple, MaxAnalysesToReturn, -1, 10000, true); EnforceValidValue(elem, HC, DelReapps, 0, 10, false); + // For Hermit Crab, the maximum number of roots/stems allowed is between one and ten. + // The default is two in order to allow for compounding (which requires there be at least two roots/stems). + EnforceValidValue(elem, HC, MaxRoots, 1, 10, false); } private void EnforceValidValue(XElement elem, string parser, string item, int min, int max, bool useMinIfZero) @@ -267,16 +255,10 @@ private void EnforceValidValue(XElement elem, string parser, string item, int mi } } - private void ReportChangeOfValue(string item, int value, int newValue, int min, int max) - { - string sMessage = String.Format(ParserUIStrings.ksChangedValueReport, item, value, newValue, min, max); - MessageBox.Show(sMessage, ParserUIStrings.ksChangeValueDialogTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - } - /// /// Set up the dlg in preparation to showing it. /// - public void SetDlgInfo(string title, string parserParameters) + public void SetDlgInfo(string title, string parserParameters, ILcmOwningSequence compoundRules) { CheckDisposed(); @@ -295,8 +277,14 @@ public void SetDlgInfo(string title, string parserParameters) PopulateDataGrid(m_dataGrid1, XAmple); PopulateDataGrid(m_dataGrid2, HC); m_dataGrid2.TableStyles[0].GridColumnStyles[2].Width = 130; - m_dataGrid2.TableStyles[0].GridColumnStyles[3].Width = 160; - m_dataGrid2.TableStyles[0].GridColumnStyles[5].Width = 400; + m_dataGrid2.TableStyles[0].GridColumnStyles[4].Width = 160; + m_dataGrid2.TableStyles[0].GridColumnStyles[6].Width = 400; + + m_compoundRules = compoundRules; + if (m_compoundRules?.Count > 0) + m_btnHCMaxCompoundRuleApps.Enabled = true; + else + m_btnHCMaxCompoundRuleApps.Enabled= false; } private void LoadParserData(DataSet dsParserParameters) @@ -313,6 +301,8 @@ private void LoadParserData(DataSet dsParserParameters) hcElem.Add(new XElement(DelReapps, 0)); if (hcElem.Element(NoDefaultCompounding) == null) hcElem.Add(new XElement(NoDefaultCompounding, false)); + if (hcElem.Element(MaxRoots) == null) + hcElem.Add(new XElement(MaxRoots, 2)); if (hcElem.Element(NotOnClitics) == null) hcElem.Add(new XElement(NotOnClitics, true)); if (hcElem.Element(AcceptUnspecifiedGraphemes) == null) @@ -369,6 +359,7 @@ private DataTable CreateHCDataTable() tblHC.Columns.Add(DelReapps, typeof(int)); tblHC.Columns.Add(NotOnClitics, typeof(bool)); tblHC.Columns.Add(NoDefaultCompounding, typeof(bool)); + tblHC.Columns.Add(MaxRoots, typeof(int)); tblHC.Columns.Add(AcceptUnspecifiedGraphemes, typeof(bool)); tblHC.Columns.Add(GuessRoots, typeof(bool)); tblHC.Columns.Add(Strata, typeof(string)); diff --git a/Src/LexText/ParserUI/ParserParametersDlg.resx b/Src/LexText/ParserUI/ParserParametersDlg.resx index 794d380c93..9fdd32fe9d 100644 --- a/Src/LexText/ParserUI/ParserParametersDlg.resx +++ b/Src/LexText/ParserUI/ParserParametersDlg.resx @@ -173,6 +173,30 @@ 6 + + 347, 270 + + + 250, 30 + + + 10 + + + Set max applications of HC Compound rules + + + m_btnHCMaxCompoundRuleApps + + + System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 8 + 347, 353 diff --git a/Src/LexText/ParserUI/ParserUI.csproj b/Src/LexText/ParserUI/ParserUI.csproj index 6de24ce3bb..afc84413ed 100644 --- a/Src/LexText/ParserUI/ParserUI.csproj +++ b/Src/LexText/ParserUI/ParserUI.csproj @@ -270,6 +270,12 @@ Code + + Form + + + HCMaxCompoundRulesDlg.cs + Form @@ -278,6 +284,9 @@ Code + + Form + ParserReportDialog.xaml @@ -318,6 +327,9 @@ Code + + HCMaxCompoundRulesDlg.cs + ImportWordSetDlg.cs Designer