diff --git a/src/App.xaml.cs b/src/App.xaml.cs index da11692a..ee2668cf 100644 --- a/src/App.xaml.cs +++ b/src/App.xaml.cs @@ -90,6 +90,14 @@ namespace SourceGit { Current.MainWindow.Show(); } + /// + /// Open repository. + /// + /// + public static void Open(Git.Repository repo) { + (Current.MainWindow as UI.Launcher).Open(repo); + } + /// /// Deactivated event. /// diff --git a/src/Git/Repository.cs b/src/Git/Repository.cs index 62f52291..742ccdbc 100644 --- a/src/Git/Repository.cs +++ b/src/Git/Repository.cs @@ -15,7 +15,6 @@ namespace SourceGit.Git { public class Repository { #region HOOKS - public static Action OnOpen = null; [XmlIgnore] public Action OnNavigateCommit = null; [XmlIgnore] public Action OnWorkingCopyChanged = null; [XmlIgnore] public Action OnTagChanged = null; @@ -23,6 +22,7 @@ namespace SourceGit.Git { [XmlIgnore] public Action OnBranchChanged = null; [XmlIgnore] public Action OnCommitsChanged = null; [XmlIgnore] public Action OnSubmoduleChanged = null; + [XmlIgnore] public Action OnClosing = null; #endregion #region PROPERTIES_SAVED @@ -294,14 +294,14 @@ namespace SourceGit.Git { featurePrefix = GetConfig("gitflow.prefix.feature"); releasePrefix = GetConfig("gitflow.prefix.release"); hotfixPrefix = GetConfig("gitflow.prefix.hotfix"); - - OnOpen?.Invoke(this); } /// /// Close repository. /// public void Close() { + OnClosing?.Invoke(); + OnBranchChanged = null; OnCommitsChanged = null; OnTagChanged = null; @@ -309,6 +309,7 @@ namespace SourceGit.Git { OnWorkingCopyChanged = null; OnNavigateCommit = null; OnSubmoduleChanged = null; + OnClosing = null; cachedBranches.Clear(); cachedRemotes.Clear(); diff --git a/src/Resources/Icons.xaml b/src/Resources/Icons.xaml index 88ea9be3..a13c55af 100644 --- a/src/Resources/Icons.xaml +++ b/src/Resources/Icons.xaml @@ -4,6 +4,7 @@ M557.696 545.347L789.873 402.66c23.998-14.999 31.297-46.496 16.398-70.493-14.798-23.798-45.995-31.197-69.993-16.699L506.501 456.555 277.123 315.37c-24.098-14.798-55.595-7.3-70.493 16.799-14.799 24.097-7.3 55.594 16.798 70.493l231.778 142.586V819.12c0 28.297 22.897 51.195 51.195 51.195 28.297 0 51.195-22.898 51.195-51.195V545.347h0.1zM506.5 0l443.356 255.975v511.95L506.501 1023.9 63.144 767.925v-511.95L506.5 0z M169.984 470.016l0 84.010667 86.016 0 0-84.010667-86.016 0zM86.016 598.016l0-171.989333 852.010667 0 0 171.989333-852.010667 0zM256 297.984l0-84.010667-86.016 0 0 84.010667 86.016 0zM86.016 169.984l852.010667 0 0 171.989333-852.010667 0 0-171.989333zM169.984 726.016l0 84.010667 86.016 0 0-84.010667-86.016 0zM86.016 854.016l0-171.989333 852.010667 0 0 171.989333-852.010667 0z M 841.758 299.375 c 0 165.25 -134 299.375 -299.375 299.375 S 243.009 464.75 243.009 299.375 S 377.009 0 542.383 0 c 165.25 0 299.375 134 299.375 299.375 Z m 0 0 M 789.383 612.75 c -69.75 55.125 -156.25 85.625 -247.125 85.625 c -91.875 0 -179.25 -31.25 -249.25 -87.375 C 108.384 678.875 25.8838 915.75 25.8838 1024 h 1027.75 c 0 -107.25 -83.125 -342.5 -264.25 -411.25 Z m 0 0 + M1024 590.432 512 193.024 0 590.432 0 428.416 512 30.976 1024 428.416ZM896 576 896 960 640 960 640 704 384 704 384 960 128 960 128 576 512 288Z M753.613 996.727L269.38 511.505 754.602 27.272z M270.387 27.273L754.62 512.495 269.398 996.728z diff --git a/src/UI/Dashboard.xaml b/src/UI/Dashboard.xaml index 6b474d1d..b3d909b8 100644 --- a/src/UI/Dashboard.xaml +++ b/src/UI/Dashboard.xaml @@ -7,8 +7,7 @@ xmlns:local="clr-namespace:SourceGit.UI" xmlns:converters="clr-namespace:SourceGit.Converters" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" - Unloaded="Cleanup"> + d:DesignHeight="450" d:DesignWidth="800"> diff --git a/src/UI/Dashboard.xaml.cs b/src/UI/Dashboard.xaml.cs index b10c2798..3d75dd8e 100644 --- a/src/UI/Dashboard.xaml.cs +++ b/src/UI/Dashboard.xaml.cs @@ -50,7 +50,8 @@ namespace SourceGit.UI { /// Constructor. /// /// Opened repository. - public Dashboard(Git.Repository opened) { + public Dashboard(Git.Repository opened) { + opened.OnClosing = Cleanup; opened.OnWorkingCopyChanged = UpdateLocalChanges; opened.OnTagChanged = UpdateTags; opened.OnStashChanged = UpdateStashes; @@ -78,6 +79,22 @@ namespace SourceGit.UI { UpdateSubmodules(); } + /// + /// Cleanup + /// + public void Cleanup() { + repo = null; + localBranchTree.ItemsSource = null; + remoteBranchTree.ItemsSource = null; + tagList.ItemsSource = null; + cachedLocalBranches.Clear(); + cachedRemotes.Clear(); + + histories.Cleanup(); + commits.Cleanup(); + stashes.Cleanup(); + } + #region DATA_UPDATE private void UpdateHistories() { Dispatcher.Invoke(() => { @@ -287,14 +304,6 @@ namespace SourceGit.UI { }); }); } - - private void Cleanup(object sender, RoutedEventArgs e) { - localBranchTree.ItemsSource = null; - remoteBranchTree.ItemsSource = null; - tagList.ItemsSource = null; - cachedLocalBranches.Clear(); - cachedRemotes.Clear(); - } #endregion #region TOOLBAR @@ -1021,7 +1030,7 @@ namespace SourceGit.UI { sub.Name = Path.GetFileName(path); sub.Parent = repo; - if (!sub.BringUpTab()) sub.Open(); + App.Open(sub); } #endregion diff --git a/src/UI/DiffViewer.xaml.cs b/src/UI/DiffViewer.xaml.cs index 274d68e4..861da646 100644 --- a/src/UI/DiffViewer.xaml.cs +++ b/src/UI/DiffViewer.xaml.cs @@ -71,6 +71,9 @@ namespace SourceGit.UI { /// public void Reset() { mask.Visibility = Visibility.Visible; + lineChanges = null; + foreach (var editor in editors) editorContainer.Children.Remove(editor); + editors.Clear(); } /// diff --git a/src/UI/Histories.xaml b/src/UI/Histories.xaml index e37e4bd1..552f0bcd 100644 --- a/src/UI/Histories.xaml +++ b/src/UI/Histories.xaml @@ -10,8 +10,7 @@ xmlns:sourcegit="clr-namespace:SourceGit" xmlns:converters="clr-namespace:SourceGit.Converters" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" - Unloaded="Cleanup"> + d:DesignHeight="450" d:DesignWidth="800"> diff --git a/src/UI/Histories.xaml.cs b/src/UI/Histories.xaml.cs index 696dc91c..46856dc9 100644 --- a/src/UI/Histories.xaml.cs +++ b/src/UI/Histories.xaml.cs @@ -78,6 +78,15 @@ namespace SourceGit.UI { } } + /// + /// Cleanup + /// + public void Cleanup() { + commitGraph.Children.Clear(); + commitList.ItemsSource = null; + cachedCommits.Clear(); + } + #region DATA public void SetCommits(List commits) { cachedCommits = commits; @@ -184,12 +193,6 @@ namespace SourceGit.UI { SetLoadingEnabled(false); }); } - - private void Cleanup(object sender, RoutedEventArgs e) { - commitGraph.Children.Clear(); - commitList.ItemsSource = null; - cachedCommits.Clear(); - } #endregion #region SEARCH_BAR @@ -516,7 +519,7 @@ namespace SourceGit.UI { // Reset var reset = new MenuItem(); - reset.Header = $"Reset '{current.Name}' To Here"; + reset.Header = $"Reset '{current.Name}' to Here"; reset.Visibility = commit.IsHEAD ? Visibility.Collapsed : Visibility.Visible; reset.Click += (o, e) => { Reset.Show(Repo, commit); @@ -526,7 +529,7 @@ namespace SourceGit.UI { // Rebase or interactive rebase var rebase = new MenuItem(); - rebase.Header = commit.IsMerged ? $"Interactive Rebase '{current.Name}' From Here" : $"Rebase '{current.Name}' To Here"; + rebase.Header = commit.IsMerged ? $"Interactive Rebase '{current.Name}' from Here" : $"Rebase '{current.Name}' to Here"; rebase.Visibility = commit.IsHEAD ? Visibility.Collapsed : Visibility.Visible; rebase.Click += (o, e) => { if (commit.IsMerged) { @@ -587,7 +590,7 @@ namespace SourceGit.UI { // Save as patch var patch = new MenuItem(); - patch.Header = "Save As Patch"; + patch.Header = "Save as Patch"; patch.Click += (o, e) => { FolderDailog.Open("Save patch to ...", saveTo => { Repo.RunCommand($"format-patch {commit.SHA} -1 -o \"{saveTo}\"", null); diff --git a/src/UI/Launcher.xaml b/src/UI/Launcher.xaml index ec7dd5e3..a5b98f74 100644 --- a/src/UI/Launcher.xaml +++ b/src/UI/Launcher.xaml @@ -110,7 +110,7 @@ Data="M 0,0 L 0,6 6,6 C 6,6 0,6 0,0 Z" Fill="Transparent"/> - + - - @@ -139,16 +132,8 @@ - - + - - - - - - - @@ -166,6 +151,7 @@ + diff --git a/src/UI/Launcher.xaml.cs b/src/UI/Launcher.xaml.cs index 1ee65d03..d22e49a5 100644 --- a/src/UI/Launcher.xaml.cs +++ b/src/UI/Launcher.xaml.cs @@ -36,26 +36,9 @@ namespace SourceGit.UI { /// Constructor /// public Launcher() { - Git.Repository.OnOpen = repo => { - Dispatcher.Invoke(() => { - var page = new Dashboard(repo); - var tab = new Tab() { - Title = repo.Parent == null ? repo.Name : $"{repo.Parent.Name} : {repo.Name}", - Tooltip = repo.Path, - AllowDragDrop = true, - Repo = repo, - Page = page, - }; - - repo.SetPopupManager(page.popupManager); - Tabs.Add(tab); - openedTabs.SelectedItem = tab; - }); - }; - Tabs.Add(new Tab() { - Title = "SOURCE GIT", - Tooltip = "Welcome Page", + Title = "HOME", + Tooltip = "Repositories Manager", AllowDragDrop = false, Page = new Manager(), }); @@ -64,21 +47,87 @@ namespace SourceGit.UI { openedTabs.SelectedItem = Tabs[0]; } + /// + /// Open repository + /// + /// + public void Open(Git.Repository repo) { + for (int i = 1; i < Tabs.Count; i++) { + var opened = Tabs[i]; + if (opened.Repo.Path == repo.Path) { + openedTabs.SelectedItem = opened; + return; + } + } + + repo.Open(); + + var page = new Dashboard(repo); + var tab = new Tab() { + Title = repo.Parent == null ? repo.Name : $"{repo.Parent.Name} : {repo.Name}", + Tooltip = repo.Path, + AllowDragDrop = true, + Repo = repo, + Page = page, + }; + + repo.SetPopupManager(page.popupManager); + Tabs.Add(tab); + openedTabs.SelectedItem = tab; + } + #region LAYOUT_CONTENT /// - /// Close repository tab. + /// Context menu for tab items. /// /// /// - private void CloseRepo(object sender, RoutedEventArgs e) { - var tab = (sender as Button).DataContext as Tab; - if (tab == null || tab.Repo == null) return; + private void TabsContextMenuOpening(object sender, ContextMenuEventArgs ev) { + var tab = (sender as TabItem).DataContext as Tab; + if (tab == null) { + ev.Handled = true; + return; + } - Tabs.Remove(tab); - tab.Page = null; - tab.Repo.RemovePopup(); - tab.Repo.Close(); - tab.Repo = null; + var repo = tab.Repo; + if (repo == null) { + ev.Handled = true; + return; + } + + var close = new MenuItem(); + close.Header = "Close"; + close.Click += (o, e) => { + Tabs.Remove(tab); + + tab.Page = null; + tab.Repo.RemovePopup(); + tab.Repo.Close(); + tab.Repo = null; + }; + + var copyPath = new MenuItem(); + copyPath.Header = "Copy Path"; + copyPath.Click += (o, e) => { + Clipboard.SetText(repo.Path); + e.Handled = true; + }; + + var refresh = new MenuItem(); + refresh.Header = "Refresh"; + refresh.Click += (o, e) => { + repo.AssertCommand(null); + e.Handled = true; + }; + + var menu = new ContextMenu(); + menu.Items.Add(close); + menu.Items.Add(new Separator()); + menu.Items.Add(copyPath); + menu.Items.Add(refresh); + menu.IsOpen = true; + + ev.Handled = true; } /// @@ -189,29 +238,4 @@ namespace SourceGit.UI { } #endregion } - - /// - /// Extension methods for repository. - /// - public static class RepositoryTabBindings { - - /// - /// Bring up tab of repository if it was opened before. - /// - /// - /// - public static bool BringUpTab(this Git.Repository repo) { - var main = App.Current.MainWindow as Launcher; - - for (int i = 1; i < main.Tabs.Count; i++) { - var opened = main.Tabs[i]; - if (opened.Repo.Path == repo.Path) { - main.openedTabs.SelectedItem = opened; - return true; - } - } - - return false; - } - } } diff --git a/src/UI/Manager.xaml.cs b/src/UI/Manager.xaml.cs index c6334c14..a89c23a7 100644 --- a/src/UI/Manager.xaml.cs +++ b/src/UI/Manager.xaml.cs @@ -429,7 +429,7 @@ namespace SourceGit.UI { } var repo = App.Preference.AddRepository(path, ""); - if (!repo.BringUpTab()) repo.Open(); + App.Open(repo); } /// diff --git a/src/UI/Stashes.xaml b/src/UI/Stashes.xaml index 832b0302..787d69d8 100644 --- a/src/UI/Stashes.xaml +++ b/src/UI/Stashes.xaml @@ -7,8 +7,7 @@ xmlns:git="clr-namespace:SourceGit.Git" xmlns:converters="clr-namespace:SourceGit.Converters" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" - Unloaded="Cleanup"> + d:DesignHeight="450" d:DesignWidth="800"> diff --git a/src/UI/Stashes.xaml.cs b/src/UI/Stashes.xaml.cs index c0d907a7..f0b5da92 100644 --- a/src/UI/Stashes.xaml.cs +++ b/src/UI/Stashes.xaml.cs @@ -34,9 +34,7 @@ namespace SourceGit.UI { /// /// Cleanup /// - /// - /// - private void Cleanup(object sender, RoutedEventArgs e) { + public void Cleanup() { stashList.ItemsSource = null; changeList.ItemsSource = null; diff.Reset(); diff --git a/src/UI/WorkingCopy.xaml.cs b/src/UI/WorkingCopy.xaml.cs index 085263d7..991796c7 100644 --- a/src/UI/WorkingCopy.xaml.cs +++ b/src/UI/WorkingCopy.xaml.cs @@ -112,6 +112,18 @@ namespace SourceGit.UI { Validation.ClearInvalid(txtCommitMsg.GetBindingExpression(TextBox.TextProperty)); } + /// + /// Cleanup + /// + public void Cleanup() { + Repo = null; + unstagedList.ItemsSource = null; + unstagedList.ItemsSource = null; + stageList.ItemsSource = null; + stageTree.ItemsSource = null; + diffViewer.Reset(); + } + #region UNSTAGED private void UnstagedTreeMultiSelectionChanged(object sender, RoutedEventArgs e) { mergePanel.Visibility = Visibility.Collapsed;