Exemple #1
0
        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);
        }
Exemple #2
0
        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();
        }
Exemple #3
0
        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));
        }
Exemple #4
0
        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, "../");
                }
            }
        }
Exemple #6
0
        /// <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);
                            }
                        }
                    }
        }
Exemple #7
0
        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));
        }
Exemple #8
0
            public int DirectoryChanged(string pszDirectory)
            {
                ISvnStatusCache fsc = GetService <ISvnStatusCache>();

                if (fsc != null)
                {
                    fsc.MarkDirtyRecursive(SvnTools.GetNormalizedFullPath(pszDirectory));
                }

                return(VSErr.S_OK);
            }
Exemple #9
0
        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];
     }
 }
Exemple #11
0
        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;
        }
Exemple #12
0
        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;
        }
Exemple #13
0
        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;
            }
        }
Exemple #14
0
        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();
        }
Exemple #15
0
        /// <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));
        }
Exemple #16
0
        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;
        }
Exemple #17
0
        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);
                    }
                }
            }
        }
Exemple #19
0
        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;
            }
        }
Exemple #20
0
        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);
                            });
                        }
                    }
                }
        }
Exemple #21
0
        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;
        }
Exemple #22
0
        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;
                    }
                }
            }
        }
Exemple #24
0
        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
            }
        }
Exemple #25
0
        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);
                    });
                }
            }
        }
Exemple #26
0
 public SvnSccContext(IAnkhServiceProvider context)
     : base(context)
 {
     _statusCache = GetService <ISvnStatusCache>();
 }
Exemple #27
0
        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--);
                }
            }
        }