/// <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); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the node. /// </summary> /// <param name="clsid">The CLSID.</param> /// <param name="layoutName">Name of the layout.</param> /// <param name="fIncludeLayouts">if set to <c>true</c> [f include layouts].</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ public XmlNode GetNode(int clsid, string layoutName, bool fIncludeLayouts) { Tuple <int, string, bool> key = Tuple.Create(clsid, layoutName, fIncludeLayouts); if (m_map.ContainsKey(key)) { return(m_map[key]); } XmlNode node; int classId = clsid; string useName = layoutName ?? "default"; string origName = useName; for ( ; ;) { string classname = m_mdc.GetClassName(classId); if (fIncludeLayouts) { // Inventory of layouts has keys class, type, name node = m_layoutInventory.GetElement("layout", new[] { classname, "jtview", useName, null }); if (node != null) { break; } } // inventory of parts has key id. node = m_partInventory.GetElement("part", new[] { classname + "-Jt-" + useName }); if (node != null) { break; } if (classId == 0 && useName == origName) { // This is somewhat by way of robustness. When we generate a modified layout name we should generate // a modified layout to match. If something slips through the cracks, use the unmodified original // view in preference to a default view of Object. int index = origName.IndexOfAny(ktagMarkers); if (index > 0) { useName = origName.Substring(0, index); classId = clsid; continue; } } if (classId == 0 && useName != "default") { // Nothing found all the way to CmObject...try default layout. useName = "default"; classId = clsid; continue; // try again with the main class, don't go to its base class at once. } if (classId == 0) { if (fIncludeLayouts) { // Really surprising...default view not found on CmObject?? throw new ApplicationException("No matching layout found for class " + classname + " jtview layout " + origName); } // okay to not find specific custom parts...we can generate them. return(null); } // Otherwise try superclass. classId = m_mdc.GetBaseClsId(classId); } m_map[key] = node; // find faster next time! return(node); }