internal void UpdateContextHierarchyIfContainsDocument(IVsHierarchy sharedHierarchy, DocumentId documentId) { // TODO: This is a very roundabout way to update the context // The sharedHierarchy passed in has a new context, but we don't know what it is. // The documentId passed in is associated with this sharedHierarchy, and this method // will be called once for each such documentId. During this process, one of these // documentIds will actually belong to the new SharedItemContextHierarchy. Once we // find that one, we can map back to the open buffer and set its active context to // the appropriate project. var contextHierarchy = LinkedFileUtilities.GetSharedItemContextHierarchy(sharedHierarchy); // TODO: linear search var matchingProject = CurrentSolution.Projects.FirstOrDefault(p => GetHostProject(p.Id).Hierarchy == contextHierarchy); if (matchingProject == null) { // How? return; } if (!matchingProject.ContainsDocument(documentId)) { // While this documentId is associated with one of the head projects for this // sharedHierarchy, it is not associated with the new context hierarchy. Another // documentId will be passed to this method and update the context. return; } // This documentId belongs to the new SharedItemContextHierarchy. Update the associated // buffer. OnDocumentContextUpdated(documentId); }
private bool IsCurrentContext(uint docCookie, DocumentKey documentKey) { IVsHierarchy hierarchy; uint itemid; RunningDocumentTable.GetDocumentHierarchyItem(docCookie, out hierarchy, out itemid); // If it belongs to a Shared Code project, then the current context is determined // by the SharedItemContextHierarchy. var hierarchyOwningDocument = LinkedFileUtilities.GetSharedItemContextHierarchy(hierarchy) ?? hierarchy; return(documentKey.HostProject.Hierarchy == hierarchyOwningDocument); }
/// <summary> /// Finds the <see cref="DocumentId"/> related to the given <see cref="DocumentId"/> that /// is in the current context. For regular files (non-shared and non-linked) and closed /// linked files, this is always the provided <see cref="DocumentId"/>. For open linked /// files and open shared files, the active context is already tracked by the /// <see cref="Workspace"/> and can be looked up directly. For closed shared files, the /// document in the shared project's <see cref="__VSHPROPID7.VSHPROPID_SharedItemContextHierarchy"/> /// is preferred. /// </summary> internal override DocumentId GetDocumentIdInCurrentContext(DocumentId documentId) { // If the document is open, then the Workspace knows the current context for both // linked and shared files if (IsDocumentOpen(documentId)) { return(base.GetDocumentIdInCurrentContext(documentId)); } var hostDocument = GetHostDocument(documentId); var itemId = hostDocument.GetItemId(); if (itemId == (uint)VSConstants.VSITEMID.Nil) { // An itemid is required to determine whether the file belongs to a Shared Project return(base.GetDocumentIdInCurrentContext(documentId)); } // If this is a regular document or a closed linked (non-shared) document, then use the // default logic for determining current context. var sharedHierarchy = LinkedFileUtilities.GetSharedHierarchyForItem(hostDocument.Project.Hierarchy, itemId); if (sharedHierarchy == null) { return(base.GetDocumentIdInCurrentContext(documentId)); } // This is a closed shared document, so we must determine the correct context. var contextHierarchy = LinkedFileUtilities.GetSharedItemContextHierarchy(sharedHierarchy); var matchingProject = CurrentSolution.Projects.FirstOrDefault(p => GetHostProject(p.Id).Hierarchy == contextHierarchy); if (matchingProject == null) { return(base.GetDocumentIdInCurrentContext(documentId)); } if (matchingProject.ContainsDocument(documentId)) { // The provided documentId is in the current context project return(documentId); } // The current context document is from another project. var linkedDocumentIds = CurrentSolution.GetDocument(documentId).GetLinkedDocumentIds(); var matchingDocumentId = linkedDocumentIds.FirstOrDefault(id => id.ProjectId == matchingProject.Id); return(matchingDocumentId ?? base.GetDocumentIdInCurrentContext(documentId)); }