示例#1
0
        /// <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);
        }
示例#2
0
        /// <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);
        }