Skip to content

Commit

Permalink
Fix LT-20509: Can't delete words with undefined phonemes (#166)
Browse files Browse the repository at this point in the history
* Fix LT-20509: Can't delete words with undefined phonemes

* Create utility for deleting problem annotations

* Remove annotation tests

---------

Co-authored-by: Jake Oliver <jeoliver97@gmail.com>
  • Loading branch information
jtmaxwell3 and JakeOliver28 authored Oct 8, 2024
1 parent d09b8b7 commit 9126788
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<utilityCatalog>
<utility assemblyPath="LexEdDll.dll" class="SIL.FieldWorks.XWorks.LexEd.HomographResetter"/>
<utility assemblyPath="MorphologyEditorDll.dll" class="SIL.FieldWorks.XWorks.MorphologyEditor.ParserAnalysisRemover"/>
<utility assemblyPath="MorphologyEditorDll.dll" class="SIL.FieldWorks.XWorks.MorphologyEditor.ParserAnnotationRemover"/>
<utility assemblyPath="FixFwDataDll.dll" class="SIL.FieldWorks.FixData.ErrorFixer"/>
<utility assemblyPath="FixFwDataDll.dll" class="SIL.FieldWorks.FixData.WriteAllObjectsUtility"/>
<utility assemblyPath="ITextDll.dll" class="SIL.FieldWorks.IText.DuplicateWordformFixer"/>
Expand Down
6 changes: 6 additions & 0 deletions DistFiles/Language Explorer/Configuration/strings-en.xml
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,12 @@
<string id="WhatDescription" txt="This utility removes all parser approved analyses from the system. It does not remove analyses that are approved/disapproved of by a human user, however. "/>
<string id="RedoDescription" txt="You cannot use 'Undo' to cancel the effect of this utility. You can restore current parser approved analyses by simply running the parser on your words again."/>
</group>
<group id="RemoveParserAnnotations">
<string id="Label" txt="Remove Parser annotations"/>
<string id="WhenDescription" txt="Run this utility when trying to delete a wordform that has parser annotations."/>
<string id="WhatDescription" txt="This utility removes all parser annotations from the system. Parser annotations used to be added by the parser when there was a problem parsing a word. "/>
<string id="RedoDescription" txt="You cannot use 'Undo' to cancel the effect of this utility."/>
</group>
<group id="NaturalClassChooser">
<string id="kstidChooseNaturalClass" txt="Choose Natural Class"/>
<string id="kstidNaturalClassListing" txt="The following natural classes have been specified in the grammar area."/>
Expand Down
13 changes: 11 additions & 2 deletions Src/FdoUi/FdoUiStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Src/FdoUi/FdoUiStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -337,4 +337,7 @@ Without these, we cannot find related entries.</value>
<value>Problem opening file</value>
<comment>Caption for error dialog</comment>
</data>
<data name="ksCannotDeleteWordformBecauseOfAnnotations" xml:space="preserve">
<value>Sorry, FieldWorks cannot delete this wordform because there are parsing annotations attached. Please invoke "Remove Parser annotations" in Tools &gt; Utilities first.</value>
</data>
</root>
13 changes: 13 additions & 0 deletions Src/FdoUi/WfiWordformUi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
// This software is licensed under the LGPL, version 2.1 or later
// (http://www.gnu.org/licenses/lgpl-2.1.html)

using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;

using SIL.LCModel;
using SIL.LCModel.Infrastructure;

