public override void OnExecute(CommandEventArgs e) { ISvnStatusCache cache = e.GetService <ISvnStatusCache>(); if (cache == null || e.Selection.SolutionFilename == null) { return; } if (!e.State.SccProviderActive) { // Ok, we should now enable ourselves as the SCC provider to get // our state loaded IAnkhSccService sccService = e.GetService <IAnkhSccService>(); sccService.RegisterAsPrimarySccProvider(); sccService.EnsureLoaded(); } SvnItem item = cache[e.Selection.SolutionFilename]; if (!HandleUnmanagedOrUnversionedSolution(e, item)) { return; } if (e.Command == AnkhCommand.FileSccAddSolutionToSubversion) { return; } SetProjectsManaged(e); }
SvnItemAnnotation(ISvnStatusCache context, string fullPath, XmlReader from) : this(context, fullPath) { if (!from.MoveToFirstAttribute()) { throw new InvalidOperationException(); } Dictionary <string, string> rest = null; do { switch (from.Name) { case AttrName: break; // TODO: Read explicit values default: if (rest == null) { rest = new Dictionary <string, string>(StringComparer.Ordinal); } rest[from.Name] = from.Value; break; } }while (from.MoveToNextAttribute()); _justStored = rest; from.MoveToElement(); }
public void RefreshText(IAnkhServiceProvider context) { if (context == null) { throw new ArgumentNullException("context"); } ISvnStatusCache cache = context.GetService <ISvnStatusCache>(); ImageIndex = PendingChange.IconIndex; SvnItem item = cache[FullPath]; if (item == null) { throw new InvalidOperationException(); // Item no longer valued } PendingChangeStatus pcs = PendingChange.Change ?? new PendingChangeStatus(PendingChangeKind.None); SetValues( pcs.PendingCommitText, PendingChange.ChangeList, GetDirectory(item), PendingChange.FullPath, item.IsLocked ? PCResources.LockedValue : "", // Locked SafeDate(item.Modified), // Modified PendingChange.Name, PendingChange.RelativePath, PendingChange.Project, context.GetService <IFileIconMapper>().GetFileType(item), SafeWorkingCopy(item)); }
public override IEnumerable <WCTreeNode> GetChildren() { ISvnStatusCache cache = Context.GetService <ISvnStatusCache>(); foreach (string s in Environment.GetLogicalDrives()) { switch (NativeMethods.GetDriveType(s)) { case NativeMethods.DriveType.Removable: if (s != "A:\\") // We should really filter floppy/disconnected drives { goto case NativeMethods.DriveType.Fixed; } break; case NativeMethods.DriveType.Fixed: case NativeMethods.DriveType.Remote: case NativeMethods.DriveType.RAMDisk: yield return(new WCDirectoryNode(Context, this, cache[s])); break; default: break; } } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); IAnkhSolutionSettings settings = Context.GetService <IAnkhSolutionSettings>(); ISvnStatusCache cache = Context.GetService <ISvnStatusCache>(); SvnItem slnDirItem = cache[settings.SolutionFilename].Parent; SvnWorkingCopy wc = slnDirItem.WorkingCopy; if (wc != null && slnDirItem.Uri != null) { SvnItem dirItem = slnDirItem; Uri cur = dirItem.Uri; Uri setUri = settings.ProjectRootUri; while (dirItem != null && dirItem.IsBelowPath(wc.FullPath)) { UriMap value = new UriMap(cur, dirItem.FullPath); slnBindPath.Items.Add(value); if (setUri == value.Uri) { slnBindPath.SelectedItem = value; } dirItem = dirItem.Parent; cur = new Uri(cur, "../"); } } }
/// <see cref="Ankh.Commands.ICommandHandler.OnExecute" /> public void OnExecute(CommandEventArgs e) { List <SvnItem> svnItems = new List <SvnItem>(); ISvnStatusCache cache = e.GetService <ISvnStatusCache>(); switch (e.Command) { case AnkhCommand.ItemMerge: // TODO: Check for solution and/or project selection to use the folder instead of the file foreach (SvnItem item in e.Selection.GetSelectedSvnItems(false)) { svnItems.Add(item); } break; case AnkhCommand.ProjectMerge: foreach (SccProject p in e.Selection.GetSelectedProjects(false)) { IProjectFileMapper pfm = e.GetService <IProjectFileMapper>(); ISccProjectInfo info = pfm.GetProjectInfo(p); if (info != null && info.ProjectDirectory != null) { svnItems.Add(cache[info.ProjectDirectory]); } } break; case AnkhCommand.SolutionMerge: svnItems.Add(cache[e.GetService <IAnkhSolutionSettings>().ProjectRoot]); break; default: throw new InvalidOperationException(); } IEnumerable <string> selectedFiles = e.Selection.GetSelectedFiles(true); IAnkhOpenDocumentTracker tracker = e.GetService <IAnkhOpenDocumentTracker>(); using (DocumentLock lck = tracker.LockDocuments(selectedFiles, DocumentLockType.ReadOnly)) using (lck.MonitorChangesForReload()) using (MergeWizard dialog = new MergeWizard(e.Context, svnItems[0])) { DialogResult result = dialog.ShowDialog(e.Context); //result = uiService.ShowDialog(dialog); if (result == DialogResult.OK) { using (MergeResultsDialog mrd = new MergeResultsDialog()) { mrd.MergeActions = dialog.MergeActions; mrd.ResolvedMergeConflicts = dialog.ResolvedMergeConflicts; mrd.ShowDialog(e.Context); } } } }
public static SvnItemAnnotation Load(ISvnStatusCache context, XmlReader from, string wcRoot) { if (from.Name != ElemNode) { return(null); } string name = from.GetAttribute(AttrName); return(new SvnItemAnnotation(context, Path.Combine(wcRoot, name), from)); }
public int DirectoryChanged(string pszDirectory) { ISvnStatusCache fsc = GetService <ISvnStatusCache>(); if (fsc != null) { fsc.MarkDirtyRecursive(SvnTools.GetNormalizedFullPath(pszDirectory)); } return(VSErr.S_OK); }
string GetSccBaseDirectory() { ThreadHelper.ThrowIfNotOnUIThread(); string projectDir = ProjectDirectory; if (projectDir == null) { return(null); } // TODO: Insert project local settings check IAnkhSolutionSettings settings = GetService <IAnkhSolutionSettings>(); ISvnStatusCache cache = GetService <ISvnStatusCache>(); SvnItem solutionRoot = settings.ProjectRootSvnItem; if (solutionRoot == null) { return(null); // Fix the solution before we try any SCC, thanks! } SvnItem projectDirItem = cache[projectDir]; if (projectDirItem != null && projectDirItem.WorkingCopy != null) { // Project is below standard workingcopy if (projectDirItem.IsBelowPath(solutionRoot)) { if (solutionRoot.WorkingCopy == projectDirItem.WorkingCopy) { // Project is in the same working copy.. use the solution root // to automatically handle in-between directory levels return(solutionRoot.FullPath); } // Project has its own workingcopy below the solution root // -> Use the complete workingcopy (might be shared with multiple projects) return(projectDirItem.WorkingCopy.FullPath); } if (solutionRoot.WorkingCopy != projectDirItem.WorkingCopy) { // Project is below a root of its own.. use its workingcopy return(projectDirItem.WorkingCopy.FullPath); } // The user deliberately choose not to have the item in the solution root // -> Default to the project directory } return(ProjectDirectory); }
public RefreshState(IAnkhServiceProvider context, IVsHierarchy hier, IVsProject project, string projectDir) { _hier = hier; _cache = context.GetService <ISvnStatusCache>(); _walker = context.GetService <ISccProjectWalker>(); _project = project as IVsProject2; _projectDir = projectDir; if (projectDir != null) { _projectDirItem = Cache[projectDir]; } }
public SvnItem(ISvnStatusCache context, string fullPath, NoSccStatus status, SvnNodeKind nodeKind) : base(fullPath) { if (context == null) { throw new ArgumentNullException("context"); } _context = context; _enqueued = true; RefreshTo(status, nodeKind); _enqueued = false; }
public SvnItemAnnotation(ISvnStatusCache context, string fullPath) { if (context == null) { throw new ArgumentNullException("context"); } else if (string.IsNullOrEmpty(fullPath)) { throw new ArgumentNullException("fullPath"); } _context = context; _fullPath = fullPath; }
void RefreshStatus() { _statusDirty = XBool.None; ISvnStatusCache statusCache = StatusCache; try { statusCache.RefreshItem(this, IsFile ? SvnNodeKind.File : SvnNodeKind.Directory); // We can check this less expensive than the statuscache! } finally { Debug.Assert(_statusDirty == XBool.False, "No longer dirty after refresh", string.Format("Path = {0}", FullPath)); _statusDirty = XBool.False; } }
public void Write(ISvnStatusCache context, XmlWriter to, string wcRoot) { to.WriteStartElement(ElemNode); to.WriteAttributeString(AttrName, new Uri(wcRoot).MakeRelativeUri(new Uri(wcRoot)).ToString()); // TODO: Write explicit values if (_justStored != null) { foreach (KeyValuePair <string, string> kv in _justStored) { to.WriteAttributeString(kv.Key, kv.Value); } } to.WriteEndElement(); }
/// <summary> /// Gets this node as a directory or NULL if it is no directory on disk /// </summary> /// <returns></returns> public SvnDirectory AsDirectory() { if (!IsDirectory) { return(null); } ISvnStatusCache cache = StatusCache; if (cache == null) { return(null); } return(cache.GetDirectory(FullPath)); }
public SvnItem(ISvnStatusCache context, string fullPath, SvnStatusData status) : base(fullPath) { if (context == null) { throw new ArgumentNullException("context"); } else if (status == null) { throw new ArgumentNullException("status"); } _context = context; _status = status; _enqueued = true; RefreshTo(status); _enqueued = false; }
private void RefreshFromList(List <SvnStatusEventArgs> resultList) { syncView.Items.Clear(); if (resultList != null && resultList.Count > 0) { ISvnStatusCache fs = Context.GetService <ISvnStatusCache>(); List <SynchronizeListItem> items = new List <SynchronizeListItem>(resultList.Count); foreach (SvnStatusEventArgs s in resultList) { SvnItem item = fs[s.FullPath]; if (item == null) { return; } items.Add(new SynchronizeListItem(syncView, item, s)); } syncView.Items.AddRange(items.ToArray()); } updateTime.Text = string.Format(PCResources.RefreshTimeX, DateTime.Now.ToShortTimeString()); }
public void OnExecute(CommandEventArgs e) { SvnItem firstVersioned = null; ISvnStatusCache cache = e.GetService <ISvnStatusCache>(); IAnkhSolutionSettings solutionSettings = e.GetService <IAnkhSolutionSettings>(); if (solutionSettings != null) { firstVersioned = cache[solutionSettings.ProjectRoot]; } if (firstVersioned == null) { return; // exceptional case } using (IssueTrackerConfigDialog dialog = new IssueTrackerConfigDialog(e.Context)) { if (dialog.ShowDialog(e.Context) == System.Windows.Forms.DialogResult.OK) { IIssueTrackerSettings currentSettings = e.GetService <IIssueTrackerSettings>(); IssueRepository newRepository = dialog.NewIssueRepository; if (newRepository == null || string.IsNullOrEmpty(newRepository.ConnectorName) || newRepository.RepositoryUri == null) { DeleteIssueRepositoryProperties(e.Context, firstVersioned); } else if (currentSettings == null || currentSettings.ShouldPersist(newRepository)) { SetIssueRepositoryProperties(e.Context, firstVersioned, newRepository); } } } }
public void RefreshText(IAnkhServiceProvider context) { if (context == null) { throw new ArgumentNullException("context"); } ISvnStatusCache cache = context.GetService <ISvnStatusCache>(); int idx = PendingChange.IconIndex; if (idx >= 0) { ImageIndex = idx; // Setting to -1 raises an exception } SvnItem item = cache[FullPath]; if (item == null) { throw new InvalidOperationException(); // Every path should return a SvnItem } PendingChangeStatus pcs = PendingChange.Change ?? new PendingChangeStatus(PendingChangeKind.None); SetValues( pcs.PendingCommitText, _lastChangeList = PendingChange.ChangeList, GetDirectory(item), PendingChange.FullPath, item.IsLocked ? PCResources.LockedValue : "", // Locked SafeDate(item.Modified), // Modified PendingChange.Name, PendingChange.RelativePath, PendingChange.Project, GetRevision(PendingChange), PendingChange.FileType, SafeWorkingCopy(item)); IAnkhCommandStates states = context.GetService <IAnkhCommandStates>(); if (!SystemInformation.HighContrast && (!states.ThemeDefined || states.ThemeLight)) { System.Drawing.Color clr = System.Drawing.Color.Black; if (item.IsConflicted || PendingChange.Kind == PendingChangeKind.WrongCasing) { clr = System.Drawing.Color.Red; } else if (item.IsDeleteScheduled) { if (item.Exists && item.InSolution && !item.IsSccExcluded) { clr = System.Drawing.Color.FromArgb(100, 0, 100); // As added } else { clr = System.Drawing.Color.DarkRed; } } else if (item.Status.IsCopied || item.Status.LocalNodeStatus == SharpSvn.SvnStatus.Added) { clr = System.Drawing.Color.FromArgb(100, 0, 100); } else if (!item.IsVersioned) { if (item.InSolution && !item.IsIgnored) { clr = System.Drawing.Color.FromArgb(100, 0, 100); // Same as added+copied } else { clr = System.Drawing.Color.Black; } } else if (item.IsModified) { clr = System.Drawing.Color.DarkBlue; } ForeColor = clr; } else if (this.ListView != null) { ForeColor = this.ListView.ForeColor; } }
public override void OnExecute(CommandEventArgs e) { SvnItem theItem = null; string path; bool allowObstructions = false; string projectRoot = e.GetService <IAnkhSolutionSettings>().ProjectRoot; if (e.Command == AnkhCommand.SolutionSwitchDialog) { path = projectRoot; } else if (e.Command == AnkhCommand.SwitchProject) { IProjectFileMapper mapper = e.GetService <IProjectFileMapper>(); path = null; foreach (SccProject item in e.Selection.GetSelectedProjects(true)) { ISccProjectInfo pi = mapper.GetProjectInfo(item); if (pi == null) { continue; } path = pi.ProjectDirectory; break; } if (string.IsNullOrEmpty(path)) { return; } } else { foreach (SvnItem item in e.Selection.GetSelectedSvnItems(false)) { if (item.IsVersioned) { theItem = item; break; } return; } path = theItem.FullPath; } ISvnStatusCache statusCache = e.GetService <ISvnStatusCache>(); SvnItem pathItem = statusCache[path]; Uri uri = pathItem.Uri; if (uri == null) { return; // Should never happen on a real workingcopy } SvnUriTarget target; SvnRevision revision = SvnRevision.None; if (e.Argument is string) { target = SvnUriTarget.FromString((string)e.Argument, true); revision = (target.Revision != SvnRevision.None) ? target.Revision : SvnRevision.Head; } else if (e.Argument is Uri) { target = (Uri)e.Argument; } else { using (SwitchDialog dlg = new SwitchDialog()) { dlg.Context = e.Context; dlg.LocalPath = path; dlg.RepositoryRoot = e.GetService <ISvnStatusCache>()[path].WorkingCopy.RepositoryRoot; dlg.SwitchToUri = uri; dlg.Revision = SvnRevision.Head; if (dlg.ShowDialog(e.Context) != DialogResult.OK) { return; } target = dlg.SwitchToUri; revision = dlg.Revision; allowObstructions = dlg.AllowUnversionedObstructions; } } // Get a list of all documents below the specified paths that are open in editors inside VS HybridCollection <string> lockPaths = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); IAnkhOpenDocumentTracker documentTracker = e.GetService <IAnkhOpenDocumentTracker>(); foreach (string file in documentTracker.GetDocumentsBelow(path)) { if (!lockPaths.Contains(file)) { lockPaths.Add(file); } } documentTracker.SaveDocuments(lockPaths); // Make sure all files are saved before merging! using (DocumentLock lck = documentTracker.LockDocuments(lockPaths, DocumentLockType.NoReload)) using (lck.MonitorChangesForReload()) { Uri newRepositoryRoot = null; e.GetService <IProgressRunner>().RunModal(CommandStrings.SwitchingTitle, delegate(object sender, ProgressWorkerArgs a) { SvnSwitchArgs args = new SvnSwitchArgs(); args.AllowObstructions = allowObstructions; args.AddExpectedError(SvnErrorCode.SVN_ERR_WC_INVALID_SWITCH); if (revision != SvnRevision.None) { args.Revision = revision; } e.GetService <IConflictHandler>().RegisterConflictHandler(args, a.Synchronizer); if (!a.Client.Switch(path, target, args)) { if (args.LastException.SvnErrorCode != SvnErrorCode.SVN_ERR_WC_INVALID_SWITCH) { return; } // source/target repository is different, check if we can fix this by relocating SvnInfoEventArgs iea; if (a.Client.GetInfo(target, out iea)) { if (pathItem.WorkingCopy.RepositoryId != iea.RepositoryId) { e.Context.GetService <IAnkhDialogOwner>() .MessageBox.Show("Cannot switch to different repository because the repository UUIDs are different", "Cannot switch", MessageBoxButtons.OK, MessageBoxIcon.Error); } else if (pathItem.WorkingCopy.RepositoryRoot != iea.RepositoryRoot) { newRepositoryRoot = iea.RepositoryRoot; } else if (pathItem.WorkingCopy.RepositoryId == Guid.Empty) { // No UUIDs and RepositoryRoot equal. Throw/show error? throw args.LastException; } } } }); if (newRepositoryRoot != null && DialogResult.Yes == e.Context.GetService <IAnkhDialogOwner>() .MessageBox.Show(string.Format("The repository root specified is different from the one in your " + "working copy. Would you like to relocate '{0}' from '{1}' to '{2}'?", pathItem.WorkingCopy.FullPath, pathItem.WorkingCopy.RepositoryRoot, newRepositoryRoot), "Relocate", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) { // We can fix this by relocating string wcRoot = pathItem.WorkingCopy.FullPath; try { e.GetService <IProgressRunner>().RunModal( CommandStrings.RelocatingTitle, delegate(object sender, ProgressWorkerArgs a) { a.Client.Relocate(wcRoot, pathItem.WorkingCopy.RepositoryRoot, newRepositoryRoot); }); } finally { statusCache.MarkDirtyRecursive(wcRoot); e.GetService <IFileStatusMonitor>().ScheduleGlyphUpdate(statusCache.GetCachedBelow(wcRoot)); } if (DialogResult.Yes == e.Context.GetService <IAnkhDialogOwner>() .MessageBox.Show(string.Format("Would you like to try to switch '{0}' to '{1}' again?", path, target), "Switch", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) { // Try to switch again e.GetService <IProgressRunner>().RunModal( CommandStrings.SwitchingTitle, delegate(object sender, ProgressWorkerArgs a) { SvnSwitchArgs args = new SvnSwitchArgs(); if (revision != SvnRevision.None) { args.Revision = revision; } args.AllowObstructions = allowObstructions; e.GetService <IConflictHandler>().RegisterConflictHandler(args, a.Synchronizer); a.Client.Switch(path, target, args); }); } } } }
public override void OnUpdate(CommandUpdateEventArgs e) { if (!e.State.SolutionExists || (e.Command == AnkhCommand.FileSccAddProjectToSubversion && e.State.EmptySolution)) { e.Enabled = false; return; } if (e.State.OtherSccProviderActive) { e.Enabled = false; return; // Only one scc provider can be active at a time } IAnkhSccService scc = e.GetService <IAnkhSccService>(); ISvnStatusCache cache = e.GetService <ISvnStatusCache>(); if (scc == null || cache == null) { e.Enabled = false; return; } string solutionFilename = e.Selection.SolutionFilename; if (string.IsNullOrEmpty(solutionFilename) || !SvnItem.IsValidPath(solutionFilename)) { solutionFilename = null; } if (e.Command == AnkhCommand.FileSccAddSolutionToSubversion) { if (solutionFilename == null || scc.IsSolutionManaged) { e.Enabled = false; // Already handled return; } SvnItem item = cache[solutionFilename]; if (!item.Exists || !item.IsFile || item.ParentDirectory.NeedsWorkingCopyUpgrade) { // Decide where you store the .sln first e.Enabled = false; return; } if (!item.IsVersioned) { // If the .sln is ignored hide it in the context menus // but don't hide it on the node itself e.HideOnContextMenu = item.IsIgnored && !e.Selection.IsSolutionSelected; } return; } IProjectFileMapper pfm = e.GetService <IProjectFileMapper>(); int n = 0; bool foundOne = false; foreach (IEnumerable <SccProject> projects in new IEnumerable <SccProject>[] { e.Selection.GetSelectedProjects(true), e.Selection.GetSelectedProjects(false) }) { foreach (SccProject p in projects) { foundOne = true; ISccProjectInfo pi = pfm.GetProjectInfo(p); if (pi == null || !pi.IsSccBindable) { continue; // Not an SCC project } // A project is managed if the file says its managed // and the project dir is managed if (pi.ProjectDirectory != null && cache[pi.ProjectDirectory].IsVersioned && scc.IsProjectManaged(p)) { continue; // Nothing to do here } string projectFile = pi.ProjectFile; if (n > 1 && projectFile != null && cache[projectFile].IsIgnored) { e.HideOnContextMenu = true; } return; } n++; if (foundOne) { break; } } e.Enabled = false; }
static void SetProjectsManaged(CommandEventArgs e) { ISvnStatusCache cache = e.GetService <ISvnStatusCache>(); IFileStatusMonitor monitor = e.GetService <IFileStatusMonitor>(); IAnkhSccService scc = e.GetService <IAnkhSccService>(); IProjectFileMapper mapper = e.GetService <IProjectFileMapper>(); AnkhMessageBox mb = new AnkhMessageBox(e.Context); if (mapper == null) { return; } List <SccProject> projectsToBeManaged = new List <SccProject>(); SvnItem slnItem = cache[e.Selection.SolutionFilename]; Uri solutionReposRoot = null; if (slnItem.WorkingCopy != null) { solutionReposRoot = slnItem.WorkingCopy.RepositoryRoot; foreach (SccProject project in GetSelection(e.Selection)) { ISccProjectInfo projInfo = mapper.GetProjectInfo(project); if (projInfo == null || projInfo.ProjectDirectory == null || !projInfo.IsSccBindable) { continue; // Some projects can't be managed } SvnItem projectDir = cache[projInfo.ProjectDirectory]; if (projectDir.WorkingCopy == slnItem.WorkingCopy) { // This is a 'normal' project, part of the solution and in the same working copy projectsToBeManaged.Add(project); continue; } bool markAsManaged; bool writeReference; if (projectDir.IsVersioned) { continue; // We don't have to add this one } if (projectDir.IsVersionable) { SvnItem parentDir = GetVersionedParent(projectDir); Debug.Assert(parentDir != null); DialogResult rslt = mb.Show(string.Format(CommandStrings.AddXToExistingWcY, projInfo.ProjectName, parentDir.FullPath), AnkhId.PlkProduct, MessageBoxButtons.YesNoCancel); switch (rslt) { case DialogResult.Cancel: return; case DialogResult.No: if (CheckoutWorkingCopyForProject(e, project, projInfo, solutionReposRoot, out markAsManaged, out writeReference)) { if (markAsManaged) { scc.SetProjectManaged(project, true); } if (writeReference) { scc.EnsureCheckOutReference(project); } continue; } break; case DialogResult.Yes: projectsToBeManaged.Add(project); AddPathToSubversion(e, projInfo.ProjectFile ?? projInfo.ProjectDirectory); continue; } } else { // We have to checkout (and create repository location) if (CheckoutWorkingCopyForProject(e, project, projInfo, solutionReposRoot, out markAsManaged, out writeReference)) { if (markAsManaged) { scc.SetProjectManaged(project, true); } if (writeReference) { scc.EnsureCheckOutReference(project); } continue; } } } } if (!AskSetManagedSelectionProjects(e, mapper, scc, projectsToBeManaged)) { return; } foreach (SccProject project in projectsToBeManaged) { if (!scc.IsProjectManaged(project)) { scc.SetProjectManaged(project, true); monitor.ScheduleSvnStatus(mapper.GetAllFilesOf(project)); // Update for 'New' status } } }
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; } } } }
public override void OnExecute(CommandEventArgs e) { SvnItem firstVersioned = null; ISvnStatusCache cache = e.GetService <ISvnStatusCache>(); switch (e.Command) { case AnkhCommand.ItemEditProperties: case AnkhCommand.ItemShowPropertyChanges: foreach (SvnItem i in e.Selection.GetSelectedSvnItems(false)) { if (i.IsVersioned) { firstVersioned = i; break; } } break; case AnkhCommand.ProjectEditProperties: // use project folder foreach (SccProject p in e.Selection.GetSelectedProjects(false)) { IProjectFileMapper pfm = e.GetService <IProjectFileMapper>(); if (pfm != null) { ISccProjectInfo info = pfm.GetProjectInfo(p); if (info != null && info.ProjectDirectory != null) { firstVersioned = cache[info.ProjectDirectory]; } if (firstVersioned != null) { break; } } } break; case AnkhCommand.SolutionEditProperties: // use solution folder IAnkhSolutionSettings solutionSettings = e.GetService <IAnkhSolutionSettings>(); if (solutionSettings != null) { firstVersioned = cache[solutionSettings.ProjectRoot]; } break; } if (firstVersioned == null) { return; // exceptional case } //using (SvnClient client = e.GetService<ISvnClientPool>().GetNoUIClient()) using (PropertyEditorDialog dialog = new PropertyEditorDialog(firstVersioned)) { dialog.Context = e.Context; SortedList <string, PropertyEditItem> editItems = new SortedList <string, PropertyEditItem>(); if (!e.GetService <IProgressRunner>().RunModal(CommandStrings.ReadingProperties, delegate(object Sender, ProgressWorkerArgs wa) { // Retrieve base properties wa.Client.PropertyList(new SvnPathTarget(firstVersioned.FullPath, SvnRevision.Base), delegate(object s, SvnPropertyListEventArgs la) { foreach (SvnPropertyValue pv in la.Properties) { PropertyEditItem ei; if (!editItems.TryGetValue(pv.Key, out ei)) { editItems.Add(pv.Key, ei = new PropertyEditItem(dialog.ListView, pv.Key)); } ei.BaseValue = pv; } }); // wa.Client.PropertyList(firstVersioned.FullPath, delegate(object s, SvnPropertyListEventArgs la) { foreach (SvnPropertyValue pv in la.Properties) { PropertyEditItem ei; if (!editItems.TryGetValue(pv.Key, out ei)) { editItems.Add(pv.Key, ei = new PropertyEditItem(dialog.ListView, pv.Key)); } ei.OriginalValue = ei.Value = pv; } }); }).Succeeded) { return; // Canceled } PropertyEditItem[] items = new PropertyEditItem[editItems.Count]; editItems.Values.CopyTo(items, 0); dialog.PropertyValues = items; if (dialog.ShowDialog(e.Context) == DialogResult.OK) { // Hack: Currently we save all properties, not only the in memory changed ones items = dialog.PropertyValues; bool hasChanges = false; foreach (PropertyEditItem i in items) { if (i.ShouldPersist) { hasChanges = true; break; } } if (!hasChanges) { return; } e.GetService <IProgressRunner>().RunModal(CommandStrings.StoringPropertyValues, delegate(object sender, ProgressWorkerArgs wa) { foreach (PropertyEditItem ei in items) { if (!ei.ShouldPersist) { continue; } if (ei.Value == null) { if (ei.OriginalValue != null) { wa.Client.DeleteProperty(firstVersioned.FullPath, ei.PropertyName); } } else if (!ei.Value.ValueEquals(ei.OriginalValue)) { if (ei.Value.StringValue != null) { wa.Client.SetProperty(firstVersioned.FullPath, ei.PropertyName, ei.Value.StringValue); } else { wa.Client.SetProperty(firstVersioned.FullPath, ei.PropertyName, ei.Value.RawValue); } } } }); } // if } }
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); }); } } }
public SvnSccContext(IAnkhServiceProvider context) : base(context) { _statusCache = GetService <ISvnStatusCache>(); }
public override void OnExecute(CommandEventArgs e) { List <SvnOrigin> selected = new List <SvnOrigin>(); ISvnStatusCache cache = e.GetService <ISvnStatusCache>(); switch (e.Command) { case AnkhCommand.Log: IAnkhDiffHandler diffHandler = e.GetService <IAnkhDiffHandler>(); List <SvnOrigin> items = new List <SvnOrigin>(); foreach (SvnItem i in e.Selection.GetSelectedSvnItems(false)) { Debug.Assert(i.IsVersioned); if (i.IsReplaced || i.IsAdded) { if (!i.HasCopyableHistory) { continue; } items.Add(new SvnOrigin(diffHandler.GetCopyOrigin(i), i.WorkingCopy.RepositoryRoot)); continue; } items.Add(new SvnOrigin(i)); } PerformLog(e.Context, items, null, null); break; case AnkhCommand.SolutionHistory: IAnkhSolutionSettings settings = e.GetService <IAnkhSolutionSettings>(); PerformLog(e.Context, new SvnOrigin[] { new SvnOrigin(cache[settings.ProjectRoot]) }, null, null); break; case AnkhCommand.ProjectHistory: IProjectFileMapper mapper = e.GetService <IProjectFileMapper>(); foreach (SccProject p in e.Selection.GetSelectedProjects(false)) { ISccProjectInfo info = mapper.GetProjectInfo(p); if (info != null) { selected.Add(new SvnOrigin(cache[info.ProjectDirectory])); } } PerformLog(e.Context, selected, null, null); break; case AnkhCommand.DocumentHistory: SvnItem docItem = e.Selection.ActiveDocumentSvnItem; Debug.Assert(docItem != null); PerformLog(e.Context, new SvnOrigin[] { new SvnOrigin(docItem) }, null, null); break; case AnkhCommand.ReposExplorerLog: foreach (ISvnRepositoryItem i in e.Selection.GetSelection <ISvnRepositoryItem>()) { if (i != null && i.Origin != null) { selected.Add(i.Origin); } } if (selected.Count > 0) { PerformLog(e.Context, selected, null, null); } break; case AnkhCommand.AnnotateShowLog: IAnnotateSection section = EnumTools.GetSingle(e.Selection.GetSelection <IAnnotateSection>()); if (section == null) { return; } PerformLog(e.Context, new SvnOrigin[] { section.Origin }, section.Revision, null); break; } }
public override void OnExecute(CommandEventArgs e) { IAnkhServiceEvents ci = e.GetService <IAnkhServiceEvents>(); if (ci != null) { ci.OnLastChanged(new LastChangedEventArgs(null, null)); } SvnRevision rev; bool allowUnversionedObstructions = false; bool updateExternals = true; bool setDepthInfinity = true; IAnkhSolutionSettings settings = e.GetService <IAnkhSolutionSettings>(); ISvnStatusCache cache = e.GetService <ISvnStatusCache>(); IProjectFileMapper mapper = e.GetService <IProjectFileMapper>(); Uri reposRoot = null; if (IsHeadCommand(e.Command) || e.DontPrompt) { rev = SvnRevision.Head; } else if (IsSolutionCommand(e.Command)) { SvnItem projectItem = settings.ProjectRootSvnItem; Debug.Assert(projectItem != null, "Has item"); using (UpdateDialog ud = new UpdateDialog()) { ud.ItemToUpdate = projectItem; ud.Revision = SvnRevision.Head; if (ud.ShowDialog(e.Context) != DialogResult.OK) { return; } rev = ud.Revision; allowUnversionedObstructions = ud.AllowUnversionedObstructions; updateExternals = ud.UpdateExternals; setDepthInfinity = ud.SetDepthInfinty; } } else if (IsFolderCommand(e.Command)) { SvnItem dirItem = EnumTools.GetFirst(e.Selection.GetSelectedSvnItems(false)); Debug.Assert(dirItem != null && dirItem.IsDirectory && dirItem.IsVersioned); using (UpdateDialog ud = new UpdateDialog()) { ud.Text = CommandStrings.UpdateFolder; ud.FolderLabelText = CommandStrings.UpdateFolderLabel; ud.ItemToUpdate = dirItem; ud.Revision = SvnRevision.Head; if (ud.ShowDialog(e.Context) != DialogResult.OK) { return; } rev = ud.Revision; allowUnversionedObstructions = ud.AllowUnversionedObstructions; updateExternals = ud.UpdateExternals; setDepthInfinity = ud.SetDepthInfinty; } } else { // We checked there was only a single repository to select a revision // from in OnUpdate, so we can suffice with only calculate the path SvnItem si = null; SvnOrigin origin = null; foreach (SccProject p in GetSelectedProjects(e)) { ISccProjectInfo pi = mapper.GetProjectInfo(p); if (pi == null || pi.ProjectDirectory == null) { continue; } SvnItem item = cache[pi.ProjectDirectory]; if (!item.IsVersioned) { continue; } if (si == null && origin == null) { si = item; origin = new SvnOrigin(item); reposRoot = item.WorkingCopy.RepositoryRoot; } else { si = null; string urlPath1 = origin.Uri.AbsolutePath; string urlPath2 = item.Uri.AbsolutePath; int i = 0; while (i < urlPath1.Length && i < urlPath2.Length && urlPath1[i] == urlPath2[i]) { i++; } while (i > 0 && urlPath1[i - 1] != '/') { i--; } origin = new SvnOrigin(new Uri(origin.Uri, urlPath1.Substring(0, i)), origin.RepositoryRoot); } } Debug.Assert(origin != null); using (UpdateDialog ud = new UpdateDialog()) { ud.Text = CommandStrings.UpdateProject; if (si != null) { ud.ItemToUpdate = si; } else { ud.SvnOrigin = origin; ud.SetMultiple(true); } ud.Revision = SvnRevision.Head; if (ud.ShowDialog(e.Context) != DialogResult.OK) { return; } rev = ud.Revision; allowUnversionedObstructions = ud.AllowUnversionedObstructions; updateExternals = ud.UpdateExternals; setDepthInfinity = ud.SetDepthInfinty; } } Dictionary <string, SvnItem> itemsToUpdate = new Dictionary <string, SvnItem>(StringComparer.OrdinalIgnoreCase); SortedList <string, UpdateGroup> groups = new SortedList <string, UpdateGroup>(StringComparer.OrdinalIgnoreCase); // Get a list of all documents below the specified paths that are open in editors inside VS HybridCollection <string> lockPaths = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); IAnkhOpenDocumentTracker documentTracker = e.GetService <IAnkhOpenDocumentTracker>(); foreach (SvnItem item in GetAllUpdateRoots(e)) { // GetAllUpdateRoots can (and probably will) return duplicates! if (itemsToUpdate.ContainsKey(item.FullPath) || !item.IsVersioned) { continue; } SvnWorkingCopy wc = item.WorkingCopy; if (!IsHeadCommand(e.Command) && reposRoot != null) { // Specific revisions are only valid on a single repository! if (wc != null && wc.RepositoryRoot != reposRoot) { continue; } } UpdateGroup group; if (!groups.TryGetValue(wc.FullPath, out group)) { group = new UpdateGroup(wc.FullPath); groups.Add(wc.FullPath, group); } group.Nodes.Add(item.FullPath); itemsToUpdate.Add(item.FullPath, item); foreach (string file in documentTracker.GetDocumentsBelow(item.FullPath)) { if (!lockPaths.Contains(file)) { lockPaths.Add(file); } } } documentTracker.SaveDocuments(lockPaths); // Make sure all files are saved before updating/merging! using (DocumentLock lck = documentTracker.LockDocuments(lockPaths, DocumentLockType.NoReload)) using (lck.MonitorChangesForReload()) { SvnUpdateResult updateResult = null; ProgressRunnerArgs pa = new ProgressRunnerArgs(); pa.CreateLog = true; string title; if (IsSolutionCommand(e.Command)) { title = CommandStrings.UpdatingSolution; } else if (IsFolderCommand(e.Command)) { title = CommandStrings.UpdatingFolder; } else { title = CommandStrings.UpdatingProject; } e.GetService <IProgressRunner>().RunModal(title, pa, delegate(object sender, ProgressWorkerArgs a) { PerformUpdate(e, a, rev, allowUnversionedObstructions, updateExternals, setDepthInfinity, groups.Values, out updateResult); }); if (ci != null && updateResult != null && IsSolutionCommand(e.Command)) { ci.OnLastChanged(new LastChangedEventArgs(CommandStrings.UpdatedToTitle, updateResult.Revision.ToString())); } } }
public override void OnUpdate(CommandUpdateEventArgs e) { if (e.State.SolutionBuilding || e.State.Debugging || e.State.SolutionOpening) { e.Enabled = false; return; } if (IsSolutionCommand(e.Command)) { IAnkhSolutionSettings settings = e.GetService <IAnkhSolutionSettings>(); if (settings == null || string.IsNullOrEmpty(settings.ProjectRoot)) { e.Enabled = false; return; } if (!settings.ProjectRootSvnItem.IsVersioned) { e.Enabled = false; } } else if (IsFolderCommand(e.Command)) { bool forHead = IsHeadCommand(e.Command); bool foundOne = false; Uri root = null; foreach (SvnItem dir in e.Selection.GetSelectedSvnItems(false)) { if (!dir.IsDirectory || !dir.IsVersioned) { e.Enabled = false; break; } foundOne = true; if (!forHead) { Uri reposRoot = dir.WorkingCopy.RepositoryRoot; if (root != reposRoot) { if (root == null) { reposRoot = root; } else { e.Enabled = false; break; } } } } if (!foundOne) { e.Enabled = false; } } else { IProjectFileMapper pfm = null; ISvnStatusCache fsc = null; Uri rootUrl = null; foreach (SccProject p in GetSelectedProjects(e)) { if (pfm == null) { pfm = e.GetService <IProjectFileMapper>(); } ISccProjectInfo pi = pfm.GetProjectInfo(p); if (pi == null || pi.ProjectDirectory == null) { continue; } if (fsc == null) { fsc = e.GetService <ISvnStatusCache>(); } SvnItem rootItem = fsc[pi.ProjectDirectory]; if (!rootItem.IsVersioned) { continue; } if (IsHeadCommand(e.Command)) { return; // Ok, we can update } if (rootUrl == null) { rootUrl = rootItem.WorkingCopy.RepositoryRoot; } else if (rootUrl != rootItem.WorkingCopy.RepositoryRoot) { // Multiple repositories selected; can't choose uniform version e.Enabled = false; return; } } if (rootUrl == null) { e.Enabled = false; } } }
void InnerRefresh() { using (BatchStartedEventArgs br = BatchRefresh()) { HybridCollection <string> mapped = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); ISvnStatusCache cache = Cache; foreach (string file in Mapper.GetAllFilesOfAllProjects()) { br.Tick(); _extraFiles.Remove(file); // If we find it here; it is no longer 'extra'! SvnItem item = cache[file]; if (item == null) { continue; } PendingChange pc = UpdatePendingChange(item); if (pc != null) { mapped.Add(pc.FullPath); } } foreach (string file in new List <string>(_extraFiles)) { br.Tick(); SvnItem item = cache[file]; if (item == null) { _extraFiles.Remove(file); continue; } PendingChange pc = UpdatePendingChange(item); if (pc != null) { mapped.Add(pc.FullPath); } else { _extraFiles.Remove(file); } } for (int i = 0; i < _pendingChanges.Count; i++) { br.Tick(); PendingChange pc = _pendingChanges[i]; if (mapped.Contains(pc.FullPath)) { continue; } _pendingChanges.RemoveAt(i--); } } }