bool CheckForFormDataLoss(IMoForm origForm, int toClsid) { string msg = null; switch (origForm.ClassID) { case MoAffixAllomorph.kclsidMoAffixAllomorph: IMoAffixAllomorph affAllo = origForm as IMoAffixAllomorph; bool loseEnv = affAllo.PhoneEnvRC.Count > 0; bool losePos = affAllo.PositionRS.Count > 0; bool loseGram = affAllo.MsEnvFeaturesOAHvo != 0 || affAllo.MsEnvPartOfSpeechRAHvo != 0; if (loseEnv && losePos && loseGram) { msg = LexEdStrings.ksConvertFormLoseEnvInfixLocGramInfo; } else if (loseEnv && losePos) { msg = LexEdStrings.ksConvertFormLoseEnvInfixLoc; } else if (loseEnv && loseGram) { msg = LexEdStrings.ksConvertFormLoseEnvGramInfo; } else if (losePos && loseGram) { msg = LexEdStrings.ksConvertFormLoseInfixLocGramInfo; } else if (loseEnv) { msg = LexEdStrings.ksConvertFormLoseEnv; } else if (losePos) { msg = LexEdStrings.ksConvertFormLoseInfixLoc; } else if (loseGram) { msg = LexEdStrings.ksConvertFormLoseGramInfo; } break; case MoAffixProcess.kclsidMoAffixProcess: msg = LexEdStrings.ksConvertFormLoseRule; break; case MoStemAllomorph.kclsidMoStemAllomorph: // not implemented break; } if (msg != null) { DialogResult result = MessageBox.Show(msg, LexEdStrings.ksConvertFormLoseCaption, MessageBoxButtons.YesNo, MessageBoxIcon.Warning); return(result == DialogResult.Yes); } return(true); }
public void TwoAnalyses() { IWfiWordform catsTest = CheckAnalysisSize("catsTEST", 0, true); ILexDb ldb = Cache.LanguageProject.LexDbOA; ParseResult result = null; UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { // Noun ILexEntry catN = m_entryFactory.Create(); IMoStemAllomorph catNForm = m_stemAlloFactory.Create(); catN.AlternateFormsOS.Add(catNForm); catNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("catNTEST", m_vernacularWS.Handle); IMoStemMsa catNMsa = m_stemMsaFactory.Create(); catN.MorphoSyntaxAnalysesOC.Add(catNMsa); ILexEntry sPl = m_entryFactory.Create(); IMoAffixAllomorph sPlForm = m_afxAlloFactory.Create(); sPl.AlternateFormsOS.Add(sPlForm); sPlForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("sPLTEST", m_vernacularWS.Handle); IMoInflAffMsa sPlMsa = m_inflAffMsaFactory.Create(); sPl.MorphoSyntaxAnalysesOC.Add(sPlMsa); // Verb ILexEntry catV = m_entryFactory.Create(); IMoStemAllomorph catVForm = m_stemAlloFactory.Create(); catV.AlternateFormsOS.Add(catVForm); catVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("catVTEST", m_vernacularWS.Handle); IMoStemMsa catVMsa = m_stemMsaFactory.Create(); catV.MorphoSyntaxAnalysesOC.Add(catVMsa); ILexEntry sAgr = m_entryFactory.Create(); IMoAffixAllomorph sAgrForm = m_afxAlloFactory.Create(); sAgr.AlternateFormsOS.Add(sAgrForm); sAgrForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("sAGRTEST", m_vernacularWS.Handle); IMoInflAffMsa sAgrMsa = m_inflAffMsaFactory.Create(); sAgr.MorphoSyntaxAnalysesOC.Add(sAgrMsa); result = new ParseResult(new[] { new ParseAnalysis(new[] { new ParseMorph(catNForm, catNMsa), new ParseMorph(sPlForm, sPlMsa) }), new ParseAnalysis(new[] { new ParseMorph(catVForm, catVMsa), new ParseMorph(sAgrForm, sAgrMsa) }) }); }); m_filer.ProcessParse(catsTest, ParserPriority.Low, result); ExecuteIdleQueue(); CheckAnalysisSize("catsTEST", 2, false); }
public void MergeCollectionPropertyBackReferences() { CheckDisposed(); ILexEntry lme = m_entriesCol.Add(new LexEntry()); FdoOwningSequence<IPhEnvironment> envsSeq = Cache.LangProject.PhonologicalDataOA.EnvironmentsOS; IPhEnvironment envKeeper = envsSeq.Append(new PhEnvironment()); IPhEnvironment envSrc = envsSeq.Append(new PhEnvironment()); // Shift back references from reference sequence property. IMoAffixAllomorph referrer = (IMoAffixAllomorph)lme.AlternateFormsOS.Append(new MoAffixAllomorph()); referrer.PhoneEnvRC.Add(envSrc); envKeeper.MergeObject(envSrc); Assert.AreEqual(envKeeper.Hvo, referrer.PhoneEnvRC.HvoArray[0]); }
protected void ConvertAffixAlloFeats(XmlDocument doc, XmlNode node, IMoForm form, XmlNode tempNode) { IMoAffixAllomorph sallo = form as IMoAffixAllomorph; IFsFeatStruc fsFeatStruc = sallo.MsEnvFeaturesOA; if (fsFeatStruc != null && !fsFeatStruc.IsEmpty) { tempNode = CreateXmlElement(doc, "affixAlloFeats", node); CreateFeatureStructureNodes(doc, tempNode, fsFeatStruc, fsFeatStruc.Hvo); } else { // There's no overt stem name on this allomorph, but there might be overt stem names // on other allomorphs in this lexical entry. This allomorph, then, cannot bear any // of the features of these other stem names. If so, there will be a property named // NotStemNameddd or NotStemNamedddNotStemNamedddd, etc. CreateNotAffixAlloFeatsElement(doc, node, tempNode); } }
public void MergeReferenceSequence() { CheckDisposed(); // 28 MoAffixAllomorph.Position(refers to PhEnvironment) ILexEntry lme = m_entriesCol.Add(new LexEntry()); IMoAffixAllomorph aKeeper = (IMoAffixAllomorph)lme.AlternateFormsOS.Append(new MoAffixAllomorph()); IMoAffixAllomorph aSrc = (IMoAffixAllomorph)lme.AlternateFormsOS.Append(new MoAffixAllomorph()); FdoOwningSequence<IPhEnvironment> envsSeq = Cache.LangProject.PhonologicalDataOA.EnvironmentsOS; envsSeq.Append(new PhEnvironment()); envsSeq.Append(new PhEnvironment()); envsSeq.Append(new PhEnvironment()); // Merge content into null. aSrc.PositionRS.Append(envsSeq[0].Hvo); aSrc.PositionRS.Append(envsSeq[1].Hvo); aKeeper.MergeObject(aSrc); Assert.AreEqual(2, aKeeper.PositionRS.Count); // Merge duplicate content into content. aSrc = (IMoAffixAllomorph)lme.AlternateFormsOS.Append(new MoAffixAllomorph()); aSrc.PositionRS.Append(envsSeq[0].Hvo); aSrc.PositionRS.Append(envsSeq[1].Hvo); aKeeper.MergeObject(aSrc); Assert.AreEqual(4, aKeeper.PositionRS.Count); // Merge content into content. aSrc = (IMoAffixAllomorph)lme.AlternateFormsOS.Append(new MoAffixAllomorph()); aSrc.PositionRS.Append(envsSeq[0].Hvo); aSrc.PositionRS.Append(envsSeq[1].Hvo); aSrc.PositionRS.Append(envsSeq[2].Hvo); aKeeper.MergeObject(aSrc); Assert.AreEqual(7, aKeeper.PositionRS.Count); // Merge null into content. aSrc = (IMoAffixAllomorph)lme.AlternateFormsOS.Append(new MoAffixAllomorph()); Assert.AreEqual(0, aSrc.PositionRS.Count); aKeeper.MergeObject(aSrc); Assert.AreEqual(7, aKeeper.PositionRS.Count); }
protected void CreateInflectionClasses(XmlDocument doc, XmlNode morphNode) { string sAlloId = XmlUtils.GetOptionalAttributeValue(morphNode, "alloid"); if (sAlloId == null) { return; } int hvoAllomorph = Convert.ToInt32(sAlloId); IMoAffixAllomorph allo = MoAffixAllomorph.CreateFromDBObject(m_cache, hvoAllomorph); if (allo == null) { return; } foreach (IMoInflClass ic in allo.InflectionClassesRC) { XmlNode icNode = CreateXmlElement(doc, "inflectionClass", morphNode); CreateXmlAttribute(doc, "id", ic.Hvo.ToString(), icNode); CreateXmlAttribute(doc, "abbr", ic.Abbreviation.BestAnalysisAlternative.Text, icNode); } }
private bool CheckForAffixDataLoss(IMoAffixForm affix, List <IMoMorphSynAnalysis> rgmsaAffix) { bool fLoseInflCls = affix.InflectionClassesRC.Count > 0; bool fLoseInfixLoc = false; bool fLoseGramInfo = false; bool fLoseRule = false; switch (affix.ClassID) { case MoAffixProcess.kclsidMoAffixProcess: fLoseRule = true; break; case MoAffixAllomorph.kclsidMoAffixAllomorph: IMoAffixAllomorph allo = affix as IMoAffixAllomorph; fLoseInfixLoc = allo.PositionRS.Count > 0; fLoseGramInfo = allo.MsEnvPartOfSpeechRAHvo != 0 || allo.MsEnvFeaturesOAHvo != 0; break; } for (int i = 0; !fLoseGramInfo && i < rgmsaAffix.Count; ++i) { IMoInflAffMsa msaInfl = rgmsaAffix[i] as IMoInflAffMsa; if (msaInfl != null) { if (msaInfl.AffixCategoryRAHvo != 0 || msaInfl.FromProdRestrictRC.Count > 0 || msaInfl.SlotsRC.Count > 0 || msaInfl.InflFeatsOAHvo != 0) { fLoseGramInfo = true; } continue; } IMoDerivAffMsa msaDeriv = rgmsaAffix[i] as IMoDerivAffMsa; if (msaDeriv != null) { if (msaDeriv.AffixCategoryRAHvo != 0 || msaDeriv.FromInflectionClassRAHvo != 0 || msaDeriv.FromPartOfSpeechRAHvo != 0 || msaDeriv.FromProdRestrictRC.Count > 0 || msaDeriv.FromStemNameRAHvo != 0 || msaDeriv.StratumRAHvo != 0 || msaDeriv.ToInflectionClassRAHvo != 0 || msaDeriv.ToProdRestrictRC.Count > 0 || msaDeriv.FromMsFeaturesOAHvo != 0 || msaDeriv.ToMsFeaturesOAHvo != 0) { fLoseGramInfo = true; } continue; } IMoDerivStepMsa msaStep = rgmsaAffix[i] as IMoDerivStepMsa; if (msaStep != null) { if (msaStep.InflectionClassRAHvo != 0 || msaStep.ProdRestrictRC.Count > 0 || msaStep.InflFeatsOAHvo != 0 || msaStep.MsFeaturesOAHvo != 0) { fLoseGramInfo = true; } continue; } } if (fLoseInflCls || fLoseInfixLoc || fLoseGramInfo || fLoseRule) { string sMsg; if (fLoseInflCls && fLoseInfixLoc && fLoseGramInfo) { sMsg = m_mediator.StringTbl.GetStringWithXPath("ChangeMorphTypeLoseInflClsInfixLocGramInfo", m_ksPath); } else if (fLoseRule && fLoseInflCls && fLoseGramInfo) { sMsg = m_mediator.StringTbl.GetStringWithXPath("ChangeMorphTypeLoseRuleInflClsGramInfo", m_ksPath); } else if (fLoseInflCls && fLoseInfixLoc) { sMsg = m_mediator.StringTbl.GetStringWithXPath("ChangeMorphTypeLoseInflClsInfixLoc", m_ksPath); } else if (fLoseInflCls && fLoseGramInfo) { sMsg = m_mediator.StringTbl.GetStringWithXPath("ChangeMorphTypeLoseInflClsGramInfo", m_ksPath); } else if (fLoseInfixLoc && fLoseGramInfo) { sMsg = m_mediator.StringTbl.GetStringWithXPath("ChangeMorphTypeLoseInfixLocGramInfo", m_ksPath); } else if (fLoseRule && fLoseInflCls) { sMsg = m_mediator.StringTbl.GetStringWithXPath("ChangeMorphTypeLoseRuleInflCls", m_ksPath); } else if (fLoseRule) { sMsg = m_mediator.StringTbl.GetStringWithXPath("ChangeMorphTypeLoseRule", m_ksPath); } else if (fLoseInflCls) { sMsg = m_mediator.StringTbl.GetStringWithXPath("ChangeMorphTypeLoseInflCls", m_ksPath); } else if (fLoseInfixLoc) { sMsg = m_mediator.StringTbl.GetStringWithXPath("ChangeMorphTypeLoseInfixLoc", m_ksPath); } else { sMsg = m_mediator.StringTbl.GetStringWithXPath("ChangeMorphTypeLoseGramInfo", m_ksPath); } string sCaption = m_mediator.StringTbl.GetStringWithXPath("ChangeLexemeMorphTypeCaption", m_ksPath); DialogResult result = MessageBox.Show(sMsg, sCaption, MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (result == DialogResult.No) { return(true); } } return(false); }
/// <summary> /// Handle launching of the MSA editor. /// </summary> protected override void HandleChooser() { VectorReferenceLauncher vrl = null; using (MsaInflectionFeatureListDlg dlg = new MsaInflectionFeatureListDlg()) { IFsFeatStruc originalFs = m_obj as IFsFeatStruc; Slice parentSlice = Slice; if (originalFs == null) { int owningFlid; int parentSliceClass = (int)parentSlice.Object.ClassID; switch (parentSliceClass) { case MoAffixAllomorphTags.kClassId: IMoAffixAllomorph allo = parentSlice.Object as IMoAffixAllomorph; owningFlid = (parentSlice as MsaInflectionFeatureListDlgLauncherSlice).Flid; dlg.SetDlgInfo(m_cache, m_mediator, m_propertyTable, allo, owningFlid); break; /*case LexEntryInflTypeTags.kClassId: * ILexEntryInflType leit = parentSlice.Object as ILexEntryInflType; * owningFlid = (parentSlice as MsaInflectionFeatureListDlgLauncherSlice).Flid; * dlg.SetDlgInfo(m_cache, m_mediator, leit, owningFlid); * break;*/ default: IMoMorphSynAnalysis msa = parentSlice.Object as IMoMorphSynAnalysis; owningFlid = (parentSlice as MsaInflectionFeatureListDlgLauncherSlice).Flid; dlg.SetDlgInfo(m_cache, m_mediator, m_propertyTable, msa, owningFlid); break; } } else { dlg.SetDlgInfo(m_cache, m_mediator, m_propertyTable, originalFs, (parentSlice as MsaInflectionFeatureListDlgLauncherSlice).Flid); } const string ksPath = "/group[@id='Linguistics']/group[@id='Morphology']/group[@id='FeatureChooser']/"; dlg.Text = StringTable.Table.GetStringWithXPath("InflectionFeatureTitle", ksPath); dlg.Prompt = StringTable.Table.GetStringWithXPath("InflectionFeaturePrompt", ksPath); dlg.LinkText = StringTable.Table.GetStringWithXPath("InflectionFeatureLink", ksPath); DialogResult result = dlg.ShowDialog(parentSlice.FindForm()); if (result == DialogResult.OK) { // Note that this may set m_obj to null. dlg.FS will be null if all inflection features have been // removed. That is a valid state for this slice; m_obj deleted is not. m_obj = dlg.FS; m_msaInflectionFeatureListDlgLauncherView.Init(m_cache, dlg.FS); } else if (result == DialogResult.Yes) { // Get the VectorReferenceLauncher for the Inflection Features slice. // Since we're not changing tools, we want to change the chooser dialog. // See LT-5913 for motivation. Control ctl = this.Parent; while (ctl != null && !(ctl is Slice)) { ctl = ctl.Parent; } Slice slice = ctl as Slice; if (slice != null) { DataTree dt = slice.ContainingDataTree; for (int i = 0; i < dt.Slices.Count; ++i) { Slice sliceT = dt.FieldOrDummyAt(i); vrl = sliceT.Control as VectorReferenceLauncher; if (vrl != null) { if (vrl.Flid == PartOfSpeechTags.kflidInflectableFeats) { break; } vrl = null; } } } if (vrl == null) { // We do, too, need to change tools! Sometimes this slice shows up in a different context, // such as the main data entry view. See LT-7167. // go to m_highestPOS in editor // TODO: this should be reviewed by someone who knows how these links should be done // I'm just guessing. // Also, is there some way to know the application name and tool name without hard coding them? var linkJump = new FwLinkArgs("posEdit", dlg.HighestPOS.Guid); m_mediator.PostMessage("FollowLink", linkJump); } else { vrl.HandleExternalChooser(); } } } }
public void ParserDataChanges() { XmlNode node; #if !ShowDumpResult m_fxtResult.Save(Path.Combine(System.IO.Path.GetTempPath(), "TestFxtUpdateBefore.xml")); #endif // ------------- // Make data changes // ------------- // Make a change to stem allomorph ILangProject lp = Cache.LangProject; ILexDb lexdb = lp.LexDbOA; int[] aiLexEntries = lexdb.EntriesOC.HvoArray; int hvoLexEntry = aiLexEntries[0]; ILexEntry lexEntry = CmObject.CreateFromDBObject(Cache, hvoLexEntry) as ILexEntry; Assert.IsNotNull(lexEntry); IMoStemAllomorph stemAllomorph = lexEntry.LexemeFormOA as IMoStemAllomorph; Assert.IsNotNull(stemAllomorph); stemAllomorph.Form.SetAlternative("bili-changed", Cache.DefaultVernWs); int hvoStemAllomorph = stemAllomorph.Hvo; stemAllomorph.IsAbstract = true; // Delete an affix allomorph hvoLexEntry = aiLexEntries[3]; lexEntry = CmObject.CreateFromDBObject(Cache, hvoLexEntry) as ILexEntry; Assert.IsNotNull(lexEntry); IMoAffixAllomorph affixAllomorph = lexEntry.AlternateFormsOS[1] as IMoAffixAllomorph; Assert.IsNotNull(affixAllomorph); int hvoAffixAllomorph = affixAllomorph.Hvo; lexEntry.AlternateFormsOS.RemoveAt(1); Cache.PropChanged(null, PropChangeType.kpctNotifyAll, hvoLexEntry, (int)LexEntry.LexEntryTags.kflidAlternateForms, 1, 0, 1); // Add a new affix allomorph IMoAffixAllomorph newAffixAllomorph = new MoAffixAllomorph(); lexEntry.AlternateFormsOS.Append(newAffixAllomorph); newAffixAllomorph.Form.SetAlternative("him-new", Cache.DefaultVernWs); int hvoNewAffixAllomorph = newAffixAllomorph.Hvo; Cache.PropChanged(null, PropChangeType.kpctNotifyAll, hvoLexEntry, (int)LexEntry.LexEntryTags.kflidAlternateForms, lexEntry.AlternateFormsOS.Count - 1, 1, 0); // add a compound rule IMoMorphData morphData = lp.MorphologicalDataOA; IMoEndoCompound compRuleNew = new MoEndoCompound(); morphData.CompoundRulesOS.Append(compRuleNew); string sCompRuleName = "new compound rule"; compRuleNew.Name.AnalysisDefaultWritingSystem = sCompRuleName; compRuleNew.HeadLast = true; int hvoPOS = lp.PartsOfSpeechOA.PossibilitiesOS.FirstItem.Hvo; compRuleNew.LeftMsaOA.PartOfSpeechRAHvo = hvoPOS; compRuleNew.RightMsaOA.PartOfSpeechRAHvo = hvoPOS; compRuleNew.OverridingMsaOA.PartOfSpeechRAHvo = hvoPOS; // Change compound rule description const string ksCompRuleDescription = "new description"; compRuleNew.Description.AnalysisDefaultWritingSystem.Text = ksCompRuleDescription; Cache.PropChanged(null, PropChangeType.kpctNotifyAll, morphData.Hvo, (int)MoMorphData.MoMorphDataTags.kflidCompoundRules, morphData.CompoundRulesOS.Count - 1, 1, 0); // delete a compound rule IMoExoCompound compRuleDeleted = morphData.CompoundRulesOS.FirstItem as IMoExoCompound; int hvoCompRuleDeletedLeftMsa = compRuleDeleted.LeftMsaOAHvo; int hvoCompRuleDeletedRightMsa = compRuleDeleted.RightMsaOAHvo; int hvoCompRuleDeletedToMsa = compRuleDeleted.ToMsaOAHvo; morphData.CompoundRulesOS.RemoveAt(0); // add an ad hoc co-prohibition IMoAlloAdhocProhib alloAdHoc = new MoAlloAdhocProhib(); morphData.AdhocCoProhibitionsOC.Add(alloAdHoc); alloAdHoc.Adjacency = 2; alloAdHoc.FirstAllomorphRAHvo = hvoNewAffixAllomorph; alloAdHoc.RestOfAllosRS.Append(hvoNewAffixAllomorph); // change a "rest of allos" in extant ad hoc co-prohibition int[] hvosAdHocProhibs = morphData.AdhocCoProhibitionsOC.HvoArray; IMoAlloAdhocProhib alloAdHocOld = CmObject.CreateFromDBObject(Cache, hvosAdHocProhibs[9]) as IMoAlloAdhocProhib; IMoAffixAllomorph alloAdHicOldFirstRestOfAllos = alloAdHocOld.RestOfAllosRS.FirstItem as IMoAffixAllomorph; IMoAffixAllomorph affixAllomorph2 = lexEntry.AlternateFormsOS[0] as IMoAffixAllomorph; alloAdHocOld.RestOfAllosRS.Append(affixAllomorph2); alloAdHocOld.RestOfAllosRS.RemoveAt(0); alloAdHocOld.Adjacency = 2; //Add a new productivity restriction ICmPossibilityList prodRestricts = morphData.ProdRestrictOA; ICmPossibility prodRestriction = new CmPossibility(); prodRestricts.PossibilitiesOS.Append(prodRestriction); string sNewProdRestrictName = "new exception feature"; prodRestriction.Name.AnalysisDefaultWritingSystem = sNewProdRestrictName; Cache.PropChanged(null, PropChangeType.kpctNotifyAll, prodRestricts.Hvo, (int)CmPossibilityList.CmPossibilityListTags.kflidPossibilities, prodRestricts.PossibilitiesOS.Count - 1, 1, 0); // Change a phonological enviroment string representation IPhPhonData phonData = lp.PhonologicalDataOA; IPhEnvironment env = phonData.EnvironmentsOS.FirstItem; const string ksEnvStringRep = "/ _ [C] [V] a e i o u"; env.StringRepresentation.Text = ksEnvStringRep; // Add a new phonological enviroment string representation IPhEnvironment envNew = new PhEnvironment(); phonData.EnvironmentsOS.Append(envNew); envNew.StringRepresentation.Text = "/ _ m"; int hvoPhonData = phonData.Hvo; Cache.PropChanged(null, PropChangeType.kpctNotifyAll, hvoPhonData, (int)PhPhonData.PhPhonDataTags.kflidEnvironments, phonData.EnvironmentsOS.Count - 1, 1, 0); // Change parser parameters (to test Unicode string field type) string sParserParameters = morphData.ParserParameters.Trim(); int i = sParserParameters.IndexOf("</ParserParameters>"); string sNewParserParameters = sParserParameters.Substring(0, i) + "<HermitCrab><stuff>1</stuff></HermitCrab>" + "</ParserParameters>"; morphData.ParserParameters = sNewParserParameters; // Delete a lex entry int[] hvosEntries = lexdb.EntriesOC.HvoArray; int hvoEntryDeleted = hvosEntries[hvosEntries.Length - 4]; ILexEntry entryDeleted = CmObject.CreateFromDBObject(Cache, hvoEntryDeleted) as ILexEntry; int hvoEntryDeletedLexemeForm = entryDeleted.LexemeFormOAHvo; int[] hvosEntryDeletedAlternateForms = entryDeleted.AlternateFormsOS.HvoArray; int[] hvosEntryDeletedMSAs = entryDeleted.MorphoSyntaxAnalysesOC.HvoArray; int[] hvosEntryDeletedSenses = entryDeleted.SensesOS.HvoArray; //entryDeleted.LexemeFormOA.DeleteUnderlyingObject(); lexdb.EntriesOC.Remove(hvosEntries[hvosEntries.Length - 4]); //Cache.PropChanged(null, PropChangeType.kpctNotifyAll, morphData.Hvo, (int)MoMorphData.MoMorphDataTags.kflidParserParameters, 0, 0, 0); // Create a new lex entry ILexEntry entryNew = new LexEntry(); lexdb.EntriesOC.Add(entryNew); IMoAffixAllomorph alloNew = new MoAffixAllomorph(); entryNew.LexemeFormOA = alloNew; string sNewAlloForm = "dem"; alloNew.Form.VernacularDefaultWritingSystem = sNewAlloForm; alloNew.MorphTypeRA = (IMoMorphType)lexdb.MorphTypesOA.LookupPossibilityByGuid(new Guid(MoMorphType.kguidMorphPrefix)); IMoAffixAllomorph alloNew2 = new MoAffixAllomorph(); entryNew.AlternateFormsOS.Append(alloNew2); string sNewAlloForm2 = "den"; alloNew2.Form.VernacularDefaultWritingSystem = sNewAlloForm2; alloNew2.MorphTypeRA = (IMoMorphType)lexdb.MorphTypesOA.LookupPossibilityByGuid(new Guid(MoMorphType.kguidMorphPrefix)); Cache.PropChanged(null, PropChangeType.kpctNotifyAll, entryNew.Hvo, (int)LexEntry.LexEntryTags.kflidAlternateForms, entryNew.AlternateFormsOS.Count - 1, 1, 0); ILexSense sense = new LexSense(); entryNew.SensesOS.Append(sense); string sGloss = "MeToo"; sense.Gloss.AnalysisDefaultWritingSystem = sGloss; IMoInflAffMsa inflAffixMsa = new MoInflAffMsa(); entryNew.MorphoSyntaxAnalysesOC.Add(inflAffixMsa); sense.MorphoSyntaxAnalysisRA = inflAffixMsa; int[] hvosPOSes = lp.PartsOfSpeechOA.PossibilitiesOS.HvoArray; int hvoVerb = hvosPOSes[12]; inflAffixMsa.PartOfSpeechRAHvo = hvoVerb; IPartOfSpeech pos = CmObject.CreateFromDBObject(Cache, hvoVerb) as IPartOfSpeech; int hvoSlot = pos.AffixSlotsOC.HvoArray[2]; inflAffixMsa.SlotsRC.Add(hvoSlot); Cache.PropChanged(null, PropChangeType.kpctNotifyAll, entryNew.Hvo, (int)LexEntry.LexEntryTags.kflidSenses, entryNew.SensesOS.Count - 1, 1, 0); // Add an inflectional template int[] hvoVerbSubCats = pos.SubPossibilitiesOS.HvoArray; int hvoIntransVerb = hvoVerbSubCats[2]; IPartOfSpeech posVI = CmObject.CreateFromDBObject(Cache, hvoIntransVerb) as IPartOfSpeech; IMoInflAffixTemplate affixTemplate = new MoInflAffixTemplate(); posVI.AffixTemplatesOS.Append(affixTemplate); affixTemplate.Name.AnalysisDefaultWritingSystem = "derived verb"; affixTemplate.Final = false; affixTemplate.SuffixSlotsRS.Append(hvoSlot); Cache.PropChanged(null, PropChangeType.kpctNotifyAll, posVI.Hvo, (int)PartOfSpeech.PartOfSpeechTags.kflidAffixTemplates, posVI.AffixTemplatesOS.Count - 1, 1, 0); // add a phonological feature IFsClosedFeature consFeat = new FsClosedFeature(); Cache.LangProject.PhFeatureSystemOA.FeaturesOC.Add(consFeat); consFeat.Name.AnalysisDefaultWritingSystem = "consonantal"; consFeat.Abbreviation.AnalysisDefaultWritingSystem = "cons"; IFsSymFeatVal consPlus = new FsSymFeatVal(); consFeat.ValuesOC.Add(consPlus); consPlus.SimpleInit("+", "positive"); IFsSymFeatVal consMinus = new FsSymFeatVal(); consFeat.ValuesOC.Add(consMinus); consMinus.SimpleInit("-", "negative"); IFsFeatStrucType fsType = null; if (Cache.LangProject.PhFeatureSystemOA.TypesOC.Count == 0) { fsType = new FsFeatStrucType(); Cache.LangProject.PhFeatureSystemOA.TypesOC.Add(fsType); fsType.Abbreviation.AnalysisDefaultWritingSystem = "Phon"; } else { foreach (IFsFeatStrucType type in Cache.LangProject.PhFeatureSystemOA.TypesOC) { fsType = type; break; } } fsType.FeaturesRS.Append(consFeat); // add a feature-based NC IPhNCFeatures featNC = new PhNCFeatures(); Cache.LangProject.PhonologicalDataOA.NaturalClassesOS.Append(featNC); featNC.Name.AnalysisDefaultWritingSystem = "Consonants (Features)"; featNC.Abbreviation.AnalysisDefaultWritingSystem = "CF"; IFsFeatStruc fs = new FsFeatStruc(); featNC.FeaturesOA = fs; IFsClosedValue val = fs.FindOrCreateClosedValue(consFeat.Hvo); val.FeatureRA = consFeat; val.ValueRA = consPlus; featNC.NotifyNew(); // add phonological rule IPhRegularRule regRule = new PhRegularRule(); Cache.LangProject.PhonologicalDataOA.PhonRulesOS.Append(regRule); regRule.NotifyNew(); regRule.Name.AnalysisDefaultWritingSystem = "regular rule"; IPhSimpleContextSeg segCtxt = new PhSimpleContextSeg(); regRule.RightHandSidesOS[0].StrucChangeOS.Append(segCtxt); IPhPhoneme phoneme = null; foreach (IPhPhoneme phon in Cache.LangProject.PhonologicalDataOA.PhonemeSetsOS[0].PhonemesOC) { phoneme = phon; break; } segCtxt.FeatureStructureRA = phoneme; segCtxt.NotifyNew(); IPhSimpleContextNC ncCtxt = new PhSimpleContextNC(); regRule.RightHandSidesOS[0].LeftContextOA = ncCtxt; ncCtxt.FeatureStructureRA = featNC; ncCtxt.NotifyNew(); // add a morphological rule IMoAffixProcess affRule = new MoAffixProcess(); entryNew.AlternateFormsOS.Append(affRule); affRule.NotifyNew(); ncCtxt = new PhSimpleContextNC(); affRule.InputOS.Append(ncCtxt); ncCtxt.FeatureStructureRA = featNC; ncCtxt.NotifyNew(); IMoCopyFromInput copy = new MoCopyFromInput(); affRule.OutputOS.Append(copy); copy.ContentRA = ncCtxt; copy.NotifyNew(); // ----------- // Update the FXT result // ----------- XmlDocument updatedFxtResult = UpdateFXT(); // ----------- // Test the updated results // ----------- // Test changed stem allomorph: checks on MultiUnicode and boolean node = updatedFxtResult.SelectSingleNode("//MoStemAllomorph[@Id='" + hvoStemAllomorph + "']"); Assert.IsNotNull(node); Assert.AreEqual(stemAllomorph.Form.VernacularDefaultWritingSystem, node.InnerText, "stem allomorph form change failed"); XmlNode contentNode = node.SelectSingleNode("@IsAbstract"); Assert.AreEqual("1", contentNode.InnerText, "stem allomorph is abstract should be true (=1)"); // Test deleted affix allomorph: checks on owning sequence node = updatedFxtResult.SelectSingleNode("//MoAffixAllomorph[@Id='" + hvoAffixAllomorph + "']"); Assert.IsNull(node, "Deleted affix allomorph should be null"); node = updatedFxtResult.SelectSingleNode("//LexEntry[@id='" + hvoLexEntry + "']/AlternateForms[@dst='" + hvoAffixAllomorph + "']"); Assert.IsNull(node, "LexEntry should no longer have deleted alternate form"); // Test added new affix allomorph: checks on owning sequence owned by an item with an @Id; also checks on addition of MoAffixAllomorph via AllAllomorphs string sXPath = "//LexEntry[@Id='" + hvoLexEntry + "']/AlternateForms[@dst='" + hvoNewAffixAllomorph + "']"; node = updatedFxtResult.SelectSingleNode(sXPath); Assert.IsNotNull(node, "LexEntry should have added alternate form"); node = updatedFxtResult.SelectSingleNode("//MoAffixAllomorph[@Id='" + hvoNewAffixAllomorph + "']"); Assert.IsNotNull(node, "Added affix allomorph should be present"); sXPath = "//LexEntry[@Id='" + hvoLexEntry + "']"; node = updatedFxtResult.SelectSingleNode(sXPath); XmlNodeList nodes = node.SelectNodes("AlternateForms"); Assert.AreEqual(3, nodes.Count, "Expected three Alternate forms in lex entry."); //Test newly added compound rule: checks on owning sequence owned by an Id-less element; also on multistring node = updatedFxtResult.SelectSingleNode("//MoEndoCompound[@Id='" + compRuleNew.Hvo + "']"); Assert.IsNotNull(node, "did not find newly added compound rule"); contentNode = node.SelectSingleNode("@HeadLast"); Assert.IsNotNull(contentNode, "missing headlast attribute for coompound rule"); Assert.AreEqual("1", contentNode.InnerText, "compound rule headlast value differs"); contentNode = node.SelectSingleNode("Name"); Assert.IsNotNull(contentNode, "missing Name for compound rule"); Assert.AreEqual(sCompRuleName, contentNode.InnerText, "compound rule name differs"); // check on MultiString contentNode = node.SelectSingleNode("Description"); Assert.AreEqual(ksCompRuleDescription, contentNode.InnerText, "compound rule description differs"); // check on count node = updatedFxtResult.SelectSingleNode("//CompoundRules"); nodes = node.SelectNodes("MoExoCompound | MoEndoCompound"); Assert.AreEqual(6, nodes.Count, "Expected seven compound rules."); // check on owningAtom node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + compRuleNew.LeftMsaOAHvo + "']"); Assert.IsNotNull(node, "missing real MoStemMsa for LeftMsa of newly added compound rule"); node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + compRuleNew.RightMsaOAHvo + "']"); Assert.IsNotNull(node, "missing real MoStemMsa for RightMsa of newly added compound rule"); node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + compRuleNew.OverridingMsaOAHvo + "']"); Assert.IsNotNull(node, "missing real MoStemMsa for OverridingMsa of newly added compound rule"); // Test deleted compound rule node = updatedFxtResult.SelectSingleNode("//MoExoCompound[@Id='" + compRuleDeleted.Hvo + "']"); Assert.IsNull(node, "compound rule should be deleted"); node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + hvoCompRuleDeletedLeftMsa + "']"); Assert.IsNull(node, "compound rule left MSA should be deleted"); node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + hvoCompRuleDeletedRightMsa + "']"); Assert.IsNull(node, "compound rule right MSA should be deleted"); node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + hvoCompRuleDeletedToMsa + "']"); Assert.IsNull(node, "compound rule to MSA should be deleted"); //Test newly added allomorph ad hoc rule: checks on owning collection node = updatedFxtResult.SelectSingleNode("//MoAlloAdhocProhib[@Id='" + alloAdHoc.Hvo + "']"); Assert.IsNotNull(node, "did not find newly added allo ad hoc rule"); contentNode = node.SelectSingleNode("@Adjacency"); Assert.IsNotNull(contentNode, "missing adjacency attribute for allo ad hoc rule"); Assert.AreEqual("2", contentNode.InnerText, "allo ad hoc rule adjacency value differs"); contentNode = node.SelectSingleNode("FirstAllomorph"); Assert.IsNotNull(contentNode, "missing FirstAllomorph for allo ad hoc rule"); contentNode = contentNode.SelectSingleNode("@dst"); Assert.IsNotNull(contentNode, "missing dst attribute of FirstAllomorph for allo ad hoc rule"); Assert.AreEqual(hvoNewAffixAllomorph.ToString(), contentNode.InnerText, "FirstAllomorph of allo ad hoc rule differs"); contentNode = node.SelectSingleNode("RestOfAllos"); Assert.IsNotNull(contentNode, "missing RestOfAllos for allo ad hoc rule"); contentNode = contentNode.SelectSingleNode("@dst"); Assert.IsNotNull(contentNode, "missing dst attribute of RestOfAllos for allo ad hoc rule"); Assert.AreEqual(hvoNewAffixAllomorph.ToString(), contentNode.InnerText, "RestOfAllos of allo ad hoc rule differs"); // test change of a "rest of allos" in extant ad hoc co-prohibition: check on reference sequence node = updatedFxtResult.SelectSingleNode("//MoAlloAdhocProhib[@Id='" + alloAdHocOld.Hvo + "']"); Assert.IsNotNull(node, "did not find old allo ad hoc rule"); contentNode = node.SelectSingleNode("RestOfAllos"); Assert.IsNotNull(contentNode, "missing RestOfAllos for old allo ad hoc rule"); contentNode = contentNode.SelectSingleNode("@dst"); Assert.IsNotNull(contentNode, "missing dst attribute of RestOfAllos for old allo ad hoc rule"); Assert.AreEqual(affixAllomorph2.Hvo.ToString(), contentNode.InnerText, "RestOfAllos of old allo ad hoc rule differs"); nodes = node.SelectNodes("RestOfAllos"); Assert.AreEqual(1, nodes.Count, "count of RestOfAllos of old allo ad hoc rule differs"); // check on integer change contentNode = node.SelectSingleNode("@Adjacency"); Assert.AreEqual("2", contentNode.InnerText, "Adjacency differs"); node = updatedFxtResult.SelectSingleNode("//MoAffixAllomorph[@Id='" + alloAdHicOldFirstRestOfAllos.Hvo + "']"); Assert.IsNotNull(node, "Original RestOfAllos allomorph should still be present"); nodes = updatedFxtResult.SelectNodes("//MoAffixAllomorph[@Id='" + affixAllomorph2.Hvo + "']"); Assert.AreEqual(1, nodes.Count, "Should only be one instance of new allomorph in RestOfAllos"); // Test added productivity restriction: check on CmPossibilityList node = updatedFxtResult.SelectSingleNode("//ProdRestrict/CmPossibility"); Assert.IsNotNull(node, "Did not find newly added productivity restriction"); node = node.SelectSingleNode("Name"); Assert.IsNotNull(node, "Expected Name node in productivity restrictioni"); Assert.AreEqual(sNewProdRestrictName, node.InnerText, "name of productivity restriction differs"); // Test phonological environment string representation: check on string node = updatedFxtResult.SelectSingleNode("//PhEnvironment[@Id='" + env.Hvo + "']/@StringRepresentation"); Assert.AreEqual(ksEnvStringRep, node.InnerText, "phonological environment string differs"); // Test adding a phonological environment string representation: // check on case where parent of owner has Id and is class name; // also check on case where there is a comment/text node within the result nodes node = updatedFxtResult.SelectSingleNode("//PhEnvironment[@Id='" + envNew.Hvo + "']"); Assert.IsNotNull(node, "missing newly added phonological environment"); nodes = updatedFxtResult.SelectNodes("//PhEnvironment"); Assert.AreEqual(11, nodes.Count, "number of PhEnvironments differs"); // Test Parser Parameters: check on unicode string node = updatedFxtResult.SelectSingleNode("//ParserParameters"); string sResultParseParameters = node.OuterXml.Trim(); Assert.AreEqual(sNewParserParameters, sResultParseParameters, "Parser Parameters content differs"); // Test deletion of a lex entry: check on finding LexDb when there is no class LexDb in FXT file nodes = updatedFxtResult.SelectNodes("//LexEntry"); Assert.AreEqual(61, nodes.Count, "number of LexEntries differs"); node = updatedFxtResult.SelectSingleNode("//LexEntry[@Id='" + hvoEntryDeleted + "']"); Assert.IsNull(node, "Deleted lex entry should be missing"); foreach (int hvo in hvosEntryDeletedAlternateForms) { node = updatedFxtResult.SelectSingleNode("//MoStemAllomorph[@Id='" + hvo + "'] | //MoAffixAllomorph[@Id='" + hvo + "']"); Assert.IsNull(node, "deleted entry's alternate form should also be gone"); } foreach (int hvo in hvosEntryDeletedMSAs) { node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + hvo + "']"); Assert.IsNull(node, "deleted entry's msa should also be gone"); } foreach (int hvo in hvosEntryDeletedSenses) { node = updatedFxtResult.SelectSingleNode("//LexSense[@Id='" + hvo + "']"); Assert.IsNull(node, "deleted entry's lexsense should also be gone"); } node = updatedFxtResult.SelectSingleNode("//MoStemAllomorph[@Id='" + hvoEntryDeletedLexemeForm + "']"); Assert.IsNull(node, "deleted entry's lexeme form should also be gone"); // Test adding new entry node = updatedFxtResult.SelectSingleNode("//LexEntry[@Id='" + entryNew.Hvo + "']"); Assert.IsNotNull(node, "new lex entry is missing"); contentNode = node.SelectSingleNode("LexemeForm[@dst='" + alloNew.Hvo + "']"); Assert.IsNotNull(contentNode, "missing lexeme form for new entry"); contentNode = node.SelectSingleNode("AlternateForms[@dst='" + alloNew2.Hvo + "']"); Assert.IsNotNull(contentNode, "missing alternate form in new lex entry"); contentNode = node.SelectSingleNode("Sense[@dst='" + sense.Hvo + "']"); Assert.IsNotNull(contentNode, "missing sense in new lex entry"); contentNode = node.SelectSingleNode("MorphoSyntaxAnalysis[@dst='" + inflAffixMsa.Hvo + "']"); Assert.IsNotNull(contentNode, "missing msa in new lex entry"); contentNode = node.SelectSingleNode("AlternateForms[@dst='" + affRule.Hvo + "']"); Assert.IsNotNull(contentNode, "missing affix process rule in new lex entry"); node = updatedFxtResult.SelectSingleNode("//MoAffixAllomorph[@Id='" + alloNew.Hvo + "']"); Assert.IsNotNull(node, "new lexeme form affix allomorph for new lex entry is missing"); contentNode = node.SelectSingleNode("@MorphType"); Assert.IsNotNull(contentNode, "@MorphType missing for new MoAffixAllomorph in lexeme form of new lex entry"); IMoMorphType typeNew = MoMorphType.CreateFromDBObject(Cache, Convert.ToInt32(contentNode.InnerText)); string sGuidNew = typeNew.Guid.ToString(); Assert.AreEqual(MoMorphType.kguidMorphPrefix, sGuidNew, "morph type wrong for new MoAffixAllomorph in lexeme form of new lex entry"); contentNode = node.SelectSingleNode("Form"); Assert.IsNotNull(contentNode, "Form missing for new MoAffixAllomorph in lexeme form new lex entry"); Assert.AreEqual(sNewAlloForm, contentNode.InnerText, "form wrong for new MoAffixAllomorph in lexeme form of new lex entry"); node = updatedFxtResult.SelectSingleNode("//MoAffixAllomorph[@Id='" + alloNew2.Hvo + "']"); Assert.IsNotNull(node, "new alternate form affix allomorph for new lex entry is missing"); contentNode = node.SelectSingleNode("@MorphType"); Assert.IsNotNull(contentNode, "@MorphType missing for new MoAffixAllomorph in alternate form of new lex entry"); typeNew = MoMorphType.CreateFromDBObject(Cache, Convert.ToInt32(contentNode.InnerText)); sGuidNew = typeNew.Guid.ToString(); Assert.AreEqual(MoMorphType.kguidMorphPrefix, sGuidNew, "morph type wrong for new MoAffixAllomorph in lexeme form of new lex entry"); contentNode = node.SelectSingleNode("Form"); Assert.IsNotNull(contentNode, "Form missing for new MoAffixAllomorph in alternate form new lex entry"); Assert.AreEqual(sNewAlloForm2, contentNode.InnerText, "form wrong for new MoAffixAllomorph in alternate form of new lex entry"); node = updatedFxtResult.SelectSingleNode("//LexSense[@Id='" + sense.Hvo + "']"); Assert.IsNotNull(node, "new sense for new lex entry is missing"); contentNode = node.SelectSingleNode("Gloss"); Assert.IsNotNull(contentNode, "Gloss missing for new LexSense in new lex entry"); Assert.AreEqual(sGloss, contentNode.InnerText, "Gloss wrong for new LexSense in new lex entry"); node = updatedFxtResult.SelectSingleNode("//MoInflAffMsa[@Id='" + inflAffixMsa.Hvo + "']"); Assert.IsNotNull(node, "new infl affix msa for new lex entry is missing"); contentNode = node.SelectSingleNode("@PartOfSpeech"); Assert.IsNotNull(contentNode, "@PartOfSpeech missing for new MoInflAffMsa in new lex entry"); Assert.AreEqual(hvoVerb.ToString(), contentNode.InnerText, "part of speech wrong for new MoInflAffMsa in new lex entry"); contentNode = node.SelectSingleNode("Slots/@dst"); Assert.IsNotNull(contentNode, "Slots missing for new MoInflAffMsa in new lex entry"); Assert.AreEqual(hvoSlot.ToString(), contentNode.InnerText, "slot wrong for new MoInflAffMsa in new lex entry"); // Test adding new template node = updatedFxtResult.SelectSingleNode("//MoInflAffixTemplate[@Id='" + affixTemplate.Hvo + "']"); Assert.IsNotNull(node, "new affix template missing"); node = updatedFxtResult.SelectSingleNode("//PartOfSpeech[@Id='" + hvoIntransVerb + "']/AffixTemplates/MoInflAffixTemplate[@Id='" + affixTemplate.Hvo + "']"); Assert.IsNotNull(node, "new affix template is in intransitive verb"); // Test adding new phonological feature node = updatedFxtResult.SelectSingleNode("//PhFeatureSystem/Features/FsClosedFeature[@Id='" + consFeat.Hvo + "']"); Assert.IsNotNull(node, "new phonological feature is missing"); contentNode = node.SelectSingleNode("Abbreviation"); Assert.IsNotNull(contentNode, "Abbreviation missing from new phonological feature"); Assert.AreEqual(contentNode.InnerText, consFeat.Abbreviation.AnalysisDefaultWritingSystem, "Abbreviation wrong for new phonological feature"); nodes = node.SelectNodes("Values/FsSymFeatVal"); Assert.IsNotNull(nodes, "values missing from new phonological feature"); Assert.AreEqual(nodes.Count, 2, "incorrect number of values in new phonological feature"); node = updatedFxtResult.SelectSingleNode("//PhFeatureSystem/Types/FsFeatStrucType/Features/Feature[@dst='" + consFeat.Hvo + "']"); Assert.IsNotNull(node, "reference to new phonological feature is missing from phonological feature system"); // Test adding new feature-based NC node = updatedFxtResult.SelectSingleNode("//PhNCFeatures[@Id='" + featNC.Hvo + "']"); Assert.IsNotNull(node, "new feature-based NC is missing"); contentNode = node.SelectSingleNode("Abbreviation"); Assert.IsNotNull(contentNode, "Abbreviation missing from new feature-based NC"); Assert.AreEqual(contentNode.InnerText, featNC.Abbreviation.AnalysisDefaultWritingSystem, "Abbreviation wrong for new feature-based NC"); contentNode = node.SelectSingleNode("FsFeatStruc/FsClosedValue[@Id='" + val.Hvo + "']"); Assert.IsNotNull(contentNode, "value missing from new feature-based NC"); Assert.AreEqual((contentNode as XmlElement).GetAttribute("Feature"), consFeat.Hvo.ToString(), "closed value feature is wrong in new feature-based NC"); Assert.AreEqual((contentNode as XmlElement).GetAttribute("Value"), consPlus.Hvo.ToString(), "closed value is wrong in new feature-based NC"); // Test adding new phonological rule node = updatedFxtResult.SelectSingleNode("//PhRegularRule[@Id='" + regRule.Hvo + "']"); Assert.IsNotNull(node, "new phonological rule is missing"); nodes = node.SelectNodes("StrucDesc/*"); Assert.AreEqual(nodes.Count, 0); contentNode = node.SelectSingleNode("RightHandSides/PhSegRuleRHS/StrucChange/PhSimpleContextSeg[@dst='" + phoneme.Hvo + "']"); Assert.IsNotNull(contentNode, "phoneme simple context missing in new phonological rule"); contentNode = node.SelectSingleNode("RightHandSides/PhSegRuleRHS/LeftContext/PhSimpleContextNC[@dst='" + featNC.Hvo + "']"); Assert.IsNotNull(contentNode, "NC simple context missing in new phonological rule"); // Test adding new morphological rule node = updatedFxtResult.SelectSingleNode("//Lexicon/Allomorphs/MoAffixProcess[@Id='" + affRule.Hvo + "']"); Assert.IsNotNull(node, "new morphological rule is missing"); contentNode = node.SelectSingleNode("Input/PhSimpleContextNC[@dst='" + featNC.Hvo + "']"); Assert.IsNotNull(contentNode, "NC simple context missing in new morphological rule"); contentNode = node.SelectSingleNode("Output/MoCopyFromInput/Content[@dst='" + ncCtxt.Hvo + "']"); Assert.IsNotNull(contentNode, "copy from input missing in new morphological rule"); // Modify a phonological rule segCtxt = new PhSimpleContextSeg(); regRule.StrucDescOS.Append(segCtxt); segCtxt.FeatureStructureRA = phoneme; segCtxt.NotifyNew(); regRule.RightHandSidesOS[0].StrucChangeOS[0].DeleteUnderlyingObject(); IPhPhonContext oldCtxt = regRule.RightHandSidesOS[0].LeftContextOA; Cache.LangProject.PhonologicalDataOA.ContextsOS.Append(oldCtxt); IPhSequenceContext seqCtxt = new PhSequenceContext(); regRule.RightHandSidesOS[0].LeftContextOA = seqCtxt; seqCtxt.MembersRS.Append(oldCtxt); seqCtxt.NotifyNew(); IPhSimpleContextBdry bdryCtxt = new PhSimpleContextBdry(); Cache.LangProject.PhonologicalDataOA.ContextsOS.Append(bdryCtxt); bdryCtxt.FeatureStructureRAHvo = Cache.GetIdFromGuid(LangProject.kguidPhRuleWordBdry); bdryCtxt.NotifyNew(); seqCtxt.MembersRS.Append(bdryCtxt); // Modify a morphological rule entryNew.LexemeFormOA = affRule; IMoInsertPhones insertPhones = new MoInsertPhones(); affRule.OutputOS.InsertAt(insertPhones, 0); insertPhones.ContentRS.Append(phoneme); insertPhones.NotifyNew(); affRule.InputOS[1].DeleteUnderlyingObject(); // change order of a sequence vector lexEntry.AlternateFormsOS.InsertAt(newAffixAllomorph, 0); updatedFxtResult = UpdateFXT(); // Test modifying a phonological rule node = updatedFxtResult.SelectSingleNode("//PhRegularRule[@Id='" + regRule.Hvo + "']"); contentNode = node.SelectSingleNode("StrucDesc/PhSimpleContextSeg[@dst='" + phoneme.Hvo + "']"); Assert.IsNotNull(contentNode, "phoneme simple context missing from StrucDesc in modified phonological rule"); contentNode = node.SelectSingleNode("RightHandSides/PhSegRuleRHS/StrucChange/PhSimpleContextSeg[@dst='" + phoneme.Hvo + "']"); Assert.IsNull(contentNode, "phoneme simple context is not missing from StrucChange in modified phonological rule"); contentNode = node.SelectSingleNode("RightHandSides/PhSegRuleRHS/LeftContext/PhSequenceContext[@Id='" + seqCtxt.Hvo + "']"); Assert.IsNotNull(contentNode, "sequence context missing from modified phonological rule"); contentNode = contentNode.SelectSingleNode("Members[@dst='" + bdryCtxt.Hvo + "']"); Assert.IsNotNull(contentNode, "boundary context missing from sequence context in modified phonological rule"); node = updatedFxtResult.SelectSingleNode("//PhPhonData/Contexts/PhSimpleContextBdry[@Id='" + bdryCtxt.Hvo + "']"); Assert.IsNotNull(node, "boundary context missing from contexts in phonological data"); // Test modifying a morphological rule node = updatedFxtResult.SelectSingleNode("//LexEntry[@Id='" + entryNew.Hvo + "']"); contentNode = node.SelectSingleNode("LexemeForm[@dst='" + affRule.Hvo + "']"); Assert.IsNotNull(contentNode, "affix process rule is not the lexeme form for the lex entry"); node = updatedFxtResult.SelectSingleNode("//Lexicon/Allomorphs/MoAffixProcess[@Id='" + affRule.Hvo + "']"); contentNode = node.SelectSingleNode("Input/PhSimpleContextNC[@dst='" + featNC.Hvo + "']"); Assert.IsNull(contentNode, "NC simple context was not removed from morphological rule"); nodes = node.SelectNodes("Output/*"); Assert.AreEqual(nodes.Count, 2, "incorrect number of mappings in morphological rule"); contentNode = node.SelectSingleNode("Output/*[position() = 1 and @Id='" + insertPhones.Hvo + "']"); Assert.IsNotNull(contentNode, "insert phones missing from morphological rule"); // Test changing order of a sequence vector node = updatedFxtResult.SelectSingleNode("//LexEntry[@Id='" + lexEntry.Hvo + "']"); contentNode = node.SelectSingleNode("AlternateForms[@dst='" + lexEntry.AlternateFormsOS[0].Hvo + "']/@ord"); Assert.AreEqual("0", contentNode.InnerText); contentNode = node.SelectSingleNode("AlternateForms[@dst='" + lexEntry.AlternateFormsOS[1].Hvo + "']/@ord"); Assert.AreEqual("1", contentNode.InnerText); contentNode = node.SelectSingleNode("AlternateForms[@dst='" + lexEntry.AlternateFormsOS[2].Hvo + "']/@ord"); Assert.AreEqual("2", contentNode.InnerText); }
public void LexEntryInflTypeAnalysisWithNullForSlotFiller() { IWfiWordform brubs = CheckAnalysisSize("brubsTEST", 0, true); ILexDb ldb = Cache.LanguageProject.LexDbOA; ParseResult result = null; UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { // Verb brub which is a present tense irregularly inflected form of 'believe' // with automatically generated null Tense slot and an -s Plural Number slot filler // (This is not supposed to be English, in case you're wondering....) ILexEntryInflType presentTenseLexEntryInflType = m_lexEntryInflTypeFactory.Create(); Cache.LangProject.LexDbOA.VariantEntryTypesOA.PossibilitiesOS.Add(presentTenseLexEntryInflType); ILexEntry believeV = m_entryFactory.Create(); IMoStemAllomorph believeVForm = m_stemAlloFactory.Create(); believeV.AlternateFormsOS.Add(believeVForm); believeVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("believeVTEST", m_vernacularWS.Handle); IMoStemMsa believeVMsa = m_stemMsaFactory.Create(); believeV.MorphoSyntaxAnalysesOC.Add(believeVMsa); ILexSense believeVSense = m_senseFactory.Create(); believeV.SensesOS.Add(believeVSense); believeVSense.MorphoSyntaxAnalysisRA = believeVMsa; ILexEntry brubV = m_entryFactory.Create(); IMoStemAllomorph brubVForm = m_stemAlloFactory.Create(); brubV.AlternateFormsOS.Add(brubVForm); brubVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("brubVTEST", m_vernacularWS.Handle); ILexEntryRef lexEntryref = m_lexEntryRefFactory.Create(); brubV.EntryRefsOS.Add(lexEntryref); lexEntryref.ComponentLexemesRS.Add(believeV); lexEntryref.VariantEntryTypesRS.Add(presentTenseLexEntryInflType); ILexEntry nullPresent = m_entryFactory.Create(); IMoAffixAllomorph nullPresentForm = m_afxAlloFactory.Create(); nullPresent.AlternateFormsOS.Add(nullPresentForm); nullPresentForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("nullPRESENTTEST", m_vernacularWS.Handle); IMoInflAffMsa nullPresentMsa = m_inflAffMsaFactory.Create(); nullPresent.MorphoSyntaxAnalysesOC.Add(nullPresentMsa); ILexEntry sPlural = m_entryFactory.Create(); IMoAffixAllomorph sPluralForm = m_afxAlloFactory.Create(); sPlural.AlternateFormsOS.Add(sPluralForm); sPluralForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("sPLURALTEST", m_vernacularWS.Handle); IMoInflAffMsa sPluralMsa = m_inflAffMsaFactory.Create(); sPlural.MorphoSyntaxAnalysesOC.Add(sPluralMsa); result = new ParseResult(new[] { new ParseAnalysis(new[] { new ParseMorph(brubVForm, MorphServices.GetMainOrFirstSenseOfVariant(brubV.EntryRefsOS[0]).MorphoSyntaxAnalysisRA, (ILexEntryInflType)brubV.EntryRefsOS[0].VariantEntryTypesRS[0]), new ParseMorph(sPluralForm, sPluralMsa) }) }); }); m_filer.ProcessParse(brubs, ParserPriority.Low, result); ExecuteIdleQueue(); CheckAnalysisSize("brubsTEST", 1, false); var analysis = brubs.AnalysesOC.ElementAt(0); Assert.AreEqual(2, analysis.MorphBundlesOS.Count, "Expected only 2 morphs in the analysis"); var morphBundle = analysis.MorphBundlesOS.ElementAt(0); Assert.IsNotNull(morphBundle.Form, "First bundle: form is not null"); Assert.IsNotNull(morphBundle.MsaRA, "First bundle: msa is not null"); Assert.IsNotNull(morphBundle.InflTypeRA, "First bundle: infl type is not null"); }
public void TwoAnalyses() { int hvoBearTEST = CheckAnalysisSize("bearsTEST", 0, true); string xmlFragment = ""; using (FdoCache cache = FdoCache.Create("TestLangProj")) { ILexDb ldb = cache.LangProject.LexDbOA; // Noun ILexEntry bearN = (ILexEntry)ldb.EntriesOC.Add(new LexEntry()); AddIdToList(bearN.Hvo); IMoStemAllomorph bearNForm = (IMoStemAllomorph)bearN.AlternateFormsOS.Append(new MoStemAllomorph()); bearNForm.Form.VernacularDefaultWritingSystem = "bearNTEST"; IMoStemMsa bearNMSA = (IMoStemMsa)bearN.MorphoSyntaxAnalysesOC.Add(new MoStemMsa()); ILexEntry sPL = (ILexEntry)ldb.EntriesOC.Add(new LexEntry()); AddIdToList(sPL.Hvo); IMoAffixAllomorph sPLForm = (IMoAffixAllomorph)sPL.AlternateFormsOS.Append(new MoAffixAllomorph()); sPLForm.Form.VernacularDefaultWritingSystem = "sPLTEST"; IMoInflAffMsa sPLMSA = (IMoInflAffMsa)sPL.MorphoSyntaxAnalysesOC.Add(new MoInflAffMsa()); // Verb ILexEntry bearV = (ILexEntry)ldb.EntriesOC.Add(new LexEntry()); AddIdToList(bearV.Hvo); IMoStemAllomorph bearVForm = (IMoStemAllomorph)bearV.AlternateFormsOS.Append(new MoStemAllomorph()); bearVForm.Form.VernacularDefaultWritingSystem = "bearVTEST"; IMoStemMsa bearVMSA = (IMoStemMsa)bearV.MorphoSyntaxAnalysesOC.Add(new MoStemMsa()); ILexEntry sAGR = (ILexEntry)ldb.EntriesOC.Add(new LexEntry()); AddIdToList(sAGR.Hvo); IMoAffixAllomorph sAGRForm = (IMoAffixAllomorph)sAGR.AlternateFormsOS.Append(new MoAffixAllomorph()); sAGRForm.Form.VernacularDefaultWritingSystem = "sAGRTEST"; IMoInflAffMsa sAGRMSA = (IMoInflAffMsa)sAGR.MorphoSyntaxAnalysesOC.Add(new MoInflAffMsa()); xmlFragment = "<Wordform DbRef='" + hvoBearTEST.ToString() + "' Form='bearsTEST'>\n" + "<WfiAnalysis>\n" + "<Morphs>\n" + "<Morph>\n" + "<MoForm DbRef='" + bearNForm.Hvo.ToString() + "' Label='bearNTEST'/>\n" + "<MSI DbRef='" + bearNMSA.Hvo.ToString() + "'/>\n" + "</Morph>\n" + "<Morph>\n" + "<MoForm DbRef='" + sPLForm.Hvo.ToString() + "' Label='sPLTEST'/>\n" + "<MSI DbRef='" + sPLMSA.Hvo.ToString() + "'/>\n" + "</Morph>\n" + "</Morphs>\n" + "</WfiAnalysis>\n" + "<WfiAnalysis>\n" + "<Morphs>\n" + "<Morph>\n" + "<MoForm DbRef='" + bearVForm.Hvo.ToString() + "' Label='bearVTEST'/>\n" + "<MSI DbRef='" + bearVMSA.Hvo.ToString() + "'/>\n" + "</Morph>\n" + "<Morph>\n" + "<MoForm DbRef='" + sAGRForm.Hvo.ToString() + "' Label='sAGRTEST'/>\n" + "<MSI DbRef='" + sAGRMSA.Hvo.ToString() + "'/>\n" + "</Morph>\n" + "</Morphs>\n" + "</WfiAnalysis>\n" + "</Wordform>\n"; } m_filer.ProcessParse(MakeXML(xmlFragment, true)); CheckAnalysisSize("bearsTEST", 2, false); }
public void LexEntryInflTypeTwoAnalyses() { IWfiWordform creb = CheckAnalysisSize("crebTEST", 0, true); ILexDb ldb = Cache.LanguageProject.LexDbOA; ParseResult result = null; UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { // Verb creb which is a past tense, plural irregularly inflected form of 'believe' and also 'seek' // with automatically generated null Tense slot and an automatically generated null Number slot filler // (This is not supposed to be English, in case you're wondering....) ILexEntryInflType pastTenseLexEntryInflType = m_lexEntryInflTypeFactory.Create(); ILexEntryInflType pluralTenseLexEntryInflType = m_lexEntryInflTypeFactory.Create(); Cache.LangProject.LexDbOA.VariantEntryTypesOA.PossibilitiesOS.Add(pastTenseLexEntryInflType); Cache.LangProject.LexDbOA.VariantEntryTypesOA.PossibilitiesOS.Add(pluralTenseLexEntryInflType); ILexEntry believeV = m_entryFactory.Create(); IMoStemAllomorph believeVForm = m_stemAlloFactory.Create(); believeV.AlternateFormsOS.Add(believeVForm); believeVForm.Form.VernacularDefaultWritingSystem = TsStringUtils.MakeString("believeVTEST", m_vernacularWS.Handle); IMoStemMsa believeVMsa = m_stemMsaFactory.Create(); believeV.MorphoSyntaxAnalysesOC.Add(believeVMsa); ILexSense believeVSense = m_senseFactory.Create(); believeV.SensesOS.Add(believeVSense); believeVSense.MorphoSyntaxAnalysisRA = believeVMsa; ILexEntry seekV = m_entryFactory.Create(); IMoStemAllomorph seekVForm = m_stemAlloFactory.Create(); believeV.AlternateFormsOS.Add(seekVForm); seekVForm.Form.VernacularDefaultWritingSystem = TsStringUtils.MakeString("seekVTEST", m_vernacularWS.Handle); IMoStemMsa seekVMsa = m_stemMsaFactory.Create(); seekV.MorphoSyntaxAnalysesOC.Add(seekVMsa); ILexSense seekVSense = m_senseFactory.Create(); seekV.SensesOS.Add(seekVSense); seekVSense.MorphoSyntaxAnalysisRA = seekVMsa; ILexEntry crebV = m_entryFactory.Create(); IMoStemAllomorph crebVForm = m_stemAlloFactory.Create(); crebV.AlternateFormsOS.Add(crebVForm); crebVForm.Form.VernacularDefaultWritingSystem = TsStringUtils.MakeString("crebVTEST", m_vernacularWS.Handle); ILexEntryRef lexEntryref = m_lexEntryRefFactory.Create(); crebV.EntryRefsOS.Add(lexEntryref); lexEntryref.ComponentLexemesRS.Add(believeV); lexEntryref.VariantEntryTypesRS.Add(pastTenseLexEntryInflType); lexEntryref.VariantEntryTypesRS.Add(pluralTenseLexEntryInflType); lexEntryref = m_lexEntryRefFactory.Create(); crebV.EntryRefsOS.Add(lexEntryref); lexEntryref.ComponentLexemesRS.Add(seekV); lexEntryref.VariantEntryTypesRS.Add(pastTenseLexEntryInflType); lexEntryref.VariantEntryTypesRS.Add(pluralTenseLexEntryInflType); ILexEntry nullPast = m_entryFactory.Create(); IMoAffixAllomorph nullPastForm = m_afxAlloFactory.Create(); nullPast.AlternateFormsOS.Add(nullPastForm); nullPastForm.Form.VernacularDefaultWritingSystem = TsStringUtils.MakeString("nullPASTTEST", m_vernacularWS.Handle); IMoInflAffMsa nullPastMsa = m_inflAffMsaFactory.Create(); nullPast.MorphoSyntaxAnalysesOC.Add(nullPastMsa); ILexEntry nullPlural = m_entryFactory.Create(); IMoAffixAllomorph nullPluralForm = m_afxAlloFactory.Create(); nullPlural.AlternateFormsOS.Add(nullPluralForm); nullPluralForm.Form.VernacularDefaultWritingSystem = TsStringUtils.MakeString("nullPLURALTEST", m_vernacularWS.Handle); IMoInflAffMsa nullPluralMsa = m_inflAffMsaFactory.Create(); nullPlural.MorphoSyntaxAnalysesOC.Add(nullPluralMsa); result = new ParseResult(new[] { new ParseAnalysis(new[] { new ParseMorph(crebVForm, MorphServices.GetMainOrFirstSenseOfVariant(crebV.EntryRefsOS[1]).MorphoSyntaxAnalysisRA, (ILexEntryInflType)crebV.EntryRefsOS[1].VariantEntryTypesRS[0]) }), new ParseAnalysis(new[] { new ParseMorph(crebVForm, MorphServices.GetMainOrFirstSenseOfVariant(crebV.EntryRefsOS[0]).MorphoSyntaxAnalysisRA, (ILexEntryInflType)crebV.EntryRefsOS[0].VariantEntryTypesRS[0]) }) }); }); m_filer.ProcessParse(creb, ParserPriority.Low, result); ExecuteIdleQueue(); CheckAnalysisSize("crebTEST", 2, false); foreach (var analysis in creb.AnalysesOC) { Assert.AreEqual(1, analysis.MorphBundlesOS.Count, "Expected only 1 morph in the analysis"); var morphBundle = analysis.MorphBundlesOS.ElementAt(0); Assert.IsNotNull(morphBundle.Form, "First bundle: form is not null"); Assert.IsNotNull(morphBundle.MsaRA, "First bundle: msa is not null"); Assert.IsNotNull(morphBundle.InflTypeRA, "First bundle: infl type is not null"); } }
private void CacheEnvironments(IMoAffixAllomorph allomorph) { int[] hvos; if (m_rootFlid == MoAffixAllomorphTags.kflidPhoneEnv) hvos = allomorph.PhoneEnvRC.ToHvoArray(); else hvos = allomorph.PositionRS.ToHvoArray(); CacheEnvironments(hvos); AppendPhoneEnv(kDummyPhoneEnvID, null); }
/// <summary> /// Handle launching of the MSA editor. /// </summary> protected override void HandleChooser() { VectorReferenceLauncher vrl = null; using (MsaInflectionFeatureListDlg dlg = new MsaInflectionFeatureListDlg()) { IFsFeatStruc originalFs = m_obj as IFsFeatStruc; Slice parentSlice = Slice; if (originalFs == null) { int owningFlid; int parentSliceClass = parentSlice.Object.ClassID; switch (parentSliceClass) { case MoAffixAllomorph.kclsidMoAffixAllomorph: IMoAffixAllomorph allo = parentSlice.Object as IMoAffixAllomorph; owningFlid = (parentSlice as MsaInflectionFeatureListDlgLauncherSlice).Flid; dlg.SetDlgInfo(m_cache, m_mediator, allo, owningFlid); break; default: IMoMorphSynAnalysis msa = parentSlice.Object as IMoMorphSynAnalysis; owningFlid = (parentSlice as MsaInflectionFeatureListDlgLauncherSlice).Flid; dlg.SetDlgInfo(m_cache, m_mediator, msa, owningFlid); break; } } else { dlg.SetDlgInfo(m_cache, m_mediator, originalFs); } const string ksPath = "/group[@id='Linguistics']/group[@id='Morphology']/group[@id='FeatureChooser']/"; dlg.Text = m_mediator.StringTbl.GetStringWithXPath("InflectionFeatureTitle", ksPath); dlg.Prompt = m_mediator.StringTbl.GetStringWithXPath("InflectionFeaturePrompt", ksPath); dlg.LinkText = m_mediator.StringTbl.GetStringWithXPath("InflectionFeatureLink", ksPath); DialogResult result = dlg.ShowDialog(parentSlice.FindForm()); if (result == DialogResult.OK) { if (dlg.FS != null) { m_obj = dlg.FS; } m_msaInflectionFeatureListDlgLauncherView.Init(m_mediator, dlg.FS); } else if (result == DialogResult.Yes) { // Get the VectorReferenceLauncher for the Inflection Features slice. // Since we're not changing tools, we want to change the chooser dialog. // See LT-5913 for motivation. Control ctl = this.Parent; while (ctl != null && !(ctl is Slice)) { ctl = ctl.Parent; } Slice slice = ctl as Slice; if (slice != null) { DataTree dt = slice.ContainingDataTree; for (int i = 0; i < dt.Controls.Count; ++i) { Slice sliceT = dt.FieldOrDummyAt(i); vrl = sliceT.Control as VectorReferenceLauncher; if (vrl != null) { if (vrl.Flid == (int)PartOfSpeech.PartOfSpeechTags.kflidInflectableFeats) { break; } vrl = null; } } } if (vrl == null) { // We do, too, need to change tools! Sometimes this slice shows up in a different context, // such as the main data entry view. See LT-7167. // go to m_highestPOS in editor // TODO: this should be reviewed by someone who knows how these links should be done // I'm just guessing. // Also, is there some way to know the application name and tool name without hard coding them? FdoUi.FwLink linkJump = new SIL.FieldWorks.FdoUi.FwLink("Language Explorer", "posEdit", dlg.HighestPOS.Guid, m_cache.ServerName, m_cache.DatabaseName); m_mediator.PostMessage("FollowLink", linkJump); } else { vrl.HandleExternalChooser(); } } } }