Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix LT-20509: Can't delete words with undefined phonemes #166

Merged
merged 8 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading