diff --git a/src/App.xaml.cs b/src/App.xaml.cs index 1528ae9b..845bef46 100644 --- a/src/App.xaml.cs +++ b/src/App.xaml.cs @@ -8,6 +8,7 @@ namespace SourceGit { /// 程序入口. /// public partial class App : Application { + public static event Action ExceptionRaised; /// /// 读取本地化字串 @@ -21,6 +22,15 @@ namespace SourceGit { return string.Format(data, args); } + /// + /// 触发错误 + /// + /// 错误上下文 + /// 错误内容 + public static void Exception(string ctx, string detail) { + ExceptionRaised?.Invoke(ctx, detail); + } + /// /// 启动. /// diff --git a/src/Commands/Command.cs b/src/Commands/Command.cs index 96f18c3f..aac9bdff 100644 --- a/src/Commands/Command.cs +++ b/src/Commands/Command.cs @@ -178,7 +178,7 @@ namespace SourceGit.Commands { /// /// public virtual void OnException(string message) { - Models.Exception.Raise(message); + App.Exception(Cwd, message); } } } diff --git a/src/Models/Exception.cs b/src/Models/Exception.cs deleted file mode 100644 index 99d5b92b..00000000 --- a/src/Models/Exception.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace SourceGit.Models { - - /// - /// 错误通知 - /// - public static class Exception { - public static Action Handler { get; set; } - - public static void Raise(string error) { - Handler?.Invoke(error); - } - } -} diff --git a/src/Views/Clone.xaml.cs b/src/Views/Clone.xaml.cs index afce1aed..f5d6b81d 100644 --- a/src/Views/Clone.xaml.cs +++ b/src/Views/Clone.xaml.cs @@ -63,7 +63,7 @@ namespace SourceGit.Views { } if (!Directory.Exists(path)) { - Models.Exception.Raise($"Folder {path} not found!"); + Dispatcher.Invoke(() => txtError.Text = $"Folder {path} not found!"); return false; } diff --git a/src/Views/Launcher.xaml b/src/Views/Launcher.xaml index d3fef695..801e8fc2 100644 --- a/src/Views/Launcher.xaml +++ b/src/Views/Launcher.xaml @@ -70,11 +70,5 @@ - - - diff --git a/src/Views/Popups/AddSubTree.xaml.cs b/src/Views/Popups/AddSubTree.xaml.cs index 0086a0a2..c68f114b 100644 --- a/src/Views/Popups/AddSubTree.xaml.cs +++ b/src/Views/Popups/AddSubTree.xaml.cs @@ -34,7 +34,7 @@ namespace SourceGit.Views.Popups { var squash = chkSquash.IsChecked == true; if (repo.SubTrees.FindIndex(x => x.Prefix == Prefix) >= 0) { - Models.Exception.Raise($"Subtree add failed. Prefix({Prefix}) already exists!"); + App.Exception(repo.Path, $"Subtree add failed. Prefix({Prefix}) already exists!"); return null; } diff --git a/src/Views/Popups/FastForwardWithoutCheckout.xaml.cs b/src/Views/Popups/FastForwardWithoutCheckout.xaml.cs index 37efa5b5..b561b1a9 100644 --- a/src/Views/Popups/FastForwardWithoutCheckout.xaml.cs +++ b/src/Views/Popups/FastForwardWithoutCheckout.xaml.cs @@ -14,7 +14,7 @@ namespace SourceGit.Views.Popups { public FastForwardWithoutCheckout(string repo, string branch, string upstream) { int idx = upstream.IndexOf('/'); if (idx < 0 || idx == upstream.Length - 1) { - Models.Exception.Raise($"Invalid upstream: {upstream}"); + App.Exception(repo, $"Invalid upstream: {upstream}"); return; } diff --git a/src/Views/Widgets/Dashboard.xaml b/src/Views/Widgets/Dashboard.xaml index 6b44bd6f..03dbfb61 100644 --- a/src/Views/Widgets/Dashboard.xaml +++ b/src/Views/Widgets/Dashboard.xaml @@ -1,4 +1,5 @@ + + + diff --git a/src/Views/Widgets/Dashboard.xaml.cs b/src/Views/Widgets/Dashboard.xaml.cs index 9bb7764a..30ff38ca 100644 --- a/src/Views/Widgets/Dashboard.xaml.cs +++ b/src/Views/Widgets/Dashboard.xaml.cs @@ -54,6 +54,8 @@ namespace SourceGit.Views.Widgets { } } + public string ExceptionContext => repo.Path; + public Dashboard(Models.Repository repo) { this.repo = repo; @@ -402,7 +404,7 @@ namespace SourceGit.Views.Widgets { private void OpenInTerminal(object sender, RoutedEventArgs e) { var bash = Path.Combine(Models.Preference.Instance.Git.Path, "..", "bash.exe"); if (!File.Exists(bash)) { - Models.Exception.Raise(App.Text("MissingBash")); + App.Exception(repo.Path, App.Text("MissingBash")); return; } @@ -428,7 +430,7 @@ namespace SourceGit.Views.Widgets { private void OpenFetch(object sender, RoutedEventArgs e) { if (repo.Remotes.Count == 0) { - Models.Exception.Raise("No remotes added to this repository!!!"); + App.Exception(repo.Path, "No remotes added to this repository!!!"); return; } @@ -438,7 +440,7 @@ namespace SourceGit.Views.Widgets { private void OpenPull(object sender, RoutedEventArgs e) { if (repo.Remotes.Count == 0) { - Models.Exception.Raise("No remotes added to this repository!!!"); + App.Exception(repo.Path, "No remotes added to this repository!!!"); return; } @@ -448,7 +450,7 @@ namespace SourceGit.Views.Widgets { private void OpenPush(object sender, RoutedEventArgs e) { if (repo.Remotes.Count == 0) { - Models.Exception.Raise("No remotes added to this repository!!!"); + App.Exception(repo.Path, "No remotes added to this repository!!!"); return; } @@ -576,7 +578,7 @@ namespace SourceGit.Views.Widgets { if (current != null) { new Popups.CreateBranch(repo, current).Show(); } else { - Models.Exception.Raise(App.Text("CreateBranch.Idle")); + App.Exception(repo.Path, App.Text("CreateBranch.Idle")); } e.Handled = true; } diff --git a/src/Views/Widgets/DiffViewer.xaml.cs b/src/Views/Widgets/DiffViewer.xaml.cs index 755509e4..4a856eea 100644 --- a/src/Views/Widgets/DiffViewer.xaml.cs +++ b/src/Views/Widgets/DiffViewer.xaml.cs @@ -604,7 +604,7 @@ namespace SourceGit.Views.Widgets { var merger = Models.MergeTool.Supported.Find(x => x.Type == mergeType); if (merger == null || merger.Type == 0 || !System.IO.File.Exists(mergeExe)) { - Models.Exception.Raise("Invalid merge tool in preference setting!"); + App.Exception(repo, "Invalid merge tool in preference setting!"); return; } diff --git a/src/Views/Widgets/Exceptions.xaml.cs b/src/Views/Widgets/Exceptions.xaml.cs index ac4a8fd9..f68583e5 100644 --- a/src/Views/Widgets/Exceptions.xaml.cs +++ b/src/Views/Widgets/Exceptions.xaml.cs @@ -10,9 +10,31 @@ namespace SourceGit.Views.Widgets { public partial class Exceptions : UserControl { public ObservableCollection Messages { get; set; } + /// + /// 用于判断异常是否属于自己的上下文属性 + /// + public static readonly DependencyProperty ContextProperty = DependencyProperty.Register( + "Context", + typeof(string), + typeof(Exceptions), + new PropertyMetadata(null)); + + /// + /// 上下文 + /// + public string Context { + get { return (string)GetValue(ContextProperty); } + set { SetValue(ContextProperty, value); } + } + public Exceptions() { + App.ExceptionRaised += (ctx, detail) => { + Dispatcher.Invoke(() => { + if (ctx == Context) Messages.Add(detail); + }); + }; + Messages = new ObservableCollection(); - Models.Exception.Handler = e => Dispatcher.Invoke(() => Messages.Add(e)); InitializeComponent(); } diff --git a/src/Views/Widgets/Histories.xaml.cs b/src/Views/Widgets/Histories.xaml.cs index 0eb0b8c7..853460bd 100644 --- a/src/Views/Widgets/Histories.xaml.cs +++ b/src/Views/Widgets/Histories.xaml.cs @@ -303,7 +303,7 @@ namespace SourceGit.Views.Widgets { } } - Models.Exception.Raise("Can NOT found parent of HEAD!"); + App.Exception(repo.Path, "Can NOT found parent of HEAD!"); e.Handled = true; }; menu.Items.Add(squash); diff --git a/src/Views/Widgets/Welcome.xaml b/src/Views/Widgets/Welcome.xaml index 9c0b3949..24c916de 100644 --- a/src/Views/Widgets/Welcome.xaml +++ b/src/Views/Widgets/Welcome.xaml @@ -1,4 +1,5 @@ - + + + + diff --git a/src/Views/Widgets/Welcome.xaml.cs b/src/Views/Widgets/Welcome.xaml.cs index fcc3de42..63062883 100644 --- a/src/Views/Widgets/Welcome.xaml.cs +++ b/src/Views/Widgets/Welcome.xaml.cs @@ -14,8 +14,14 @@ namespace SourceGit.Views.Widgets { /// 新标签页 /// public partial class Welcome : UserControl { + public string ExceptionContext { + get; + set; + } public Welcome() { + ExceptionContext = Guid.NewGuid().ToString(); + InitializeComponent(); UpdateVisibles(); @@ -34,7 +40,7 @@ namespace SourceGit.Views.Widgets { if (MakeSureReady()) { var bash = Path.Combine(Models.Preference.Instance.Git.Path, "..", "bash.exe"); if (!File.Exists(bash)) { - Models.Exception.Raise(App.Text("MissingBash")); + App.Exception(ExceptionContext, App.Text("MissingBash")); return; } @@ -175,7 +181,7 @@ namespace SourceGit.Views.Widgets { var bash = Path.Combine(Models.Preference.Instance.Git.Path, "..", "bash.exe"); if (!File.Exists(bash)) { - Models.Exception.Raise(App.Text("MissingBash")); + App.Exception(ExceptionContext, App.Text("MissingBash")); return; } @@ -245,7 +251,7 @@ namespace SourceGit.Views.Widgets { private bool MakeSureReady() { if (!Models.Preference.Instance.IsReady) { - Models.Exception.Raise(App.Text("NotConfigured")); + App.Exception(ExceptionContext, App.Text("NotConfigured")); return false; } return true; @@ -255,7 +261,7 @@ namespace SourceGit.Views.Widgets { if (!MakeSureReady()) return; if (!Directory.Exists(path)) { - Models.Exception.Raise(App.Text("PathNotFound", path)); + App.Exception(ExceptionContext, App.Text("PathNotFound", path)); return; } diff --git a/src/Views/Widgets/WorkingCopy.xaml.cs b/src/Views/Widgets/WorkingCopy.xaml.cs index b95f210b..95406fd4 100644 --- a/src/Views/Widgets/WorkingCopy.xaml.cs +++ b/src/Views/Widgets/WorkingCopy.xaml.cs @@ -220,7 +220,7 @@ namespace SourceGit.Views.Widgets { var merger = Models.MergeTool.Supported.Find(x => x.Type == mergeType); if (merger == null || merger.Type == 0 || !File.Exists(mergeExe)) { - Models.Exception.Raise("Invalid merge tool in preference setting!"); + App.Exception(repo.Path, "Invalid merge tool in preference setting!"); return; } @@ -289,7 +289,7 @@ namespace SourceGit.Views.Widgets { private void StartAmend(object sender, RoutedEventArgs e) { var commits = new Commands.Commits(repo.Path, "-n 1", false).Result(); if (commits.Count == 0) { - Models.Exception.Raise("No commits to amend!"); + App.Exception(repo.Path, "No commits to amend!"); chkAmend.IsChecked = false; return; } @@ -316,12 +316,12 @@ namespace SourceGit.Views.Widgets { var changes = await Task.Run(() => new Commands.LocalChanges(repo.Path).Result()); var conflict = changes.Find(x => x.IsConflit); if (conflict != null) { - Models.Exception.Raise("You have unsolved conflicts in your working copy!"); + App.Exception(repo.Path, "You have unsolved conflicts in your working copy!"); return; } if (stagedContainer.Changes.Count == 0) { - Models.Exception.Raise("No files added to commit!"); + App.Exception(repo.Path, "No files added to commit!"); return; } @@ -351,12 +351,12 @@ namespace SourceGit.Views.Widgets { var changes = await Task.Run(() => new Commands.LocalChanges(repo.Path).Result()); var conflict = changes.Find(x => x.IsConflit); if (conflict != null) { - Models.Exception.Raise("You have unsolved conflicts in your working copy!"); + App.Exception(repo.Path, "You have unsolved conflicts in your working copy!"); return; } if (stagedContainer.Changes.Count == 0) { - Models.Exception.Raise("No files added to commit!"); + App.Exception(repo.Path, "No files added to commit!"); return; }