Ejemplo n.º 1
0
        /// <summary>
        /// Return whether it is OK to move the objects indicated by odi to the specified destination.
        /// </summary>
        /// <param name="hvoDstOwner"></param>
        /// <param name="flidDst"></param>
        /// <param name="ihvoDstStart"></param>
        /// <param name="odi"></param>
        /// <returns></returns>
        public bool OkToMove(int hvoDstOwner, int flidDst, int ihvoDstStart, ObjectDragInfo odi)
        {
            CheckDisposed();

            FDO.FdoCache cache = Slice.ContainingDataTree.Cache;
            if (flidDst == odi.FlidSrc)
            {
                // Verify that it is not a no-operation.
                if (hvoDstOwner == odi.HvoSrcOwner)
                {
                    // Same property of same object. If it's a collection, disable.
                    FieldType fieldType = cache.GetFieldType(flidDst);
                    // We can't drag it to the position it's already at; that's no change. We also can't drag it
                    // to the position one greater: that amounts to trying to place it after itself, which (after
                    // removing it from before itself) amounts to a no-operation.
                    if (fieldType == FieldType.kcptOwningSequence &&
                        ihvoDstStart != odi.IhvoSrcStart && ihvoDstStart != odi.IhvoSrcStart + 1)
                    {
                        // It's a sequence and the target and source positions are different, so we can do it.
                        return(true);
                    }
                }
                else
                {
                    // Different objects; need to verify no circular ownership involved.
                    for (int ihvo = odi.IhvoSrcStart; ihvo <= odi.IhvoSrcEnd; ihvo++)
                    {
                        int hvo = cache.GetVectorItem(odi.HvoSrcOwner, odi.FlidSrc, ihvo);
                        // See if hvoDstOwner is owned by hvo
                        int hvo2 = hvoDstOwner;
                        // loop from hvo2 to root owner of hvo2. If hvo2 or any of its owners is hvo,
                        // we have a problem.
                        while (hvo2 != 0)
                        {
                            if (hvo == hvo2)
                            {
                                return(false);                                // circular ownership, can't drop.
                            }
                            hvo2 = cache.GetOwnerOfObject(hvo2);
                        }
                    }
                    return(true);
                }
            }
            else
            {
                // Different property, check signature.
                IFwMetaDataCache mdc    = cache.MetaDataCacheAccessor;
                uint             luclid = mdc.GetDstClsId((uint)flidDst);
                for (int ihvo = odi.IhvoSrcStart; ihvo <= odi.IhvoSrcEnd; ihvo++)
                {
                    int  hvo = cache.GetVectorItem(odi.HvoSrcOwner, odi.FlidSrc, ihvo);
                    uint cls = (uint)cache.GetClassOfObject(hvo);
                    while (cls != 0 && cls != luclid)
                    {
                        cls = mdc.GetBaseClsId(cls);
                    }
                    if (cls == 0)
                    {
                        return(false);                        // wrong signature, can't drop.
                    }
                }
                // All sigs OK, allow drop.
                return(true);
            }
            // If none of those cases is OK, can't do it.
            return(false);
        }