/// <summary> /// Map itemsBeforeListChange (associated with flidForItemsBeforeListChange) /// to those in the current list (associated with flidForCurrentList) /// and provide a set of common ancestors. /// </summary> /// <param name="flidForItemsBeforeListChange"></param> /// <param name="itemsBeforeListChange"></param> /// <param name="flidForCurrentList"></param> /// <param name="commonAncestors"></param> /// <returns></returns> public Set <int> FindCorrespondingItemsInCurrentList(int flidForItemsBeforeListChange, Set <int> itemsBeforeListChange, int flidForCurrentList, out Set <int> commonAncestors) { Set <int> relatives = new Set <int>(); commonAncestors = new Set <int>(); int newListItemsClass = (int)Cache.GetDestinationClass((uint)flidForCurrentList); uint prevListItemsClass = Cache.GetDestinationClass((uint)flidForItemsBeforeListChange); RelationshipOfRelatives relationshipOfTarget = FindTreeRelationship((int)prevListItemsClass, newListItemsClass); // if new listListItemsClass is same as the given object, there's nothing more we have to do. switch (relationshipOfTarget) { case RelationshipOfRelatives.Sibling: { Debug.Fail("Sibling relationships are not supported."); // no use for this currently. break; } case RelationshipOfRelatives.Ancestor: { GhostParentHelper gph = GetGhostParentHelper(flidForItemsBeforeListChange); // the items (e.g. senses) are owned by the new class (e.g. entry), // so find the (new class) ancestor for each item. foreach (int hvoBeforeListChange in itemsBeforeListChange) { int hvoAncestorOfItem = 0; if (gph != null && gph.GhostOwnerClass == (uint)newListItemsClass && gph.IsGhostOwnerClass(hvoBeforeListChange)) { // just add the ghost owner, as the ancestor relative, // since it's already in the newListItemsClass hvoAncestorOfItem = hvoBeforeListChange; } else { hvoAncestorOfItem = Cache.GetOwnerOfObjectOfClass(hvoBeforeListChange, newListItemsClass); } relatives.Add(hvoAncestorOfItem); } commonAncestors = relatives; break; } case RelationshipOfRelatives.Descendent: case RelationshipOfRelatives.Cousin: { foreach (int hvoBeforeListChange in itemsBeforeListChange) { int hvoCommonAncestor = 0; if (relationshipOfTarget == RelationshipOfRelatives.Descendent) { // the item is the ancestor hvoCommonAncestor = hvoBeforeListChange; } else { // the item and its cousins have a common ancestor. hvoCommonAncestor = GetHvoCommonAncestor(hvoBeforeListChange, (int)prevListItemsClass, newListItemsClass); } // only add the descendants/cousins if we haven't already processed the ancestor. if (!commonAncestors.Contains(hvoCommonAncestor)) { GhostParentHelper gph = GetGhostParentHelper(flidForCurrentList); Set <int> descendents = GetDescendents(hvoCommonAncestor, flidForCurrentList); if (descendents.Count > 0) { relatives.AddRange(descendents); } else if (gph != null && gph.IsGhostOwnerClass(hvoCommonAncestor)) { relatives.Add(hvoCommonAncestor); } commonAncestors.Add(hvoCommonAncestor); } } break; } } return(relatives); }
/// <summary> /// Map itemsBeforeListChange (associated with flidForItemsBeforeListChange) /// to those in the current list (associated with flidForCurrentList) /// and provide a set of common ancestors. /// </summary> /// <param name="flidForItemsBeforeListChange"></param> /// <param name="itemsBeforeListChange"></param> /// <param name="flidForCurrentList"></param> /// <param name="commonAncestors"></param> /// <returns></returns> public Set <int> FindCorrespondingItemsInCurrentList(int flidForItemsBeforeListChange, Set <int> itemsBeforeListChange, int flidForCurrentList, out Set <int> commonAncestors) { Set <int> relatives = new Set <int>(); commonAncestors = new Set <int>(); int newListItemsClass = GhostParentHelper.GetBulkEditDestinationClass(Cache, flidForCurrentList); int prevListItemsClass = GhostParentHelper.GetBulkEditDestinationClass(Cache, flidForItemsBeforeListChange); RelationshipOfRelatives relationshipOfTarget = FindTreeRelationship(prevListItemsClass, newListItemsClass); // if new listListItemsClass is same as the given object, there's nothing more we have to do. switch (relationshipOfTarget) { case RelationshipOfRelatives.Sibling: { Debug.Fail("Sibling relationships are not supported."); // no use for this currently. break; } case RelationshipOfRelatives.Ancestor: { GhostParentHelper gph = GetGhostParentHelper(flidForItemsBeforeListChange); // the items (e.g. senses) are owned by the new class (e.g. entry), // so find the (new class) ancestor for each item. foreach (int hvoBeforeListChange in itemsBeforeListChange) { int hvoAncestorOfItem; if (gph != null && gph.GhostOwnerClass == newListItemsClass && gph.IsGhostOwnerClass(hvoBeforeListChange)) { // just add the ghost owner, as the ancestor relative, // since it's already in the newListItemsClass hvoAncestorOfItem = hvoBeforeListChange; } else { var obj = Cache.ServiceLocator.GetInstance <ICmObjectRepository>().GetObject(hvoBeforeListChange); hvoAncestorOfItem = obj.OwnerOfClass(newListItemsClass).Hvo; } relatives.Add(hvoAncestorOfItem); } commonAncestors = relatives; break; } case RelationshipOfRelatives.Descendent: case RelationshipOfRelatives.Cousin: { HashSet <int> newClasses = new HashSet <int>(((IFwMetaDataCacheManaged)Cache.MetaDataCacheAccessor).GetAllSubclasses(newListItemsClass)); foreach (int hvoBeforeListChange in itemsBeforeListChange) { if (!Cache.ServiceLocator.IsValidObjectId(hvoBeforeListChange)) { continue; // skip this one. } if (newClasses.Contains(Cache.ServiceLocator.GetObject(hvoBeforeListChange).ClassID)) { // strangely, the 'before' object is ALREADY one that is valid for, and presumably in, // the destination property. One way this happens is at startup, when switching to // the saved target column, but we have also saved the list of objects. relatives.Add(hvoBeforeListChange); continue; } int hvoCommonAncestor; if (relationshipOfTarget == RelationshipOfRelatives.Descendent) { // the item is the ancestor hvoCommonAncestor = hvoBeforeListChange; } else { // the item and its cousins have a common ancestor. hvoCommonAncestor = GetHvoCommonAncestor(hvoBeforeListChange, prevListItemsClass, newListItemsClass); } // only add the descendants/cousins if we haven't already processed the ancestor. if (!commonAncestors.Contains(hvoCommonAncestor)) { GhostParentHelper gph = GetGhostParentHelper(flidForCurrentList); Set <int> descendents = GetDescendents(hvoCommonAncestor, flidForCurrentList); if (descendents.Count > 0) { relatives.AddRange(descendents); } else if (gph != null && gph.IsGhostOwnerClass(hvoCommonAncestor)) { relatives.Add(hvoCommonAncestor); } commonAncestors.Add(hvoCommonAncestor); } } break; } } return(relatives); }