private GhostParentHelper GetGhostParentHelper(int flidToTry) { GhostParentHelper gph = null; IVwVirtualHandler vh; if (Cache.TryGetVirtualHandler(flidToTry, out vh) && vh is FDOGhostSequencePropertyVirtualHandler) { gph = GhostParentHelper.CreateGhostParentHelper(Cache, vh.Tag); } return(gph); }
/// <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); }
public void InitForGhostItems(FdoCache cache, XmlNode colSpec) { m_ghostParentHelper = GhostParentHelper.CreateGhostParentHelper(cache, colSpec); }
/// <summary> /// If the column is not configured as ghostable, returns null. /// </summary> /// <param name="cache"></param> /// <param name="colSpec"></param> /// <returns></returns> internal static GhostParentHelper CreateGhostParentHelper(FdoCache cache, XmlNode colSpec) { GhostParentHelper gph = new GhostParentHelper(cache, colSpec); if (gph.IsGhostableColumn) return gph; return null; }
/// <summary> /// needed for AllowDeleteItem(). /// </summary> /// <returns></returns> private GhostParentHelper UpdateCurrentGhostParentHelper() { m_ghostParentHelper = null; // see if the object is a ghost object owner. foreach (int owningFlidForGhost in m_bulkEditListItemsGhostFields) { int targetClass = (int)m_cache.GetDestinationClass((uint)owningFlidForGhost); if (targetClass == m_expectedListItemsClassId) { m_ghostParentHelper = GhostParentHelper.CreateGhostParentHelper(m_cache, owningFlidForGhost); break; } } return m_ghostParentHelper; }
private GhostParentHelper GetGhostParentHelper(int flidToTry) { return(GhostParentHelper.CreateIfPossible(Cache.ServiceLocator, flidToTry)); }
/// <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); }