/// <summary> /// Check for and deal with moves that should not be allowed. /// Previously the only disallowed move was one that reorganized a chart template that is in use. /// This is not the optimum place to 'know' about this, but I (JohnT) am not sure where is. /// Now we are disallowing certain moves within the TextMarkup Tags list too, so I (GordonM) have /// refactored a bit. /// Review: Should these be pulled out to the PossibilityTreeBarHandler subclass? /// </summary> /// <param name="hvoMove"></param> /// <param name="hvoDest"></param> /// <returns>true if a problem was reported and the move should be cancelled.</returns> private bool CheckAndReportForbiddenMove(int hvoMove, int hvoDest) { FdoCache cache = (FdoCache)m_mediator.PropertyTable.GetValue("cache"); CmPossibility movingPossItem = CmObject.CreateFromDBObject(cache, hvoMove) as CmPossibility; if (movingPossItem != null) { ICmPossibility rootPoss = movingPossItem.MainPossibility; int hvoRootItem = rootPoss.Hvo; int hvoPossList = rootPoss.OwningList.Hvo; // If we get here hvoPossList is a possibility list and hvoRootItem is a top level item in that list // and movingPossItem is, or is a subpossibility of, that top level item. // 1. Check to see if hvoRootItem is a chart template containing our target. // If so, hvoPossList is owned in the chart templates property. if (cache.GetOwningFlidOfObject(hvoPossList) == (int)DsDiscourseData.DsDiscourseDataTags.kflidConstChartTempl) { return(CheckAndReportBadDiscourseTemplateMove(cache, movingPossItem, hvoRootItem, hvoPossList, hvoDest)); } // 2. Check to see if hvoRootItem is a TextMarkup TagList containing our target (i.e. a Tag type). // If so, hvoPossList is owned in the text markup tags property. if (cache.GetOwningFlidOfObject(hvoPossList) == (int)LangProject.LangProjectTags.kflidTextMarkupTags) { return(CheckAndReportBadTagListMove(cache, movingPossItem, hvoRootItem, hvoPossList, hvoDest)); } } return(false); // not detecting problems with moving other kinds of things. }
public void FindOrCreateAnnotationCategory_AbsentCategory_ThirdLevel() { Assert.AreEqual(1, m_possList.PossibilitiesOS[1].SubPossibilitiesOS[1].SubPossibilitiesOS.Count); int hvoPossibility = m_scr.NoteCategoriesOA.FindOrCreatePossibility( "Level 1a" + StringUtils.kchObject + "New Level 2 Category" + StringUtils.kchObject + "New Level 3 Category", m_wsSpanish); // Confirm that a new third-level node was created. CmPossibility newCategory = new CmPossibility(m_inMemoryCache.Cache, hvoPossibility); Assert.AreEqual("New Level 3 Category", newCategory.Name.GetAlternativeTss(m_wsSpanish).Text); // Confirm that a new parent node for the third-level node was created on the second level. Assert.AreEqual(1, m_possList.PossibilitiesOS[0].SubPossibilitiesOS.Count, "Another category CmPossibility should have been created on second level under Level 1a."); Assert.AreEqual(1, m_possList.PossibilitiesOS[0].SubPossibilitiesOS[0].SubPossibilitiesOS.Count); Assert.IsTrue(newCategory.Owner is ICmPossibility, "Category should have been created under another category CmPossibility"); Assert.AreEqual("New Level 2 Category", ((CmPossibility)newCategory.Owner).Name.GetAlternativeTss(m_wsSpanish).Text); Assert.IsTrue(((CmPossibility)newCategory.Owner).Owner is ICmPossibility); CmPossibility level1Possibility = (CmPossibility)((CmPossibility)newCategory.Owner).Owner; Assert.AreEqual("Level 1a", level1Possibility.Name.GetAlternativeTss(m_wsSpanish).Text); }
public CmPossibility MakeTemplate(out List <int> allCols) { // The exact organization of columns is not of great // importance for the current tests (still less the names), but we do want there // to be a hierarchy, since that is a common problem, and naming them conventionally // may make debugging easier. Currently this is the same set of columns as // m_logic.CreateDefaultColumns, but we make it explicit here so most of the test // code is unaffected by changes to the default. XmlDocument doc = new XmlDocument(); doc.LoadXml( "<template name=\"default\">" + "<column name=\"prenuclear\">" + "<column name=\"prenuc1\"/>" + "<column name=\"prenuc2\"/>" + "</column>" + "<column name=\"nucleus\">" + "<column name=\"Subject\"/>" + "<column name=\"verb\"/>" + "<column name=\"object\"/>" + "</column>" + "<column name=\"postnuc\"/>" + "</template>"); m_template = (CmPossibility)m_cache.LangProject.CreateChartTemplate(doc.DocumentElement); //m_template = m_logic.CreateTemplate(doc.DocumentElement); m_allColumns = m_logic.AllColumns(m_template); allCols = m_allColumns; return(m_template); }
protected virtual void SetInfoBarText() { if (m_informationBar == null) { return; } string className = StringTbl.GetString("No Records", "Misc"); if (Clerk.CurrentObject != null) { string typeName = Clerk.CurrentObject.GetType().Name; if (Clerk.CurrentObject is CmPossibility) { CmPossibility possibility = Clerk.CurrentObject as CmPossibility; className = possibility.ItemTypeName(StringTbl); } else { className = StringTbl.GetString(typeName, "ClassNames"); } if (className == "*" + typeName + "*") { className = typeName; } } // This code: ((IPaneBar)m_informationBar).Text = className; // causes about 47 of the following exceptions when executed in Flex. // First-chance exception at 0x4ed9b280 in Flex.exe: 0xC0000005: Access violation writing location 0x00f90004. // The following code doesn't cause the exception, but neither one actually sets the Text to className, // so something needs to be changed somewhere. It doesn't enter "override string Text" in PaneBar.cs (m_informationBar as IPaneBar).Text = className; }
public void ModifyVectors(LangProject lp) { //add a new item to an owned sequence attribute CmAnthroItem a = (CmAnthroItem)lp.AnthroListOA.PossibilitiesOS.Append(new CmAnthroItem()); //add a new item to an owned collection attribute CmOverlay overlay = (CmOverlay)lp.OverlaysOC.Add(new CmOverlay()); //add a new item to a reference collection attribute CmPossibility position = (CmPossibility)lp.PositionsOA.PossibilitiesOS [0]; CmPerson person = (CmPerson)lp.PeopleOA.PossibilitiesOS[0]; person.PositionsRC.Add(position); //move the last item in a sequence to the beginning FdoOwnSeqVector positions = lp.PositionsOA.PossibilitiesOS; position = (CmPossibility)positions[positions.Count - 1]; positions.InsertAt(position, 0); //do the same, without instantiating the object we're moving int hvo = positions.hvoArray[positions.Count - 1]; positions.InsertAt(hvo, 0); }
public void DBObjectInstantiation() { CheckDisposed(); // Putting persons in the UsageTypes doesn't really make sense, but for testing purposes // it doesn't matter what we store there as long as it is derived from CmPossibility CmPerson person = new CmPerson(); CmPossibility pos = new CmPossibility(); Cache.LangProject.LexDbOA.UsageTypesOA.PossibilitiesOS.Append(person); Cache.LangProject.LexDbOA.UsageTypesOA.PossibilitiesOS.Append(pos); int khvoAPossibiltyObject = pos.Hvo; int khvoAPersonObject = person.Hvo; Assert.AreEqual("CmPerson", CmPossibility.CreateFromDBObject(Cache, khvoAPersonObject).GetType().Name); Assert.AreEqual("CmPossibility", CmPossibility.CreateFromDBObject(Cache, khvoAPossibiltyObject).GetType().Name); // Now try it not assuming anything about the class type (use the method on CmObject) // CmObject uses a different, less efficient method. Assert.AreEqual("CmPerson", CmObject.CreateFromDBObject(Cache, khvoAPersonObject).GetType().Name); // trying to turn a possibility into a person should throw an exception CmPerson.CreateFromDBObject(Cache, khvoAPossibiltyObject); }
/// <summary> /// Checks for and reports any disallowed tag list moves. /// </summary> /// <param name="cache"></param> /// <param name="movingTagItem">The proposed tag item to move.</param> /// <param name="hvoSubListRoot">The hvo of the top-level Tag Type Possibility containing the moving item.</param> /// <param name="hvoMainTagList">The hvo of the main PossiblityList grouping all TextMarkup Tags.</param> /// <param name="hvoDest">The hvo of the destination tag item.</param> /// <returns>true if we found and reported a bad move.</returns> private bool CheckAndReportBadTagListMove(FdoCache cache, CmPossibility movingTagItem, int hvoSubListRoot, int hvoMainTagList, int hvoDest) { // Check if movingTagItem is a top-level Tag Type. if (movingTagItem.Hvo == hvoSubListRoot) { if (hvoDest == hvoMainTagList) // top-level Tag Type can move to main list (probably already there) { return(false); } // The moving item is a top-level Tag Type, it cannot be demoted. MessageBox.Show(m_tree, xWorksStrings.ksCantDemoteTagList, xWorksStrings.ksProhibitedMovement, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(true); } // Unless something is badly wrong, the destination is either the tag type root, // a tag one level down from the root, or the base list. if (cache.GetOwnerOfObject(hvoDest) == hvoMainTagList) { // Destination is Tag Type root, not a problem return(false); } if (hvoDest == hvoMainTagList) { // Can't promote tag to Tag Type root MessageBox.Show(m_tree, xWorksStrings.ksCantPromoteTag, xWorksStrings.ksProhibitedMovement, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(true); } // This would give us hierarchy too deep (at least for now) MessageBox.Show(m_tree, xWorksStrings.ksTagListTooDeep, xWorksStrings.ksProhibitedMovement, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(true); }
private static void InitItem(XmlNode item, ICmPossibility poss) { var defAnalWs = poss.Cache.DefaultAnalWs; var strFact = poss.Cache.TsStrFactory; // Set name property poss.Name.set_String( defAnalWs, strFact.MakeString( XmlUtils.GetManditoryAttributeValue(item, "name"), defAnalWs)); // Set Abbreviation. var abbr = XmlUtils.GetOptionalAttributeValue(item, "abbr"); if (String.IsNullOrEmpty(abbr)) { abbr = poss.Name.AnalysisDefaultWritingSystem.Text; } poss.Abbreviation.set_String( defAnalWs, strFact.MakeString( abbr, defAnalWs)); // Create optional child items. foreach (XmlNode subItem in item.ChildNodes) { var poss2 = new CmPossibility(); poss.SubPossibilitiesOS.Add(poss2); InitItem(subItem, poss2); } }
internal ICmPossibility CreateColumn(ICmPossibility parent, XmlNode spec) { var result = new CmPossibility(); parent.SubPossibilitiesOS.Add(result); SetNameAndChildColumns(result, spec); return(result); }
private void MakeListXml(ICmPossibilityList list, XmlElement root) { foreach (XmlNode item in root) { var poss = new CmPossibility(); list.PossibilitiesOS.Add(poss); InitItem(item, poss); } }
/// <summary> /// add any subitems to the tree. Note! This assumes that the list has been preloaded /// (e.g., using PreLoadList), so it bypasses normal load operations for speed purposes. /// Withoug preloading, it took almost 19,000 queries to start FW showing semantic domain /// list. With preloading it reduced the number to 200 queries. /// </summary> /// <param name="obj"></param> /// <param name="parentsCollection"></param> protected override void AddSubNodes(ICmObject obj, TreeNodeCollection parentsCollection) { ICmPossibility pss = obj as ICmPossibility; foreach (int hvoSub in pss.SubPossibilities()) { // Assume its basic information has already been loaded using PreLoadList. CmPossibility sub = CmPossibility.CreateFromDBObject(obj.Cache, hvoSub, false) as CmPossibility; AddTreeNode(sub, parentsCollection); } }
public override void Exit() { m_chart = null; m_template = null; m_allColumns = null; m_mockRibbon = null; m_logic = null; m_firstParaWfics = null; base.Exit(); }
/// <summary> /// Create a List of ColumnMenuItems for ComboBox based on an array of column hvos. /// </summary> /// <param name="hvoArray"></param> internal void CollectColumnsToCombo(int[] hvoArray) { int ccols = hvoArray.Length; ColumnMenuItem[] cols = new ColumnMenuItem[ccols]; for (int i = 0; i < ccols; i++) { cols[i] = new ColumnMenuItem(CmPossibility.CreateFromDBObject(Cache, hvoArray[i])); } SentElem.ComboCols = cols; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Creates the categories. /// </summary> /// <param name="cache">The cache.</param> /// <param name="list">The possibility (category) list.</param> /// <param name="ws">The writing system for setting the category names.</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ internal static ICmPossibilityList CreateCategories(FdoCache cache, ICmPossibilityList list, int ws) { list = cache.LangProject.TranslatedScriptureOA.NoteCategoriesOA; // Initialize text. ITsPropsBldr ttpBldr = TsPropsBldrClass.Create(); ttpBldr.SetIntPropValues((int)FwTextPropType.ktptWs, (int)FwTextPropVar.ktpvDefault, ws); ITsStrBldr tsStrBldr = TsStrBldrClass.Create(); // Set possibilities on top level--"Level 1a" CmPossibility possibility1a = new CmPossibility(); list.PossibilitiesOS.Append(possibility1a); tsStrBldr.ReplaceRgch(0, 0, "Level 1a", 8, ttpBldr.GetTextProps()); possibility1a.Name.SetAlternative(tsStrBldr.GetString(), ws); // Add another on top level--"Level 1b" CmPossibility possibility1b = new CmPossibility(); list.PossibilitiesOS.Append(possibility1b); tsStrBldr.ReplaceRgch(0, tsStrBldr.Length, "Level 1b", 8, ttpBldr.GetTextProps()); possibility1b.Name.SetAlternative(tsStrBldr.GetString(), ws); // Add possibilities on second level under "Level 1b"--"Level 2a" CmPossibility subPossibility2a = new CmPossibility(); possibility1b.SubPossibilitiesOS.Append(subPossibility2a); tsStrBldr.ReplaceRgch(0, tsStrBldr.Length, "Level 2a, parent is 1b", 22, ttpBldr.GetTextProps()); subPossibility2a.Name.SetAlternative(tsStrBldr.GetString(), ws); // Add "Level 2b" under "Level 1b" CmPossibility subPossibility2b = new CmPossibility(); possibility1b.SubPossibilitiesOS.Append(subPossibility2b); tsStrBldr.ReplaceRgch(0, tsStrBldr.Length, "Level 2b, parent is 1b", 22, ttpBldr.GetTextProps()); subPossibility2b.Name.SetAlternative(tsStrBldr.GetString(), ws); // Add "Level 3" under "Level 2b" CmPossibility subSubPossibility3 = new CmPossibility(); subPossibility2b.SubPossibilitiesOS.Append(subSubPossibility3); tsStrBldr.ReplaceRgch(0, tsStrBldr.Length, "Level 3, parent is 2b", 21, ttpBldr.GetTextProps()); subSubPossibility3.Name.SetAlternative(tsStrBldr.GetString(), ws); return(list); }
public void FindOrCreateAnnotationCategory_AbsentCategory_FirstLevel() { Assert.AreEqual(2, m_possList.PossibilitiesOS.Count); int hvoPossibility = m_scr.NoteCategoriesOA.FindOrCreatePossibility( "New Category", m_wsSpanish); // Confirm that a "New Category" category has been created at the top level. Assert.AreEqual(3, m_possList.PossibilitiesOS.Count, "Another category CmPossibility should have been created on first level."); CmPossibility newCategory = new CmPossibility(m_inMemoryCache.Cache, hvoPossibility); Assert.AreEqual("New Category", newCategory.Name.GetAlternativeTss(m_wsSpanish).Text); Assert.IsFalse(newCategory.Owner is ICmPossibility, "Category should have been created at the top level"); }
public void FindOrCreateAnnotationCategory_NameOnlyButAbsent() { int initialCategoryCount = m_possList.PossibilitiesOS.Count; int hvoPossibility = m_scr.NoteCategoriesOA.FindOrCreatePossibility( "New category", m_wsSpanish, false); // Confirm that a new category was added and that FindOrCreatePossibility returns it. Assert.AreEqual(initialCategoryCount + 1, m_possList.PossibilitiesOS.Count); CmPossibility newCategory = new CmPossibility(Cache, hvoPossibility); int actualWs; Assert.AreEqual("New category", newCategory.Name.GetAlternativeOrBestTss(m_wsSpanish, out actualWs).Text, "The newly-created category was not found"); Assert.AreEqual(m_wsSpanish, actualWs, "The new category name was not found in the expected writing system"); }
protected override void CreateTestData() { base.CreateTestData(); m_firstParaWfics = m_helper.MakeAnnotations(m_firstPara); m_logic = new TestCCLogic(Cache, m_chart, m_stText.Hvo); m_helper.Logic = m_logic; m_logic.Ribbon = m_mockRibbon = new MockRibbon(Cache, m_stText.Hvo); m_template = m_helper.MakeTemplate(out m_allColumns); // Note: do this AFTER creating the template, which may also create the DiscourseData object. m_chart = new DsConstChart(); Cache.LangProject.DiscourseDataOA.ChartsOC.Add(m_chart); m_chart.TemplateRA = m_template; m_logic.Chart = m_chart; m_helper.MakeDefaultChartMarkers(); m_helper.Chart = m_chart; }
/// <summary> /// Checks for and reports any disallowed discourse template moves. /// </summary> /// <param name="cache"></param> /// <param name="movingColumn">The proposed possibility item (template column) to move.</param> /// <param name="hvoTemplate">The hvo of the affected Chart Template (only 'default' exists so far).</param> /// <param name="hvoTemplateList">The hvo of the Template List.</param> /// <param name="hvoDest">The hvo of the destination item.</param> /// <returns>true means we found and reported a bad move.</returns> private bool CheckAndReportBadDiscourseTemplateMove(FdoCache cache, CmPossibility movingColumn, int hvoTemplate, int hvoTemplateList, int hvoDest) { // First, check whether we're allowed to manipulate this column at all. This is the same check as // whether we're allowed to delete it. if (movingColumn.CheckAndReportProtectedChartColumn()) { return(true); } // Other things being equal, we now need to make sure we aren't messing up the chart levels // Unless something is badly wrong, the destination is either the root template, // a column group one level down from the root template, a column two levels down, // or the base list. if (hvoDest == hvoTemplateList) { MessageBox.Show(m_tree, xWorksStrings.ksCantPromoteGroupToTemplate, xWorksStrings.ksProhibitedMovement, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(true); } // if the destination IS the root, that's fine...anything can move there. if (hvoDest == hvoTemplate) { return(false); } // It's OK to move a leaf to a group (one level down from the root, as long as // the destination 'group' isn't a column that's in use. bool moveColumnIsLeaf = movingColumn.SubPossibilitiesOS.Count == 0; if (cache.GetOwnerOfObject(hvoDest) == hvoTemplate && moveColumnIsLeaf) { CmPossibility dest = (CmPossibility.CreateFromDBObject(cache, hvoDest)) as CmPossibility; // If it isn't already a group, we can only turn it into one if it's empty if (dest.SubPossibilitiesOS.Count == 0) { return(dest.CheckAndReportProtectedChartColumn()); } // If it's already a group it should be fine as a destination. return(false); } // Anything else represents an attempt to make the tree too deep, e.g., moving a // column into child column, or a group into another group. MessageBox.Show(m_tree, xWorksStrings.ksTemplateTooDeep, xWorksStrings.ksProhibitedMovement, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(true); }
protected override void CreateTestData() { base.CreateTestData(); m_cclogic = new TestCCLogic(Cache, m_chart, m_stText.Hvo); m_helper.Logic = m_cclogic; m_template = m_helper.MakeTemplate(out m_allColumns); // Note: do this AFTER creating the template, which may also create the DiscourseData object. m_chart = new DsConstChart(); Cache.LangProject.DiscourseDataOA.ChartsOC.Add(m_chart); m_chart.TemplateRA = m_template; m_cclogic.Chart = m_chart; m_cclogic.Ribbon = m_mockRibbon = new MockRibbon(Cache, m_stText.Hvo); m_helper.Chart = m_chart; m_origCell = null; // Test must fill in the ClickedCell in the CChartSentenceElements object m_eligCols = m_allColumns.ToArray(); // CChartSentenceElements always starts with all columns m_eligRows = null; // Test must fill in EligibleRows in the CChartSentenceElements object m_sentElem = new CChartSentenceElements(m_origCell, m_eligRows, m_eligCols); m_dlgLogicPrepose = new AdvancedMTDialogLogic(Cache, true, m_sentElem); m_dlgLogicPostpose = new AdvancedMTDialogLogic(Cache, false, m_sentElem); // create one each direction; test both }
/// ------------------------------------------------------------------------------------ /// <summary> /// Fill in a note category node in the database from an XML node /// </summary> /// <param name="hvoOwner">owner's id</param> /// <param name="ownFlid">field ID in which the category is owned</param> /// <param name="index">0-based position in the list of possibilities</param> /// <param name="node">XML node to get info from</param> /// ------------------------------------------------------------------------------------ private void CreateNoteCategory(int hvoOwner, int ownFlid, int index, XmlNode node) { int hvoPossibility = m_scr.Cache.MainCacheAccessor.MakeNewObject( CmPossibility.kClassId, hvoOwner, ownFlid, index); Debug.Assert(hvoPossibility > 0); CmPossibility category = new CmPossibility(m_scr.Cache, hvoPossibility); SetMultiUnicodeAlternatives(category.Name, node.SelectNodes("name")); SetMultiUnicodeAlternatives(category.Abbreviation, node.SelectNodes("abbreviation")); // get the description for the note category XmlNodeList descNodes = node.SelectNodes("description"); if (descNodes != null) { foreach (XmlNode descNode in descNodes) { int ws = GetWs(descNode.Attributes); string alternative = descNode.InnerText; if (ws > 0 && alternative != null && alternative != string.Empty) { category.Description.GetAlternative(ws).UnderlyingTsString = m_strFactory.MakeString(alternative, ws); } // REVIEW: What should we do when the writing system is not defined in the database? } } // create note categories for any subcategories int subIndex = 0; foreach (XmlNode categoryNode in node.SelectNodes("category")) { CreateNoteCategory(hvoPossibility, (int)CmPossibility.CmPossibilityTags.kflidSubPossibilities, subIndex++, categoryNode); } }
protected override void CreateTestData() { base.CreateTestData(); m_firstParaWfics = m_helper.MakeAnnotations(m_firstPara); m_logic = new TestCCLogic(Cache, m_chart, m_stText.Hvo); // m_chart is still null! m_helper.Logic = m_logic; m_logic.Ribbon = m_mockRibbon = new MockRibbon(Cache, m_stText.Hvo); m_template = m_helper.MakeTemplate(out m_allColumns); // Note: do this AFTER creating the template, which may also create the DiscourseData object. m_chart = new DsConstChart(); Cache.LangProject.DiscourseDataOA.ChartsOC.Add(m_chart); m_chart.TemplateRA = m_template; m_logic.Chart = m_chart; m_helper.MakeDefaultChartMarkers(); m_helper.Chart = m_chart; m_constChart = new ConstituentChart(Cache, m_logic); m_constChart.Init(null, null); m_chartBody = m_constChart.Body; m_chartBody.Cache = Cache; // don't know why constructor doesn't do this, but it doesn't. m_chartBody.SetRoot(m_chart.Hvo, m_allColumns.ToArray()); }
/// <summary> /// Move the clicked item the specified distance (currently +/- 1) in its owning list. /// </summary> /// <param name="distance"></param> void MoveItem(int distance) { int hvoMove = ClickObject; FdoCache cache = (FdoCache)m_mediator.PropertyTable.GetValue("cache"); CmPossibility column = CmObject.CreateFromDBObject(cache, hvoMove) as CmPossibility; if (column.CheckAndReportProtectedChartColumn()) { return; } int hvoOwner = cache.GetOwnerOfObject(hvoMove); if (hvoOwner == 0) // probably not possible { return; } ICmObject owner = CmObject.CreateFromDBObject(cache, hvoOwner); int flid = column.OwningFlid; int oldIndex = column.IndexInOwner; int newIndex = oldIndex + distance; if (newIndex < 0) { return; } int cobj = cache.GetVectorSize(owner.Hvo, flid); if (newIndex >= cobj) { return; } // Without this, we insert it before the next object, which is the one it's already before, // so it doesn't move. if (distance > 0) { newIndex++; } cache.MoveOwningSequence(owner.Hvo, flid, oldIndex, oldIndex, owner.Hvo, flid, newIndex); }
/// <summary> /// Create a CmPossibility based on an XML specification of a constituent chart template. /// See CreateDefaultTemplate for an example. /// </summary> /// <param name="spec"></param> /// <returns></returns> public ICmPossibility CreateChartTemplate(XmlNode spec) { // Make sure we have the containing objects; if not create them. var dData = m_cache.LanguageProject.DiscourseDataOA; if (dData == null) { dData = new DsDiscourseData(); m_cache.LanguageProject.DiscourseDataOA = dData; } // Also make sure it has a templates list var templates = dData.ConstChartTemplOA; if (templates == null) { templates = new CmPossibilityList(); dData.ConstChartTemplOA = templates; } var template = new CmPossibility(); m_cache.LanguageProject.DiscourseDataOA.ConstChartTemplOA.PossibilitiesOS.Add(template); SetNameAndChildColumns(template, spec); return(template); }
public void PrintCmPossibility(FdoCache fcTLP) { CmPossibility p = new CmPossibility(fcTLP, 190); Console.WriteLine(p.Description.AnalysisDefaultWritingSystem); }
/// <summary> /// Create a CmPossibility based on an XML specification of a constituent chart template. /// See CreateDefaultTemplate for an example. /// </summary> /// <param name="spec"></param> /// <returns></returns> public ICmPossibility CreateChartTemplate(XmlNode spec) { // Make sure we have the containing objects; if not create them. var dData = m_cache.LanguageProject.DiscourseDataOA; if (dData == null) { dData = new DsDiscourseData(); m_cache.LanguageProject.DiscourseDataOA = dData; } // Also make sure it has a templates list var templates = dData.ConstChartTemplOA; if (templates == null) { templates = new CmPossibilityList(); dData.ConstChartTemplOA = templates; } var template = new CmPossibility(); m_cache.LanguageProject.DiscourseDataOA.ConstChartTemplOA.PossibilitiesOS.Add(template); SetNameAndChildColumns(template, spec); return template; }
ICmPossibility ICmPossibilityFactoryInternal.Create(Guid guid, int hvo, ICmPossibility owner, int index) { if (owner == null) throw new ArgumentNullException("owner"); var retval = new CmPossibility( m_cache, hvo, guid); owner.SubPossibilitiesOS.Insert(index, retval); return retval; }
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); }
private static void InitItem(XmlNode item, ICmPossibility poss) { var defAnalWs = poss.Cache.DefaultAnalWs; var strFact = poss.Cache.TsStrFactory; // Set name property poss.Name.set_String( defAnalWs, strFact.MakeString( XmlUtils.GetManditoryAttributeValue(item, "name"), defAnalWs)); // Set Abbreviation. var abbr = XmlUtils.GetOptionalAttributeValue(item, "abbr"); if (String.IsNullOrEmpty(abbr)) abbr = poss.Name.AnalysisDefaultWritingSystem.Text; poss.Abbreviation.set_String( defAnalWs, strFact.MakeString( abbr, defAnalWs)); // Create optional child items. foreach (XmlNode subItem in item.ChildNodes) { var poss2 = new CmPossibility(); poss.SubPossibilitiesOS.Add(poss2); InitItem(subItem, poss2); } }
internal ICmPossibility CreateColumn(ICmPossibility parent, XmlNode spec) { var result = new CmPossibility(); parent.SubPossibilitiesOS.Add(result); SetNameAndChildColumns(result, spec); return result; }
ICmPossibility ICmPossibilityFactory.Create(Guid guid, ICmPossibility owner) { if (owner == null) throw new ArgumentNullException("owner"); int hvo = ((IDataReader)m_cache.ServiceLocator.GetInstance<IDataSetup>()).GetNextRealHvo(); int flid = m_cache.MetaDataCache.GetFieldId("CmPossibility", "SubPossibilities", false); var retval = new CmPossibility(m_cache, hvo, guid); owner.SubPossibilitiesOS.Add(retval); return retval; }