public int OnAfterRenameDirectories(int cProjects, int cDirs, IVsProject[] rgpProjects, int[] rgFirstIndices, string[] rgszMkOldNames, string[] rgszMkNewNames, VSRENAMEDIRECTORYFLAGS[] rgFlags) { ThreadHelper.ThrowIfNotOnUIThread(); if (rgszMkNewNames == null || rgpProjects == null || rgszMkOldNames == null) { return(VSErr.E_POINTER); } int iDirectory = 0; for (int i = 0; i < cDirs; i++) { string s = rgszMkOldNames[i]; if (!string.IsNullOrEmpty(s)) { SvnCache.MarkDirty(s); } s = rgszMkNewNames[i]; if (!string.IsNullOrEmpty(s)) { SvnCache.MarkDirty(s); } } if (!SccProvider.IsActive) { return(VSErr.S_OK); } ProcessRenames(rgszMkOldNames, rgszMkNewNames); for (int iProject = 0; (iProject < cProjects) && (iDirectory < cDirs); iProject++) { int iLastDirectoryThisProject = (iProject < cProjects - 1) ? rgFirstIndices[iProject + 1] : cDirs; IVsSccProject2 sccProject = rgpProjects[iProject] as IVsSccProject2; bool track = SccEvents.TrackProjectChanges(sccProject); for (; iDirectory < iLastDirectoryThisProject; iDirectory++) { if (sccProject == null || !track) { continue; // Not handled by our provider } SccEvents.OnProjectDirectoryRenamed(sccProject, SvnTools.GetNormalizedFullPath(rgszMkOldNames[iDirectory]), SvnTools.GetNormalizedFullPath(rgszMkNewNames[iDirectory]), rgFlags[iDirectory]); } } return(VSErr.S_OK); }
/// <summary> /// /// </summary> /// <param name="cProjects"></param> /// <param name="cDirectories"></param> /// <param name="rgpProjects"></param> /// <param name="rgFirstIndices"></param> /// <param name="rgpszMkDocuments"></param> /// <param name="rgFlags"></param> /// <returns></returns> /// <remarks>Deny a query only if allowing the operation would compromise your stable state</remarks> public int OnAfterAddDirectoriesEx(int cProjects, int cDirectories, IVsProject[] rgpProjects, int[] rgFirstIndices, string[] rgpszMkDocuments, VSADDDIRECTORYFLAGS[] rgFlags) { ThreadHelper.ThrowIfNotOnUIThread(); if (rgpProjects == null || rgpszMkDocuments == null) { return(VSErr.E_POINTER); } bool sccActive = SccProvider.IsActive; for (int iProject = 0, iDir = 0; (iProject < cProjects) && (iDir < cDirectories); iProject++) { int iLastDirectoryThisProject = (iProject < cProjects - 1) ? rgFirstIndices[iProject + 1] : cDirectories; IVsSccProject2 sccProject = rgpProjects[iProject] as IVsSccProject2; bool trackCopies; bool track = SccEvents.TrackProjectChanges(sccProject, out trackCopies); for (; iDir < iLastDirectoryThisProject; iDir++) { if (!track) { continue; } string dir = rgpszMkDocuments[iDir]; if (!SvnItem.IsValidPath(dir)) { continue; } dir = SvnTools.GetNormalizedFullPath(dir); string origin = null; if (sccActive && _solutionLoaded) { SvnCache.MarkDirty(dir); TryFindOrigin(dir, out origin); } if (sccProject != null) { SccEvents.OnProjectDirectoryAdded(sccProject, dir, origin); } if (sccActive && trackCopies && !string.IsNullOrEmpty(origin) && SvnCache[origin].HasCopyableHistory) { using (SvnSccContext svn = new SvnSccContext(this)) { svn.AddParents(dir); svn.MetaCopy(origin, dir); } } } } return(VSErr.S_OK); }
/// <summary> /// This method notifies the client after a project has added files. /// </summary> /// <param name="cProjects">[in] Number of projects to which files were added.</param> /// <param name="cFiles">[in] Number of files that were added.</param> /// <param name="rgpProjects">[in] Array of projects to which files were added.</param> /// <param name="rgFirstIndices">[in] Array of first indices identifying which project each file belongs to. For more information, see IVsTrackProjectDocumentsEvents2.</param> /// <param name="rgpszMkDocuments">[in] Array of paths for the files that were processed. This is the same size as cFiles.</param> /// <param name="rgFlags">[in] Array of flags. For a list of rgFlags values, see <see cref="VSADDFILEFLAGS" />.</param> /// <returns></returns> public int OnAfterAddFilesEx(int cProjects, int cFiles, IVsProject[] rgpProjects, int[] rgFirstIndices, string[] rgpszMkDocuments, VSADDFILEFLAGS[] rgFlags) { ThreadHelper.ThrowIfNotOnUIThread(); RegisterForSccCleanup(); // Clear the origins table after adding SortedList <string, string> copies = null; bool sccActive = SccProvider.IsActive; for (int iProject = 0, iFile = 0; (iProject < cProjects) && (iFile < cFiles); iProject++) { int iLastFileThisProject = (iProject < cProjects - 1) ? rgFirstIndices[iProject + 1] : cFiles; IVsSccProject2 sccProject = rgpProjects[iProject] as IVsSccProject2; bool trackCopies; bool track = SccEvents.TrackProjectChanges(sccProject, out trackCopies); for (; iFile < iLastFileThisProject; iFile++) { if (!track) { continue; // Not handled by our provider } string origin = null; string newName = rgpszMkDocuments[iFile]; if (!SvnItem.IsValidPath(newName)) { continue; } newName = SvnTools.GetNormalizedFullPath(newName); if (sccActive && _solutionLoaded) { SvnCache.MarkDirty(newName); TryFindOrigin(newName, out origin); } // We do this before the copies to make sure a failed copy doesn't break the project SccEvents.OnProjectFileAdded(sccProject, newName); if (sccActive && trackCopies && !string.IsNullOrEmpty(origin) && SvnCache[origin].HasCopyableHistory) { if (copies == null) { copies = new SortedList <string, string>(StringComparer.OrdinalIgnoreCase); } copies[newName] = origin; } } } if (copies != null) { using (SvnSccContext svn = new SvnSccContext(Context)) { foreach (KeyValuePair <string, string> kv in copies) { svn.AddParents(kv.Key); svn.MetaCopy(kv.Value, kv.Key); } } } return(VSErr.S_OK); }
public int OnAfterRenameFiles(int cProjects, int cFiles, IVsProject[] rgpProjects, int[] rgFirstIndices, string[] rgszMkOldNames, string[] rgszMkNewNames, VSRENAMEFILEFLAGS[] rgFlags) { if (rgszMkNewNames == null || rgpProjects == null || rgszMkOldNames == null || rgszMkOldNames.Length != rgszMkNewNames.Length) { return(VSErr.E_POINTER); } // TODO: C++ projects do not send directory renames; but do send OnAfterRenameFile() events // for all files (one at a time). We should detect that case here and fix up this dirt! for (int i = 0; i < cFiles; i++) { string s = rgszMkOldNames[i]; if (SvnItem.IsValidPath(s)) { SvnCache.MarkDirty(s); } s = rgszMkNewNames[i]; if (SvnItem.IsValidPath(s)) { SvnCache.MarkDirty(s); } } if (!SccProvider.IsActive) { return(VSErr.S_OK); } ProcessRenames(rgszMkOldNames, rgszMkNewNames); for (int iProject = 0, iFile = 0; (iProject < cProjects) && (iFile < cFiles); iProject++) { int iLastFileThisProject = (iProject < cProjects - 1) ? rgFirstIndices[iProject + 1] : cFiles; if (rgpProjects[iProject] != null) { IVsSccProject2 sccProject = rgpProjects[iProject] as IVsSccProject2; bool track = SccEvents.TrackProjectChanges(sccProject); for (; iFile < iLastFileThisProject; iFile++) { if (sccProject == null || !track) { continue; // Not handled by our provider } if (!SvnItem.IsValidPath(rgszMkOldNames[iFile])) { continue; } string oldName = SvnTools.GetNormalizedFullPath(rgszMkOldNames[iFile]); string newName = SvnTools.GetNormalizedFullPath(rgszMkNewNames[iFile]); if (oldName == newName) { continue; } SccEvents.OnProjectFileRenamed(sccProject, oldName, newName, rgFlags[iFile]); } } else { // Renaming something in the solution (= solution file itself) for (; iFile < iLastFileThisProject; iFile++) { if (!SvnItem.IsValidPath(rgszMkOldNames[iFile])) { continue; } string oldName = SvnTools.GetNormalizedFullPath(rgszMkOldNames[iFile]); string newName = SvnTools.GetNormalizedFullPath(rgszMkNewNames[iFile]); if (oldName != newName) { SccEvents.OnSolutionRenamedFile(oldName, newName); } SccEvents.Translate_SolutionRenamed(rgszMkOldNames[iFile], rgszMkNewNames[iFile]); } } } return(VSErr.S_OK); }