public void Path_TestReallyLong() { string temp = Path.GetTempPath() + "\\" + Guid.NewGuid() + new String('a', 200); temp = temp.Replace("\\\\", "\\"); if (temp.Length < 256) { temp += "bbbbbbbbbbbbbbbbbbbb"; } Assert.That(CreateDirectory("\\\\?\\" + temp, IntPtr.Zero), Is.True, "Created directory {0}", temp); try { Assert.That(SvnTools.GetNormalizedFullPath(temp), Is.Not.Null, "Normalized path valid for extremely long path"); Assert.That(SvnTools.GetTruePath(temp), Is.Not.Null, "True path valid for extremely long path"); string t2 = temp.Replace("\\", "\\.\\"); Assert.That(SvnTools.GetNormalizedFullPath(t2), Is.EqualTo(SvnTools.GetNormalizedFullPath(temp)), "True path completed"); Assert.That(SvnTools.GetTruePath(t2), Is.EqualTo(SvnTools.GetTruePath(temp))); string sd = Guid.NewGuid().ToString() + ".tMp"; string notExisting = Path.Combine(temp, sd); string notExistingUpper = Path.Combine(temp.ToUpperInvariant(), sd); Assert.That(SvnTools.GetTruePath(notExistingUpper), Is.Null); Assert.That(SvnTools.GetTruePath(notExistingUpper, false), Is.Null); Assert.That(SvnTools.GetTruePath(notExistingUpper, true), Is.EqualTo(notExisting)); notExisting = Path.Combine(notExisting, "a\\b.tmp"); notExistingUpper = Path.Combine(notExistingUpper, "a\\b.tmp"); Assert.That(SvnTools.GetTruePath(notExistingUpper), Is.Null); Assert.That(SvnTools.GetTruePath(notExistingUpper, false), Is.Null); Assert.That(SvnTools.GetTruePath(notExistingUpper, true), Is.EqualTo(notExisting)); } finally { RemoveDirectory("\\\\?\\" + temp); } }
/// <summary> /// Marks the specified file dirty /// </summary> /// <param name="file"></param> void ISccStatusCache.MarkDirty(string path) { if (path == null) { throw new ArgumentNullException("path"); } var normPath = SvnTools.GetNormalizedFullPath(path); lock (_lock) { SvnItem item; if (Map.TryGetValue(normPath, out item)) { item.MarkDirty(); } } }
public int OnAfterRemoveDirectories(int cProjects, int cDirectories, IVsProject[] rgpProjects, int[] rgFirstIndices, string[] rgpszMkDocuments, VSREMOVEDIRECTORYFLAGS[] rgFlags) { ThreadHelper.ThrowIfNotOnUIThread(); if (rgpProjects == null || rgpszMkDocuments == null) { return(VSErr.E_POINTER); } for (int iProject = 0, iDirectory = 0; (iProject < cProjects) && (iDirectory < cDirectories); iProject++) { int iLastDirectoryThisProject = (iProject < cProjects - 1) ? rgFirstIndices[iProject + 1] : cDirectories; 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 } string dir = rgpszMkDocuments[iDirectory]; if (!SvnItem.IsValidPath(dir)) { continue; } dir = SvnTools.GetNormalizedFullPath(dir); SccEvents.OnProjectDirectoryRemoved(sccProject, dir, rgFlags[iDirectory]); if (SccProvider.IsActive && track) { SccEvents.AddDelayedDelete(dir); } } } return(VSErr.S_OK); }
/// <summary> /// Gets the list of files specified by the hierarchy (IVsSccProject2 or IVsHierarchy) /// </summary> /// <param name="hierarchy"></param> /// <param name="id"></param> /// <param name="depth"></param> /// <returns></returns> /// <remarks>The list might contain duplicates if files are included more than once</remarks> public IEnumerable <string> GetSccFiles(IVsHierarchy hierarchy, uint id, ProjectWalkDepth depth, IDictionary <string, uint> map) { ThreadHelper.ThrowIfNotOnUIThread(); // Note: This command is not cached like the other commands on this object! if (hierarchy == null) { throw new ArgumentNullException("hierarchy"); } SelectionItem si = new SelectionItem(hierarchy, id); string[] files; if (!SelectionUtils.GetSccFiles(si, out files, depth >= ProjectWalkDepth.SpecialFiles, IncludeNoScc(depth), map)) { yield break; } foreach (string file in files) { yield return(SvnTools.GetNormalizedFullPath(file)); } if (depth > ProjectWalkDepth.SpecialFiles) { Dictionary <SelectionItem, SelectionItem> previous = new Dictionary <SelectionItem, SelectionItem>(); previous.Add(si, si); foreach (SelectionItem item in GetDescendants(si, previous, depth)) { if (!SelectionUtils.GetSccFiles(item, out files, depth >= ProjectWalkDepth.SpecialFiles, depth != ProjectWalkDepth.AllDescendantsInHierarchy, map)) { continue; } foreach (string file in files) { yield return(SvnTools.GetNormalizedFullPath(file)); } } } }
void SetProjectRootValue(string value) { if (SolutionFilename == null) { return; } string sd = SvnTools.PathToRelativeUri(SvnTools.GetNormalizedDirectoryName(SolutionFilename).TrimEnd('\\') + '\\').ToString(); string v = SvnTools.PathToRelativeUri(SvnTools.GetNormalizedFullPath(value)).ToString(); if (!v.EndsWith("/")) { v += "/"; } if (!sd.StartsWith(v, StringComparison.OrdinalIgnoreCase)) { return; } Uri solUri; Uri resUri; if (!Uri.TryCreate("file:///" + sd.Replace('\\', '/'), UriKind.Absolute, out solUri) || !Uri.TryCreate("file:///" + v.Replace('\\', '/'), UriKind.Absolute, out resUri)) { return; } using (SvnClient client = GetService <ISvnClientPool>().GetNoUIClient()) { SvnSetPropertyArgs ps = new SvnSetPropertyArgs(); ps.ThrowOnError = false; client.SetProperty(SolutionFilename, AnkhSccPropertyNames.ProjectRoot, solUri.MakeRelativeUri(resUri).ToString(), ps); GetService <ISvnStatusCache>().MarkDirty(SolutionFilename); // The getter will reload the settings for us } _cache = null; }
public int OnAfterRemoveFiles(int cProjects, int cFiles, IVsProject[] rgpProjects, int[] rgFirstIndices, string[] rgpszMkDocuments, VSREMOVEFILEFLAGS[] rgFlags) { ThreadHelper.ThrowIfNotOnUIThread(); if (rgpProjects == null || rgpszMkDocuments == null) { return(VSErr.E_POINTER); } 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 track = SccEvents.TrackProjectChanges(sccProject); for (; iFile < iLastFileThisProject; iFile++) { if (sccProject == null || !track) { continue; // Not handled by our provider } string file = rgpszMkDocuments[iFile]; if (!SvnItem.IsValidPath(file)) { continue; } file = SvnTools.GetNormalizedFullPath(file); SccEvents.OnProjectFileRemoved(sccProject, file); if (SccProvider.IsActive && track) { SccEvents.AddDelayedDelete(file); } } } return(VSErr.S_OK); }
/// <summary> /// /// </summary> /// <returns></returns> public IndexerResult Exec() { Uri codeBase = new Uri(typeof(SourceServerIndexer).Assembly.CodeBase); string myDir = Path.GetDirectoryName(codeBase.LocalPath); _srcToolPath = SvnTools.GetNormalizedFullPath(Path.Combine(myDir, "srctool.exe")); _pdbStrPath = SvnTools.GetNormalizedFullPath(Path.Combine(myDir, "pdbstr.exe")); if (!File.Exists(_srcToolPath)) { throw new FileNotFoundException("SRCTOOL.EXE not found", _srcToolPath); } if (!File.Exists(_srcToolPath)) { throw new FileNotFoundException("PDBSTR.EXE not found", _pdbStrPath); } IndexerState state = new IndexerState(); foreach (string pdbFile in SymbolFiles) { SymbolFile symbolFile = new SymbolFile(pdbFile); if (!symbolFile.Exists) { throw new FileNotFoundException(string.Format("Symbol {0} file not found", symbolFile.FullName), symbolFile.FullName); } state.SymbolFiles.Add(symbolFile.FullName, symbolFile); } ReadSourceFilesFromPdbs(state); // Check if there are files to index for this pdb file PerformExclusions(state); ResolveFiles(state); WritePdbAnnotations(state); return(CreateResultData(state)); }
/// <summary> /// Marks the specified file dirty /// </summary> /// <param name="file"></param> void ISccStatusCache.MarkDirty(IEnumerable <string> paths) { if (paths == null) { throw new ArgumentNullException("paths"); } lock (_lock) { foreach (var path in paths) { var normPath = SvnTools.GetNormalizedFullPath(path); SvnItem item; if (Map.TryGetValue(normPath, out item)) { item.MarkDirty(); } } } }
/// <summary> /// Accesses a specified set of files and asks all implementers of this method to release any locks that may exist on those files. /// </summary> /// <param name="grfRequiredAccess">[in] A value from the <see cref="T:Microsoft.VisualStudio.Shell.Interop.__HANDSOFFMODE"></see> enumeration, indicating the type of access requested. This can be used to optimize the locks that actually need to be released.</param> /// <param name="cFiles">[in] The number of files in the rgpszMkDocuments array.</param> /// <param name="rgpszMkDocuments">[in] If there are any locks on this array of file names, the caller wants them to be released.</param> /// <returns> /// If the method succeeds, it returns <see cref="F:Microsoft.VisualStudio.VSErr.S_OK"></see>. If it fails, it returns an error code. /// </returns> public int HandsOffFiles(uint grfRequiredAccess, int cFiles, string[] rgpszMkDocuments) { if (_collectHints && rgpszMkDocuments != null) { // Some projects call HandsOffFiles of files they want to add. Use that to collect extra origin information foreach (string file in rgpszMkDocuments) { if (!SccProvider.IsSafeSccPath(file)) { continue; } string fullFile = SvnTools.GetNormalizedFullPath(file); if (!_fileHints.Contains(fullFile)) { _fileHints.Add(fullFile); } } } return(VSErr.S_OK); }
static string SubPath(string origin, string relativePath) { if (string.IsNullOrEmpty(origin)) { return(null); } else if (string.IsNullOrEmpty(relativePath)) { return(origin); } string r = SvnTools.GetNormalizedFullPath(Path.Combine(origin, relativePath)); if (File.Exists(r)) { return(r); } else { return(null); } }
public IEnumerable <SccProject> GetAllProjectsContaining(IEnumerable <string> paths) { if (paths == null) { throw new ArgumentNullException("paths"); } ThreadHelper.ThrowIfNotOnUIThread(); Hashtable projects = new Hashtable(); foreach (string path in paths) { string nPath = SvnTools.GetNormalizedFullPath(path); SccProjectFile file; if (TryGetFile(nPath, out file)) { foreach (SccProjectData pd in file.GetOwnerProjects()) { if (projects.Contains(pd)) { continue; } projects.Add(pd, pd); yield return(pd.SvnProject); } } if (!projects.Contains(SccProject.Solution) && string.Equals(path, SolutionFilename, StringComparison.OrdinalIgnoreCase)) { projects.Add(SccProject.Solution, SccProject.Solution); yield return(SccProject.Solution); } } }
public ICollection <string> GetDocumentsBelow(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } path = SvnTools.GetNormalizedFullPath(path); List <string> files = new List <string>(); SccDocumentData dd; if (_docMap.TryGetValue(path, out dd)) { files.Add(path); } if (!path.EndsWith(Path.DirectorySeparatorChar.ToString())) { path += Path.DirectorySeparatorChar; } foreach (SccDocumentData d in _docMap.Values) { string docPath = d.FullPath; if (docPath == null) { continue; // Not file based } if (SvnItem.IsBelowRoot(docPath, path)) { files.Add(SvnTools.GetNormalizedFullPath(d.Name)); } } return(files.ToArray()); }
private void SelectInFileExplorer(string fullPath) { if (string.IsNullOrEmpty(fullPath)) { throw new ArgumentNullException("fullPath"); } fullPath = SvnTools.GetNormalizedFullPath(fullPath); IntPtr pidlList = NativeMethods.ILCreateFromPathW(fullPath); if (pidlList != IntPtr.Zero) { try { // Open parent folder and select item Marshal.ThrowExceptionForHR(NativeMethods.SHOpenFolderAndSelectItems(pidlList, 0, IntPtr.Zero, 0)); } finally { NativeMethods.ILFree(pidlList); } } }
void LoadSolutionInfo() { ThreadHelper.ThrowIfNotOnUIThread(); string dir, path, user; _rawSolutionDirectory = null; _solutionDirectory = null; _solutionFile = ""; IVsSolution sol = GetService <IVsSolution>(typeof(SVsSolution)); if (sol == null || !VSErr.Succeeded(sol.GetSolutionInfo(out dir, out path, out user))) { return; } if (string.IsNullOrEmpty(dir) || string.IsNullOrEmpty(path)) { // Cache negative result; will be returned as null } else { if (IsSafeSccPath(dir)) { _rawSolutionDirectory = dir; _solutionDirectory = SvnTools.GetTruePath(dir, true) ?? SvnTools.GetNormalizedFullPath(dir); } if (IsSafeSccPath(path)) { _solutionFile = SvnTools.GetTruePath(path, true) ?? SvnTools.GetNormalizedFullPath(path); } } }
public IEnumerable <Selection.SccProject> GetAllProjectsContaining(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } path = SvnTools.GetNormalizedFullPath(path); SccProjectFile file; if (TryGetFile(path, out file)) { foreach (SccProjectData pd in file.GetOwnerProjects()) { yield return(pd.SvnProject); } } if (string.Equals(path, SolutionFilename, StringComparison.OrdinalIgnoreCase)) { yield return(SccProject.Solution); } }
private void VerifySolutionNaming() { ThreadHelper.ThrowIfNotOnUIThread(); IVsSolution sol = GetService <IVsSolution>(typeof(SVsSolution)); string dir, path, user; if (sol == null || !VSErr.Succeeded(sol.GetSolutionInfo(out dir, out path, out user)) || string.IsNullOrEmpty(path)) { return; } string trueSln = SvnTools.GetTruePath(path, true) ?? SvnTools.GetNormalizedFullPath(path); if (trueSln == path) { return; // Nothing to do for us } IVsRunningDocumentTable rdt = GetService <IVsRunningDocumentTable>(typeof(SVsRunningDocumentTable)); if (rdt == null) { return; } Guid IID_hier = typeof(IVsHierarchy).GUID; IntPtr hier = IntPtr.Zero; IntPtr unk = Marshal.GetIUnknownForObject(sol); IntPtr ppunkDocData = IntPtr.Zero; try { IVsHierarchy slnHier; uint pitemid; uint pdwCookie; if (!VSErr.Succeeded(rdt.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_EditLock, path, out slnHier, out pitemid, out ppunkDocData, out pdwCookie))) { return; } if (!VSErr.Succeeded(Marshal.QueryInterface(unk, ref IID_hier, out hier))) { hier = IntPtr.Zero; return; } if (VSErr.Succeeded(rdt.RenameDocument(path, trueSln, hier, VSItemId.Root))) { int hr; hr = rdt.SaveDocuments((uint)(__VSRDTSAVEOPTIONS.RDTSAVEOPT_ForceSave | __VSRDTSAVEOPTIONS.RDTSAVEOPT_SaveNoChildren), slnHier, pitemid, pdwCookie); hr = sol.SaveSolutionElement((uint)(__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave), (IVsHierarchy)sol, pdwCookie); //GC.KeepAlive(hr); } if (ppunkDocData != IntPtr.Zero) { object doc = Marshal.GetObjectForIUnknown(ppunkDocData); } } finally { System.Runtime.InteropServices.Marshal.Release(unk); if (hier != IntPtr.Zero) { System.Runtime.InteropServices.Marshal.Release(hier); } if (ppunkDocData != IntPtr.Zero) { Marshal.Release(hier); } } }
public void TestChangeLists() { SvnSandBox sbox = new SvnSandBox(this); sbox.Create(SandBoxRepository.Default); string WcPath = sbox.Wc; Uri WcUri = sbox.Uri; string file1 = Path.Combine(WcPath, "ChangeListFile1"); string file2 = Path.Combine(WcPath, "ChangeListFile2"); string file3 = Path.Combine(WcPath, "ChangeListFile3"); string file4 = Path.Combine(WcPath, "ChangeListFile4"); using (SvnClient client = NewSvnClient(true, false)) { SvnInfoArgs ia = new SvnInfoArgs(); ia.ThrowOnError = false; SvnInfoEventArgs iea; Collection <SvnInfoEventArgs> ee; Assert.That(client.GetInfo(new Uri(WcUri, "ChangeListFile1"), ia, out ee), Is.False); Assert.That(client.GetInfo(new Uri(WcUri, "ChangeListFile2"), ia, out ee), Is.False); Assert.That(client.GetInfo(new Uri(WcUri, "ChangeListFile3"), ia, out ee), Is.False); Assert.That(client.GetInfo(new Uri(WcUri, "ChangeListFile4"), ia, out ee), Is.False); TouchFile(file1); TouchFile(file2); TouchFile(file3); TouchFile(file4); client.Add(file1); client.Commit(WcPath); client.GetInfo(new Uri(WcUri, "ChangeListFile1"), out iea); Assert.That(iea, Is.Not.Null); client.Add(file2); client.Add(file3); client.Add(file4); client.AddToChangeList(file2, "ChangeListTest-2"); client.AddToChangeList(file3, "ChangeListTest-3"); Collection <SvnListChangeListEventArgs> paths; SvnListChangeListArgs a = new SvnListChangeListArgs(); a.ChangeLists.Add("ChangeListTest-2"); client.GetChangeList(WcPath, a, out paths); Assert.That(paths, Is.Not.Null); Assert.That(paths.Count, Is.EqualTo(1)); Assert.That(paths[0].Path, Is.EqualTo(SvnTools.GetNormalizedFullPath(file2))); a = new SvnListChangeListArgs(); a.ChangeLists.Add("ChangeListTest-4"); client.GetChangeList(WcPath, a, out paths); Assert.That(paths, Is.Not.Null); Assert.That(paths.Count, Is.EqualTo(0)); SvnCommitArgs ca = new SvnCommitArgs(); ca.ChangeLists.Add("ChangeListTest-2"); client.Commit(WcPath, ca); Assert.That(client.GetInfo(new Uri(WcUri, "ChangeListFile2"), ia, out ee), Is.True); Assert.That(client.GetInfo(new Uri(WcUri, "ChangeListFile3"), ia, out ee), Is.False); Assert.That(client.GetInfo(new Uri(WcUri, "ChangeListFile4"), ia, out ee), Is.False); bool visited = false; a = new SvnListChangeListArgs(); a.ChangeLists.Add("ChangeListTest-3"); client.ListChangeList(WcPath, a, delegate(object sender, SvnListChangeListEventArgs e) { Assert.That(e.Path, Is.EqualTo(file3)); visited = true; }); Assert.That(visited, Is.True); visited = false; client.Status(file4, delegate(object sender, SvnStatusEventArgs e) { Assert.That(e.FullPath, Is.EqualTo(file4)); Assert.That(e.LocalNodeStatus, Is.EqualTo(SvnStatus.Added)); Assert.That(e.IsRemoteUpdated, Is.False); Assert.That(e.Path, Is.EqualTo(file4)); visited = true; }); Assert.That(visited, Is.True); client.Commit(WcPath); Assert.That(client.GetInfo(new Uri(WcUri, "ChangeListFile3"), ia, out ee), Is.True); Assert.That(client.GetInfo(new Uri(WcUri, "ChangeListFile4"), ia, out ee), Is.True); } }
internal void EnlistAndCheckout(IVsHierarchy vsHierarchy, string pszProjectMk) { string slnProjectMk; if (!_trueNameMap.TryGetValue(pszProjectMk, out slnProjectMk)) { slnProjectMk = pszProjectMk; } SccSvnOrigin origin; if (!_originMap.TryGetValue(slnProjectMk, out origin)) { return; } if (string.IsNullOrEmpty(origin.SvnUri)) { return; } IVsSolution sol = GetService <IVsSolution>(typeof(SVsSolution)); if (sol == null) { return; } IVsProjectFactory factory; if (!VSErr.Succeeded(sol.GetProjectFactory(0, null, pszProjectMk, out factory))) { return; } IVsSccProjectEnlistmentFactory enlistFactory = factory as IVsSccProjectEnlistmentFactory; if (enlistFactory == null) { return; } string enlistPath, enlistPathUNC; if (!VSErr.Succeeded(enlistFactory.GetDefaultEnlistment(pszProjectMk, out enlistPath, out enlistPathUNC))) { return; } uint flags; int hr; // Website projects return E_NOTIMPL on these methods if (!VSErr.Succeeded(hr = enlistFactory.GetEnlistmentFactoryOptions(out flags))) { if (hr != VSErr.E_NOTIMPL) { return; } flags = 0; } if (!VSErr.Succeeded(hr = enlistFactory.OnBeforeEnlistmentCreate(pszProjectMk, enlistPath, enlistPathUNC))) { return; } Uri projectUri; if (!Uri.TryCreate(origin.SvnUri, UriKind.Absolute, out projectUri)) { Uri relativeUri; if (!Uri.TryCreate(origin.SvnUri, UriKind.Relative, out relativeUri)) { return; } // We have a Uri relative from the solution file if (StatusCache == null) { return; } SvnItem slnDirItem = StatusCache[SolutionDirectory]; if (!slnDirItem.IsVersioned || slnDirItem.Uri == null) { return; } projectUri = new Uri(slnDirItem.Uri, relativeUri); } GetService <IProgressRunner>().RunModal(Resources.CheckingOutProject, delegate(object sender, ProgressWorkerArgs e) { e.Client.CheckOut(projectUri, SvnTools.GetNormalizedFullPath(enlistPathUNC)); }); if (!VSErr.Succeeded(hr = enlistFactory.OnAfterEnlistmentCreate(pszProjectMk, enlistPath, enlistPathUNC))) { return; } SccTranslatePathInfo tpi = new SccTranslatePathInfo(slnProjectMk, enlistPath, enlistPathUNC); _translationMap[tpi.SolutionPath] = tpi; if (tpi.SolutionPath != tpi.EnlistmentUNCPath) { _trueNameMap[tpi.EnlistmentUNCPath] = tpi.SolutionPath; } }
public void SerializeSccExcludeData(System.IO.Stream store, bool writeData) { ClearSolutionInfo(); // Force the right data string baseDir = SolutionDirectory; if (writeData) { if (_sccExcluded.Count == 0) { return; } using (BinaryWriter bw = new BinaryWriter(store)) { bw.Write(_sccExcluded.Count); foreach (string path in _sccExcluded) { if (baseDir != null) { bw.Write(SvnItem.MakeRelative(baseDir, path)); } else { bw.Write(path); } } } } else { if (store.Length == 0) { return; } using (BinaryReader br = new BinaryReader(store)) { int count = br.ReadInt32(); while (count-- > 0) { string path = br.ReadString(); try { if (baseDir != null) { path = SvnTools.GetNormalizedFullPath(Path.Combine(baseDir, path)); } else { path = SvnTools.GetNormalizedFullPath(path); } if (!_sccExcluded.Contains(path)) { _sccExcluded.Add(path); } } catch { } } } } }
internal unsafe sbyte *AllocAbsoluteDirent(string value) { return(AllocDirent(SvnTools.GetNormalizedFullPath(value))); }
public int OnAfterAttributeChangeEx(uint docCookie, uint grfAttribs, IVsHierarchy pHierOld, uint itemidOld, string pszMkDocumentOld, IVsHierarchy pHierNew, uint itemidNew, string pszMkDocumentNew) { if ((grfAttribs & TrackedRDTAttributes) == 0) { return(VSErr.S_OK); // Not interested } SccDocumentData data; if (!TryGetDocument(docCookie, true, out data)) { return(VSErr.S_OK); } __VSRDTATTRIB attribs = (__VSRDTATTRIB)grfAttribs; { bool wasInitialized = data.IsDocumentInitialized; data.OnAttributeChange(attribs, _poller); if (!wasInitialized && GetDocumentFlags_cb != null && (attribs & (SccDocumentData.RDTA_DocumentInitialized | SccDocumentData.RDTA_HierarchyInitialized)) != 0) { uint newFlags = GetDocumentFlags_cb(data.Cookie); data.SetFlags((_VSRDTFLAGS)newFlags); } } if ((attribs & __VSRDTATTRIB.RDTA_ItemID) == __VSRDTATTRIB.RDTA_ItemID) { data.ItemId = itemidNew; } if ((attribs & __VSRDTATTRIB.RDTA_Hierarchy) == __VSRDTATTRIB.RDTA_Hierarchy) { data.Hierarchy = pHierNew; } if ((attribs & __VSRDTATTRIB.RDTA_MkDocument) == __VSRDTATTRIB.RDTA_MkDocument && !string.IsNullOrEmpty(pszMkDocumentNew)) { if (data.Name != pszMkDocumentNew) { // The document changed names; Handle this as opening a new document SccDocumentData newData; if (!_docMap.TryGetValue(pszMkDocumentNew, out newData)) { newData = new SccDocumentData(Context, pszMkDocumentNew); newData.CopyState(data); newData.Cookie = docCookie; data.Dispose(); _docMap.Add(pszMkDocumentNew, newData); } else { data.Dispose(); // Removes old item from docmap and cookie map if necessary } _cookieMap[newData.Cookie] = newData; data = newData; } if (!string.IsNullOrEmpty(pszMkDocumentOld) && pszMkDocumentNew != pszMkDocumentOld) { if (SvnItem.IsValidPath(pszMkDocumentNew) && SvnItem.IsValidPath(pszMkDocumentOld)) { string oldFile = SvnTools.GetNormalizedFullPath(pszMkDocumentOld); string newFile = SvnTools.GetNormalizedFullPath(pszMkDocumentNew); ProjectTracker.OnDocumentSaveAs(oldFile, newFile); } } } return(VSErr.S_OK); }
public IDisposable MoveAway(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } path = SvnTools.GetNormalizedFullPath(path); bool isFile = true; if (!File.Exists(path)) { if (Directory.Exists(path)) { isFile = false; } else { throw new InvalidOperationException(); } } FileAttributes attrs = FileAttributes.Normal; if (isFile) { attrs = File.GetAttributes(path); File.SetAttributes(path, FileAttributes.Normal); } string tmp; int n = 0; do { tmp = path + string.Format(".AnkhSVN.{0}.tmp", n++); }while (File.Exists(tmp) || Directory.Exists(tmp)); RetriedRename(path, tmp); if (isFile) { File.SetAttributes(tmp, FileAttributes.ReadOnly); } return(new DelegateRunner( delegate() { if (SvnItem.PathExists(path)) { SvnItem.DeleteNode(path); } RetriedRename(tmp, path); if (isFile) { File.SetAttributes(path, attrs); } })); }
/// <summary> /// Called from RefreshPath's call to <see cref="GitClient::Status"/> /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// <remarks> /// All information we receive here is live from Git and Disk and is therefore propagated /// in all GitItems wishing information /// </remarks> void RefreshCallback(object sender, GitStatusEventArgs e) { // Note: There is a lock(_lock) around this in our caller GitStatusData status = new GitStatusData(e); string path = e.FullPath; // Fully normalized if (_root == null) { _root = new string[] { e.FullPath, e.RelativePath } } ; GitItem item; if (!_map.TryGetValue(path, out item) || !NewFullPathOk(item, path, status)) { // We only create an item if we don't have an existing // with a valid path. (No casing changes allowed!) GitItem newItem = CreateItem(path, status); StoreItem(newItem); if (item != null) { ((IGitItemUpdate)item).RefreshTo(newItem); item.Dispose(); } item = newItem; } else { ((IGitItemUpdate)item).RefreshTo(status); } // Note: There is a lock(_lock) around this in our caller } /// <summary> /// Marks the specified file dirty /// </summary> /// <param name="file"></param> void ISccStatusCache.MarkDirty(string path) { if (path == null) { throw new ArgumentNullException("path"); } string normPath = SvnTools.GetNormalizedFullPath(path); lock (_lock) { GitItem item; if (_map.TryGetValue(normPath, out item)) { item.MarkDirty(); } } } void ISccStatusCache.MarkDirtyRecursive(string path) { if (path == null) { throw new ArgumentNullException("path"); } lock (_lock) { List <string> names = new List <string>(); foreach (GitItem v in _map.Values) { string name = v.FullPath; if (v.IsBelowPath(path)) { v.MarkDirty(); } } } }
public override void OnExecute(CommandEventArgs e) { ISvnRepositoryItem item = EnumTools.GetSingle(e.Selection.GetSelection <ISvnRepositoryItem>()); if (item == null) { return; } string copyTo; bool copyBelow = false; bool suggestExport = false; ISvnStatusCache cache = e.GetService <ISvnStatusCache>(); if (item.NodeKind == SharpSvn.SvnNodeKind.Directory) { using (FolderBrowserDialog fd = new FolderBrowserDialog()) { fd.ShowNewFolderButton = false; if (DialogResult.OK != fd.ShowDialog(e.Context.DialogOwner)) { return; } copyTo = fd.SelectedPath; copyBelow = true; SvnItem dirItem = cache[copyTo]; if (dirItem == null || !dirItem.IsVersioned) { suggestExport = true; } } } else { using (SaveFileDialog sfd = new SaveFileDialog()) { sfd.CheckPathExists = true; sfd.OverwritePrompt = true; string name = item.Origin.Target.FileName; string ext = Path.GetExtension(item.Origin.Target.FileName); sfd.Filter = string.Format("{0} files|*.{0}|All files (*.*)|*", ext.TrimStart('.')); sfd.FileName = name; if (DialogResult.OK != sfd.ShowDialog(e.Context.DialogOwner)) { return; } copyTo = SvnTools.GetNormalizedFullPath(sfd.FileName); SvnItem fileItem = cache[copyTo]; if (File.Exists(copyTo)) { // We prompted to confirm; remove the file! if (fileItem.IsVersioned) { e.GetService <IProgressRunner>().RunModal(CommandStrings.Copying, delegate(object sender, ProgressWorkerArgs a) { SvnDeleteArgs da = new SvnDeleteArgs(); da.Force = true; a.Client.Delete(copyTo, da); }); } else { SvnItem.DeleteNode(copyTo); } } SvnItem dir = fileItem.Parent; if (dir == null || !(dir.IsVersioned && dir.IsVersionable)) { suggestExport = true; } } } if (!suggestExport) { e.GetService <IProgressRunner>().RunModal(CommandStrings.Copying, delegate(object sender, ProgressWorkerArgs a) { SvnCopyArgs ca = new SvnCopyArgs(); ca.CreateParents = true; if (copyBelow) { ca.AlwaysCopyAsChild = true; } a.Client.Copy(item.Origin.Target, copyTo, ca); }); } else { AnkhMessageBox mb = new AnkhMessageBox(e.Context); if (DialogResult.Yes == mb.Show(CommandStrings.NotInWorkingCopyExportInstead, CommandStrings.NotInWorkingCopyTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Information)) { e.GetService <IProgressRunner>().RunModal(CommandStrings.Exporting, delegate(object sender, ProgressWorkerArgs a) { SvnExportArgs ea = new SvnExportArgs(); ea.Revision = item.Revision; ea.Overwrite = true; a.Client.Export(item.Origin.Target, copyTo, ea); }); } } }
private static void CheckOutAndOpenProject(CommandEventArgs e, SvnUriTarget checkoutLocation, SvnRevision revision, Uri projectTop, string localDir, Uri projectUri) { IProgressRunner runner = e.GetService <IProgressRunner>(); runner.RunModal(CommandStrings.CheckingOutSolution, delegate(object sender, ProgressWorkerArgs ee) { PerformCheckout(ee, checkoutLocation, revision, localDir); }); Uri file = projectTop.MakeRelativeUri(projectUri); string projectFile = SvnTools.GetNormalizedFullPath(Path.Combine(localDir, SvnTools.UriPartToPath(file.ToString()))); AddProject(e, projectFile); using (ProjectAddInfoDialog pai = new ProjectAddInfoDialog()) { IAnkhSolutionSettings ss = e.GetService <IAnkhSolutionSettings>(); ISvnStatusCache cache = e.GetService <ISvnStatusCache>(); SvnItem rootItem; pai.EnableSlnConnection = false; if (ss == null || cache == null || string.IsNullOrEmpty(ss.ProjectRoot) || !SvnItem.IsBelowRoot(localDir, ss.ProjectRoot) || null == (rootItem = cache[localDir])) { pai.EnableExternal = false; pai.EnableCopy = false; } else { SvnItem dir = rootItem.Parent; if (ss.ProjectRootSvnItem != null && ss.ProjectRootSvnItem.IsVersioned) { HybridCollection <string> dirs = new HybridCollection <string>(); SvnItem exDir = dir; while (exDir != null && exDir.IsBelowPath(ss.ProjectRoot)) { if (exDir.IsVersioned && exDir.WorkingCopy == ss.ProjectRootSvnItem.WorkingCopy) { dirs.Add(exDir.FullPath); } exDir = exDir.Parent; } pai.SetExternalDirs(dirs); pai.EnableExternal = true; } else { pai.EnableExternal = false; } if (rootItem.WorkingCopy != null && dir.WorkingCopy != null) { pai.EnableCopy = (rootItem.WorkingCopy.RepositoryRoot == dir.WorkingCopy.RepositoryRoot) && (rootItem.WorkingCopy.RepositoryId == dir.WorkingCopy.RepositoryId); } else { pai.EnableCopy = false; } } if (pai.ShowDialog(e.Context) == DialogResult.OK) { switch (pai.SelectedMode) { case ProjectAddMode.External: if (pai.ExternalLocation != null) { using (SvnClient cl = e.GetService <ISvnClientPool>().GetNoUIClient()) { string externals; if (!cl.TryGetProperty(pai.ExternalLocation, SvnPropertyNames.SvnExternals, out externals)) { externals = ""; } SvnExternalItem sei; if (pai.ExternalLocked) { sei = new SvnExternalItem(SvnItem.SubPath(localDir, pai.ExternalLocation), checkoutLocation.Uri, revision, revision); } else { sei = new SvnExternalItem(SvnItem.SubPath(localDir, pai.ExternalLocation), checkoutLocation.Uri); } externals = sei.ToString(true) + Environment.NewLine + externals; cl.SetProperty(pai.ExternalLocation, SvnPropertyNames.SvnExternals, externals); } } break; case ProjectAddMode.Copy: using (SvnClient cl = e.GetService <ISvnClientPool>().GetClient()) { string tmpDir = localDir + "-Src-copyTmp"; Directory.CreateDirectory(tmpDir); Directory.Move(Path.Combine(localDir, SvnClient.AdministrativeDirectoryName), Path.Combine(tmpDir, SvnClient.AdministrativeDirectoryName)); SvnCopyArgs ma = new SvnCopyArgs(); ma.MetaDataOnly = true; cl.Copy(tmpDir, localDir, ma); SvnItem.DeleteDirectory(tmpDir, true); cache.MarkDirtyRecursive(localDir); } break; case ProjectAddMode.Unversioned: cache.MarkDirtyRecursive(localDir); SvnItem.DeleteDirectory(Path.Combine(localDir, SvnClient.AdministrativeDirectoryName), true); e.GetService <IFileStatusMonitor>().ScheduleGlyphUpdate(projectFile); // And everything else in the project break; } } } }
/// <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 void Path_NormalizePrefixesArway() { Assert.That(SvnTools.GetNormalizedFullPath(@"\\?\C:\Windows\Q"), Is.EqualTo(@"C:\Windows\Q")); Assert.That(SvnTools.GetNormalizedFullPath(@"\\?\UNC\server\Share\Windows\Q"), Is.EqualTo(@"\\server\Share\Windows\Q")); }
public void Path_NormalizePathSharp() { Assert.That(SvnTools.GetNormalizedFullPath("c:\\a\\..\\123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\\"), Is.EqualTo("C:\\123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")); Assert.That(SvnTools.GetNormalizedFullPath("C:\\123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"), Is.EqualTo("C:\\123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"), "Shortcut route via IsNormalized"); Assert.That(SvnTools.GetNormalizedDirectoryName("C:\\asdasdashdadhjadjahjdhasjhajhfasdjsdf\\sdsdfsdfsdfgsdjhfsda hjsdsdf sdaf\\sad sad sad f\\"), Is.EqualTo("C:\\asdasdashdadhjadjahjdhasjhajhfasdjsdf\\sdsdfsdfsdfgsdjhfsda hjsdsdf sdaf")); Assert.That(SvnTools.GetNormalizedDirectoryName("C:\\"), Is.Null); Assert.That(SvnTools.GetNormalizedDirectoryName("C:\\\\"), Is.Null); string drive = Environment.CurrentDirectory.Substring(0, 2).ToLowerInvariant(); Assert.That(SvnTools.GetNormalizedDirectoryName(drive), Is.EqualTo(drive.ToUpperInvariant() + Path.GetDirectoryName(Environment.CurrentDirectory).Substring(2))); // CWD on current drive Assert.That(SvnTools.GetNormalizedDirectoryName("C:\\"), Is.Null); Assert.That(SvnTools.GetNormalizedDirectoryName("C:\\\\"), Is.Null); Assert.That(SvnTools.GetNormalizedDirectoryName("c:\\a"), Is.EqualTo("C:\\")); Assert.That(Path.GetDirectoryName(@"\\Server\Share\Path"), Is.EqualTo(@"\\Server\Share")); Assert.That(Path.GetDirectoryName(@"\\Server\Share"), Is.Null); Assert.That(Path.GetDirectoryName(@"C:\Dir\Sub\"), Is.EqualTo(@"C:\Dir\Sub")); Assert.That(Path.GetDirectoryName(@"C:\Dir\Sub"), Is.EqualTo(@"C:\Dir")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"\\Server\Share\Path"), Is.EqualTo(@"\\server\Share")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"\\Server\Share"), Is.Null); Assert.That(Path.GetDirectoryName(@"\\server\c$"), Is.Null); Assert.That(Path.GetDirectoryName(@"\\server\c$\\"), Is.EqualTo(@"\\server\c$")); Assert.That(SvnTools.GetNormalizedFullPath(@"\\server\c$"), Is.EqualTo(@"\\server\c$")); Assert.That(SvnTools.GetNormalizedFullPath(@"\\seRver\c$\"), Is.EqualTo(@"\\server\c$")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"\\server\c$"), Is.Null); Assert.That(SvnTools.GetNormalizedDirectoryName(@"\\server\c$\\"), Is.Null); Assert.That(SvnTools.GetNormalizedDirectoryName(@"\\seRver\c$\\"), Is.Null); string share = @"\\" + Environment.MachineName.ToLowerInvariant() + @"\C$"; string shaUC = @"\\" + Environment.MachineName.ToUpperInvariant() + @"\C$"; Assert.That(SvnTools.IsNormalizedFullPath(share)); Assert.That(!SvnTools.IsNormalizedFullPath(shaUC)); Assert.That(!SvnTools.IsNormalizedFullPath(share + "\\")); Assert.That(!SvnTools.IsNormalizedFullPath(shaUC + "\\")); Assert.That(SvnTools.GetTruePath(share + "\\A\\B", true), Is.EqualTo(share + "\\A\\B")); Assert.That(SvnTools.GetTruePath(share + "\\A", true), Is.EqualTo(share + "\\A")); Assert.That(SvnTools.GetTruePath(share, true), Is.EqualTo(share)); Assert.That(SvnTools.GetTruePath(share + "\\", true), Is.EqualTo(share)); Assert.That(SvnTools.GetTruePath("C:\\A", true), Is.EqualTo("C:\\A")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"C:\dir"), Is.EqualTo(@"C:\")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"c:\dir"), Is.EqualTo(@"C:\")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"C:\dir\\"), Is.EqualTo(@"C:\")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"c:\dir\\"), Is.EqualTo(@"C:\")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"C:\sub\dir"), Is.EqualTo(@"C:\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"c:\sub\dir"), Is.EqualTo(@"C:\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"C:\sub\dir\\"), Is.EqualTo(@"C:\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"c:\sub\dir\\"), Is.EqualTo(@"C:\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"C:\dir"), Is.EqualTo(@"C:\")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"c:\dir"), Is.EqualTo(@"C:\")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"C:\dir\\"), Is.EqualTo(@"C:\")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"c:\dir\\"), Is.EqualTo(@"C:\")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"C:\sub\dir"), Is.EqualTo(@"C:\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"c:\sub\dir"), Is.EqualTo(@"C:\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"C:\sub\dir\\"), Is.EqualTo(@"C:\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(@"c:\sub\dir\\"), Is.EqualTo(@"C:\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(share + @"\dir"), Is.EqualTo(share)); Assert.That(SvnTools.GetNormalizedDirectoryName(shaUC + @"\dir"), Is.EqualTo(share)); Assert.That(SvnTools.GetNormalizedDirectoryName(share + @"\dir\\"), Is.EqualTo(share)); Assert.That(SvnTools.GetNormalizedDirectoryName(shaUC + @"\dir\\"), Is.EqualTo(share)); Assert.That(SvnTools.GetNormalizedDirectoryName(share + @"\sub\dir"), Is.EqualTo(share + @"\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(shaUC + @"\sub\dir"), Is.EqualTo(share + @"\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(share + @"\sub\dir\\"), Is.EqualTo(share + @"\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(shaUC + @"\sub\dir\\"), Is.EqualTo(share + @"\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(share + @"\dir"), Is.EqualTo(share)); Assert.That(SvnTools.GetNormalizedDirectoryName(shaUC + @"\dir"), Is.EqualTo(share)); Assert.That(SvnTools.GetNormalizedDirectoryName(share + @"\dir\\"), Is.EqualTo(share)); Assert.That(SvnTools.GetNormalizedDirectoryName(shaUC + @"\dir\\"), Is.EqualTo(share)); Assert.That(SvnTools.GetNormalizedDirectoryName(share + @"\sub\dir"), Is.EqualTo(share + @"\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(shaUC + @"\sub\dir"), Is.EqualTo(share + @"\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(share + @"\sub\dir\\"), Is.EqualTo(share + @"\sub")); Assert.That(SvnTools.GetNormalizedDirectoryName(shaUC + @"\sub\dir\\"), Is.EqualTo(share + @"\sub")); }
private void TryFindOrigin(string newName, out string origin) { ThreadHelper.ThrowIfNotOnUIThread(); if (_fileOrigins.TryGetValue(newName, out origin)) { if (origin != null) { return; } } else { _fileOrigins.Add(newName, null); } // We haven't got the project file origin for free via OnQueryAddFilesEx // So: // 1 - The file is really new or // 2 - The file is drag&dropped into the project from the solution explorer or // 3 - The file is copy pasted into the project from an other project or // 4 - The file is added via add existing item or // 5 - The file is added via drag&drop from another application (OLE drop) // // The only way to determine is walking through these options SortedList <string, string> nameToItem = new SortedList <string, string>(); nameToItem[Path.GetFileName(newName)] = newName; foreach (KeyValuePair <string, string> kv in _fileOrigins) { if (kv.Value != null) { continue; } nameToItem[Path.GetFileName(kv.Key)] = kv.Key; } // 2 - If the file is drag&dropped in the solution explorer // the current selection is still the original selection // **************** Check the current selection ************* // Checks for drag&drop actions. The selection contains the original list of files // BH: resx files are not correctly included if we don't retrieve this list recursive foreach (string file in SelectionContext.GetSelectedFiles(true)) { if (_fileOrigins.ContainsKey(file)) { continue; } string name = Path.GetFileName(file); if (nameToItem.ContainsKey(name)) { string item = nameToItem[name]; CheckForMatch(item, file); } } // **************** Check the clipboard ********************* // 3 - Copy & Paste in the solution explorer: // The original hierarchy information is still on the clipboard IDataObject dataObject; string projectItemType; if (null != (dataObject = SafeGetDataObject()) && SolutionExplorerClipboardItem.CanRead(dataObject, out projectItemType)) { IVsSolution solution = GetService <IVsSolution>(typeof(SVsSolution)); ISccProjectWalker walker = GetService <ISccProjectWalker>(); foreach (string projref in SolutionExplorerClipboardItem.DecodeProjectItemData(dataObject, projectItemType)) { IVsHierarchy project; uint itemid; { string updatedRef; VSUPDATEPROJREFREASON[] updateReason = new VSUPDATEPROJREFREASON[1]; if (!VSErr.Succeeded(solution.GetItemOfProjref(projref, out project, out itemid, out updatedRef, updateReason))) { continue; } } foreach (string rawFile in walker.GetSccFiles(project, itemid, ProjectWalkDepth.AllDescendantsInHierarchy, null)) { if (!SvnItem.IsValidPath(rawFile)) { continue; } string file = SvnTools.GetNormalizedFullPath(rawFile); if (_fileOrigins.ContainsKey(file)) { continue; } string name = Path.GetFileName(file); if (nameToItem.ContainsKey(name)) { string item = nameToItem[name]; CheckForMatch(item, file); } } } } // **************** Check external hints ******************** // Checks for HandsOff events send by the project system foreach (string file in _fileHints) { if (_fileOrigins.ContainsKey(file)) { continue; } string name = Path.GetFileName(file); if (nameToItem.ContainsKey(name)) { string item = nameToItem[name]; CheckForMatch(item, file); } } // The clipboard seems to have some other format which might contain other info origin = _fileOrigins[newName]; if (origin == null) { bool first = true; string path = null; foreach (KeyValuePair <string, string> kv in _fileOrigins) { if (kv.Value == null) { continue; } if (SvnItem.IsBelowRoot(kv.Key, newName)) { string itemRoot = kv.Value.Substring(0, kv.Value.Length - kv.Key.Length + newName.Length); if (first) { path = itemRoot; first = false; } else if (path != itemRoot) { origin = null; return; } } } origin = path; } }
/// <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); }