namespace SIL.FieldWorks.FdoUi
{
Expand Down Expand Up @@ -76,6 +79,16 @@ protected override bool IsAcceptableContextToJump(string toolCurrent, string too

public override bool CanDelete(out string cannotDeleteMsg)
{
ICmBaseAnnotationRepository repository = base.Object.Cache.ServiceLocator.GetInstance<ICmBaseAnnotationRepository>();
IEnumerable<ICmBaseAnnotation> problemAnnotations =
from ann in repository.AllInstances()
where ann.BeginObjectRA == base.Object && ann.SourceRA is ICmAgent
select ann;
if (problemAnnotations.Any())
{
cannotDeleteMsg = FdoUiStrings.ksCannotDeleteWordformBecauseOfAnnotations;
return false;
}
if (base.CanDelete(out cannotDeleteMsg))
return true;
cannotDeleteMsg = FdoUiStrings.ksCannotDeleteWordform;
Expand Down
5 changes: 3 additions & 2 deletions Src/LexText/Morphology/MorphologyEditorDll.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<OutputPath>..\..\..\Output\Debug\</OutputPath>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
Expand Down Expand Up @@ -353,6 +353,7 @@
<Compile Include="ParserAnalysisRemover.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="ParserAnnotationRemover.cs" />
<Compile Include="PhEnvStrRepresentationSlice.cs">
<SubType>UserControl</SubType>
</Compile>
Expand Down Expand Up @@ -460,4 +461,4 @@
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>
</Project>
117 changes: 117 additions & 0 deletions Src/LexText/Morphology/ParserAnnotationRemover.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using SIL.FieldWorks.Common.FwUtils;
using SIL.FieldWorks.FwCoreDlgs;
using SIL.LCModel.Infrastructure;
using SIL.LCModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SIL.Data;

namespace SIL.FieldWorks.XWorks.MorphologyEditor
{
/// <summary>
/// This class serves to remove all annotations produced by the parser.
/// </summary>
public class ParserAnnotationRemover : IUtility
{
#region Data members

private UtilityDlg m_dlg;
const string kPath = "/group[@id='Linguistics']/group[@id='Morphology']/group[@id='RemoveParserAnnotations']/";

#endregion Data members

/// <summary>
/// Override method to return the Label property.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Label;
}

#region IUtility implementation

/// <summary>
/// Get the main label describing the utility.
/// </summary>
public string Label
{
get
{
Debug.Assert(m_dlg != null);
return StringTable.Table.GetStringWithXPath("Label", kPath);
}
}

/// <summary>
/// Set the UtilityDlg.
/// </summary>
/// <remarks>
/// This must be set, before calling any other property or method.
/// </remarks>
public UtilityDlg Dialog
{
set
{
Debug.Assert(value != null);
Debug.Assert(m_dlg == null);

m_dlg = value;
}
}

/// <summary>
/// Load 0 or more items in the list box.
/// </summary>
public void LoadUtilities()
{
Debug.Assert(m_dlg != null);
m_dlg.Utilities.Items.Add(this);

}

/// <summary>
/// Notify the utility that has been selected in the dlg.
/// </summary>
public void OnSelection()
{
Debug.Assert(m_dlg != null);
m_dlg.WhenDescription = StringTable.Table.GetStringWithXPath("WhenDescription", kPath);
m_dlg.WhatDescription = StringTable.Table.GetStringWithXPath("WhatDescription", kPath);
m_dlg.RedoDescription = StringTable.Table.GetStringWithXPath("RedoDescription", kPath);
}

/// <summary>
/// Have the utility do what it does.
/// </summary>
public void Process()
{
Debug.Assert(m_dlg != null);
var cache = m_dlg.PropTable.GetValue<LcmCache>("cache");
ICmBaseAnnotationRepository repository = cache.ServiceLocator.GetInstance<ICmBaseAnnotationRepository>();
IList<ICmBaseAnnotation> problemAnnotations = (from ann in repository.AllInstances() where ann.SourceRA is ICmAgent select ann).ToList();
if (problemAnnotations.Count > 0)
{
// Set up progress bar.
m_dlg.ProgressBar.Minimum = 0;
m_dlg.ProgressBar.Maximum = problemAnnotations.Count;
m_dlg.ProgressBar.Step = 1;

NonUndoableUnitOfWorkHelper.Do(cache.ActionHandlerAccessor, () =>
{
foreach (ICmBaseAnnotation problem in problemAnnotations)
{
cache.DomainDataByFlid.DeleteObj(problem.Hvo);
m_dlg.ProgressBar.PerformStep();
}
});
}
}

#endregion IUtility implementation
}
}
12 changes: 3 additions & 9 deletions Src/LexText/ParserCore/ParseFiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,11 @@ private bool UpdateWordforms(object parameter)
string form = work.Wordform.Form.BestVernacularAlternative.Text;
using (new TaskReport(String.Format(ParserCoreStrings.ksUpdateX, form), m_taskUpdateHandler))
{
// delete old problem annotations
// delete all old problem annotations
// (We no longer create new problem annotations.)
IEnumerable<ICmBaseAnnotation> problemAnnotations =
from ann in m_baseAnnotationRepository.AllInstances()
where ann.BeginObjectRA == work.Wordform && ann.SourceRA == m_parserAgent
where ann.SourceRA == m_parserAgent
select ann;
foreach (ICmBaseAnnotation problem in problemAnnotations)
m_cache.DomainDataByFlid.DeleteObj(problem.Hvo);
Expand All @@ -194,13 +195,6 @@ from ann in m_baseAnnotationRepository.AllInstances()
if (work.ParseResult.ErrorMessage != null)
{
// there was an error, so create a problem annotation
ICmBaseAnnotation problemReport = m_baseAnnotationFactory.Create();
m_cache.LangProject.AnnotationsOC.Add(problemReport);
problemReport.CompDetails = work.ParseResult.ErrorMessage;
problemReport.SourceRA = m_parserAgent;
problemReport.AnnotationTypeRA = null;
problemReport.BeginObjectRA = work.Wordform;
SetUnsuccessfulParseEvals(work.Wordform, Opinions.noopinion);
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,6 @@ protected ICmAgent HumanAgent
}
}

protected IWfiWordform CheckAnnotationSize(string form, int expectedSize, bool isStarting)
{
ILcmServiceLocator servLoc = Cache.ServiceLocator;
IWfiWordform wf = FindOrCreateWordform(form);
int actualSize =
(from ann in servLoc.GetInstance<ICmBaseAnnotationRepository>().AllInstances()
where ann.BeginObjectRA == wf
select ann).Count();
// wf.RefsFrom_CmBaseAnnotation_BeginObject.Count;
string msg = String.Format("Wrong number of {0} annotations for: {1}", isStarting ? "starting" : "ending", form);
Assert.AreEqual(expectedSize, actualSize, msg);
return wf;
}

private IWfiWordform FindOrCreateWordform(string form)
{
ILcmServiceLocator servLoc = Cache.ServiceLocator;
Expand Down Expand Up @@ -176,26 +162,6 @@ protected void UndoAll()

#region Tests

[Test]
public void TooManyAnalyses()
{
IWfiWordform bearsTest = CheckAnnotationSize("bearsTEST", 0, true);
var result = new ParseResult("Maximum permitted analyses (448) reached.");
m_filer.ProcessParse(bearsTest, ParserPriority.Low, result);
ExecuteIdleQueue();
CheckAnnotationSize("bearsTEST", 1, false);
}

[Test]
public void BufferOverrun()
{
IWfiWordform dogsTest = CheckAnnotationSize("dogsTEST", 0, true);
var result = new ParseResult("Maximum internal buffer size (117) reached.");
m_filer.ProcessParse(dogsTest, ParserPriority.Low, result);
ExecuteIdleQueue();
CheckAnnotationSize("dogsTEST", 1, false);
}

[Test]
public void TwoAnalyses()
{
Expand Down

0 comments on commit 9126788

Please sign in to comment.