using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Navigation; namespace SourceGit.Views.Widgets { /// /// 提交详情 /// public partial class CommitDetail : UserControl { private string repo = null; private Models.Commit commit = null; private Commands.Context cancelToken = new Commands.Context(); public CommitDetail() { InitializeComponent(); Unloaded += (o, e) => { changeList.ItemsSource = new List(); changeContainer.CleanUp(); revisionFiles.Cleanup(); }; } public void SetData(string repo, Models.Commit commit) { cancelToken.IsCancelRequested = true; cancelToken = new Commands.Context(); this.repo = repo; this.commit = commit; revisionFiles.SetData(repo, commit.SHA, cancelToken); UpdateInformation(commit); UpdateChanges(); } #region DATA private void UpdateInformation(Models.Commit commit) { txtSHA.Text = commit.SHA; txtMessage.Text = (commit.Subject + "\n\n" + commit.Message.Trim()).Trim(); avatarAuthor.Email = commit.Author.Email; avatarAuthor.FallbackLabel = commit.Author.Name; txtAuthorName.Text = commit.Author.Name; txtAuthorEmail.Text = commit.Author.Email; txtAuthorTime.Text = commit.Author.Time; avatarCommitter.Email = commit.Committer.Email; avatarCommitter.FallbackLabel = commit.Committer.Name; txtCommitterName.Text = commit.Committer.Name; txtCommitterEmail.Text = commit.Committer.Email; txtCommitterTime.Text = commit.Committer.Time; if (commit.Committer.Email == commit.Author.Email && commit.Committer.Time == commit.Author.Time) { avatarCommitter.Visibility = Visibility.Hidden; committerInfoPanel.Visibility = Visibility.Hidden; } else { avatarCommitter.Visibility = Visibility.Visible; committerInfoPanel.Visibility = Visibility.Visible; } if (commit.Parents.Count == 0) { rowParents.Height = new GridLength(0); } else { rowParents.Height = GridLength.Auto; var shortPIDs = new List(); foreach (var p in commit.Parents) shortPIDs.Add(p.Substring(0, 10)); listParents.ItemsSource = shortPIDs; } if (!commit.HasDecorators) { rowRefs.Height = new GridLength(0); } else { rowRefs.Height = GridLength.Auto; listRefs.ItemsSource = commit.Decorators; } } private void UpdateChanges() { var cmd = new Commands.CommitChanges(repo, commit.SHA) { Ctx = cancelToken }; Task.Run(() => { var changes = cmd.Result(); if (cmd.Ctx.IsCancelRequested) return; Dispatcher.Invoke(() => { changeList.ItemsSource = changes; changeContainer.SetData(repo, new List() { commit }, changes); }); }); } #endregion #region EVENTS private void OnNavigateParent(object sender, RequestNavigateEventArgs e) { Models.Watcher.Get(repo)?.NavigateTo(e.Uri.OriginalString); } private void OnChangeListMouseDoubleClick(object sender, MouseButtonEventArgs e) { var row = sender as DataGridRow; if (row == null) return; var change = row.DataContext as Models.Change; if (change == null) return; body.SelectedIndex = 1; changeContainer.Select(change); e.Handled = true; } private void OnChangeListContextMenuOpening(object sender, ContextMenuEventArgs e) { var row = sender as DataGridRow; if (row == null) return; var change = row.DataContext as Models.Change; if (change == null) return; var menu = new ContextMenu(); if (change.Index != Models.Change.Status.Deleted) { var history = new MenuItem(); history.Header = App.Text("FileHistory"); history.IsEnabled = change.Index != Models.Change.Status.Deleted; history.Click += (o, ev) => { var viewer = new Views.Histories(repo, change.Path); viewer.Show(); ev.Handled = true; }; var blame = new MenuItem(); blame.Header = App.Text("Blame"); blame.IsEnabled = change.Index != Models.Change.Status.Deleted; blame.Click += (obj, ev) => { var viewer = new Blame(repo, change.Path, commit.SHA); viewer.Show(); ev.Handled = true; }; var explore = new MenuItem(); explore.Header = App.Text("RevealFile"); explore.IsEnabled = change.Index != Models.Change.Status.Deleted; explore.Click += (o, ev) => { var full = Path.GetFullPath(repo + "\\" + change.Path); Process.Start("explorer", $"/select,{full}"); ev.Handled = true; }; menu.Items.Add(history); menu.Items.Add(blame); menu.Items.Add(explore); } var copyPath = new MenuItem(); copyPath.Header = App.Text("CopyPath"); copyPath.Click += (obj, ev) => { Clipboard.SetText(change.Path); ev.Handled = true; }; menu.Items.Add(copyPath); menu.IsOpen = true; e.Handled = true; } #endregion } }