mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-10-31 13:03:20 -07:00
feature<Launcher>: close tabs by context menu; collect garbage after repository closed
This commit is contained in:
parent
a9f138076e
commit
1a46551a77
14 changed files with 145 additions and 103 deletions
|
@ -90,6 +90,14 @@ namespace SourceGit {
|
||||||
Current.MainWindow.Show();
|
Current.MainWindow.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Open repository.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="repo"></param>
|
||||||
|
public static void Open(Git.Repository repo) {
|
||||||
|
(Current.MainWindow as UI.Launcher).Open(repo);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deactivated event.
|
/// Deactivated event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -15,7 +15,6 @@ namespace SourceGit.Git {
|
||||||
public class Repository {
|
public class Repository {
|
||||||
|
|
||||||
#region HOOKS
|
#region HOOKS
|
||||||
public static Action<Repository> OnOpen = null;
|
|
||||||
[XmlIgnore] public Action<string> OnNavigateCommit = null;
|
[XmlIgnore] public Action<string> OnNavigateCommit = null;
|
||||||
[XmlIgnore] public Action OnWorkingCopyChanged = null;
|
[XmlIgnore] public Action OnWorkingCopyChanged = null;
|
||||||
[XmlIgnore] public Action OnTagChanged = null;
|
[XmlIgnore] public Action OnTagChanged = null;
|
||||||
|
@ -23,6 +22,7 @@ namespace SourceGit.Git {
|
||||||
[XmlIgnore] public Action OnBranchChanged = null;
|
[XmlIgnore] public Action OnBranchChanged = null;
|
||||||
[XmlIgnore] public Action OnCommitsChanged = null;
|
[XmlIgnore] public Action OnCommitsChanged = null;
|
||||||
[XmlIgnore] public Action OnSubmoduleChanged = null;
|
[XmlIgnore] public Action OnSubmoduleChanged = null;
|
||||||
|
[XmlIgnore] public Action OnClosing = null;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region PROPERTIES_SAVED
|
#region PROPERTIES_SAVED
|
||||||
|
@ -294,14 +294,14 @@ namespace SourceGit.Git {
|
||||||
featurePrefix = GetConfig("gitflow.prefix.feature");
|
featurePrefix = GetConfig("gitflow.prefix.feature");
|
||||||
releasePrefix = GetConfig("gitflow.prefix.release");
|
releasePrefix = GetConfig("gitflow.prefix.release");
|
||||||
hotfixPrefix = GetConfig("gitflow.prefix.hotfix");
|
hotfixPrefix = GetConfig("gitflow.prefix.hotfix");
|
||||||
|
|
||||||
OnOpen?.Invoke(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Close repository.
|
/// Close repository.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Close() {
|
public void Close() {
|
||||||
|
OnClosing?.Invoke();
|
||||||
|
|
||||||
OnBranchChanged = null;
|
OnBranchChanged = null;
|
||||||
OnCommitsChanged = null;
|
OnCommitsChanged = null;
|
||||||
OnTagChanged = null;
|
OnTagChanged = null;
|
||||||
|
@ -309,6 +309,7 @@ namespace SourceGit.Git {
|
||||||
OnWorkingCopyChanged = null;
|
OnWorkingCopyChanged = null;
|
||||||
OnNavigateCommit = null;
|
OnNavigateCommit = null;
|
||||||
OnSubmoduleChanged = null;
|
OnSubmoduleChanged = null;
|
||||||
|
OnClosing = null;
|
||||||
|
|
||||||
cachedBranches.Clear();
|
cachedBranches.Clear();
|
||||||
cachedRemotes.Clear();
|
cachedRemotes.Clear();
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<Geometry x:Key="Icon.Submodule">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</Geometry>
|
<Geometry x:Key="Icon.Submodule">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</Geometry>
|
||||||
<Geometry x:Key="Icon.LFS">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</Geometry>
|
<Geometry x:Key="Icon.LFS">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</Geometry>
|
||||||
<Geometry x:Key="Icon.User">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</Geometry>
|
<Geometry x:Key="Icon.User">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</Geometry>
|
||||||
|
<Geometry x:Key="Icon.Home">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</Geometry>
|
||||||
|
|
||||||
<Geometry x:Key="Icon.ScrollLeft">M753.613 996.727L269.38 511.505 754.602 27.272z</Geometry>
|
<Geometry x:Key="Icon.ScrollLeft">M753.613 996.727L269.38 511.505 754.602 27.272z</Geometry>
|
||||||
<Geometry x:Key="Icon.ScrollRight">M270.387 27.273L754.62 512.495 269.398 996.728z</Geometry>
|
<Geometry x:Key="Icon.ScrollRight">M270.387 27.273L754.62 512.495 269.398 996.728z</Geometry>
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
xmlns:local="clr-namespace:SourceGit.UI"
|
xmlns:local="clr-namespace:SourceGit.UI"
|
||||||
xmlns:converters="clr-namespace:SourceGit.Converters"
|
xmlns:converters="clr-namespace:SourceGit.Converters"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450" d:DesignWidth="800"
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
Unloaded="Cleanup">
|
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<RoutedUICommand x:Key="OpenSearchBarCommand" Text="OpenSearchBar"/>
|
<RoutedUICommand x:Key="OpenSearchBarCommand" Text="OpenSearchBar"/>
|
||||||
<RoutedUICommand x:Key="HideSearchBarCommand" Text="HideSearchBar"/>
|
<RoutedUICommand x:Key="HideSearchBarCommand" Text="HideSearchBar"/>
|
||||||
|
|
|
@ -50,7 +50,8 @@ namespace SourceGit.UI {
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="repo">Opened repository.</param>
|
/// <param name="repo">Opened repository.</param>
|
||||||
public Dashboard(Git.Repository opened) {
|
public Dashboard(Git.Repository opened) {
|
||||||
|
opened.OnClosing = Cleanup;
|
||||||
opened.OnWorkingCopyChanged = UpdateLocalChanges;
|
opened.OnWorkingCopyChanged = UpdateLocalChanges;
|
||||||
opened.OnTagChanged = UpdateTags;
|
opened.OnTagChanged = UpdateTags;
|
||||||
opened.OnStashChanged = UpdateStashes;
|
opened.OnStashChanged = UpdateStashes;
|
||||||
|
@ -78,6 +79,22 @@ namespace SourceGit.UI {
|
||||||
UpdateSubmodules();
|
UpdateSubmodules();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cleanup
|
||||||
|
/// </summary>
|
||||||
|
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
|
#region DATA_UPDATE
|
||||||
private void UpdateHistories() {
|
private void UpdateHistories() {
|
||||||
Dispatcher.Invoke(() => {
|
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
|
#endregion
|
||||||
|
|
||||||
#region TOOLBAR
|
#region TOOLBAR
|
||||||
|
@ -1021,7 +1030,7 @@ namespace SourceGit.UI {
|
||||||
sub.Name = Path.GetFileName(path);
|
sub.Name = Path.GetFileName(path);
|
||||||
sub.Parent = repo;
|
sub.Parent = repo;
|
||||||
|
|
||||||
if (!sub.BringUpTab()) sub.Open();
|
App.Open(sub);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,9 @@ namespace SourceGit.UI {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Reset() {
|
public void Reset() {
|
||||||
mask.Visibility = Visibility.Visible;
|
mask.Visibility = Visibility.Visible;
|
||||||
|
lineChanges = null;
|
||||||
|
foreach (var editor in editors) editorContainer.Children.Remove(editor);
|
||||||
|
editors.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -10,8 +10,7 @@
|
||||||
xmlns:sourcegit="clr-namespace:SourceGit"
|
xmlns:sourcegit="clr-namespace:SourceGit"
|
||||||
xmlns:converters="clr-namespace:SourceGit.Converters"
|
xmlns:converters="clr-namespace:SourceGit.Converters"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450" d:DesignWidth="800"
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
Unloaded="Cleanup">
|
|
||||||
<Grid x:Name="layout" Background="{StaticResource Brush.BG1}">
|
<Grid x:Name="layout" Background="{StaticResource Brush.BG1}">
|
||||||
<!-- List Panel (SearchBar + DataGrid) -->
|
<!-- List Panel (SearchBar + DataGrid) -->
|
||||||
<Grid x:Name="commitListPanel" Background="{StaticResource Brush.BG2}" ClipToBounds="True">
|
<Grid x:Name="commitListPanel" Background="{StaticResource Brush.BG2}" ClipToBounds="True">
|
||||||
|
|
|
@ -78,6 +78,15 @@ namespace SourceGit.UI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cleanup
|
||||||
|
/// </summary>
|
||||||
|
public void Cleanup() {
|
||||||
|
commitGraph.Children.Clear();
|
||||||
|
commitList.ItemsSource = null;
|
||||||
|
cachedCommits.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
#region DATA
|
#region DATA
|
||||||
public void SetCommits(List<Git.Commit> commits) {
|
public void SetCommits(List<Git.Commit> commits) {
|
||||||
cachedCommits = commits;
|
cachedCommits = commits;
|
||||||
|
@ -184,12 +193,6 @@ namespace SourceGit.UI {
|
||||||
SetLoadingEnabled(false);
|
SetLoadingEnabled(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Cleanup(object sender, RoutedEventArgs e) {
|
|
||||||
commitGraph.Children.Clear();
|
|
||||||
commitList.ItemsSource = null;
|
|
||||||
cachedCommits.Clear();
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region SEARCH_BAR
|
#region SEARCH_BAR
|
||||||
|
@ -516,7 +519,7 @@ namespace SourceGit.UI {
|
||||||
|
|
||||||
// Reset
|
// Reset
|
||||||
var reset = new MenuItem();
|
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.Visibility = commit.IsHEAD ? Visibility.Collapsed : Visibility.Visible;
|
||||||
reset.Click += (o, e) => {
|
reset.Click += (o, e) => {
|
||||||
Reset.Show(Repo, commit);
|
Reset.Show(Repo, commit);
|
||||||
|
@ -526,7 +529,7 @@ namespace SourceGit.UI {
|
||||||
|
|
||||||
// Rebase or interactive rebase
|
// Rebase or interactive rebase
|
||||||
var rebase = new MenuItem();
|
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.Visibility = commit.IsHEAD ? Visibility.Collapsed : Visibility.Visible;
|
||||||
rebase.Click += (o, e) => {
|
rebase.Click += (o, e) => {
|
||||||
if (commit.IsMerged) {
|
if (commit.IsMerged) {
|
||||||
|
@ -587,7 +590,7 @@ namespace SourceGit.UI {
|
||||||
|
|
||||||
// Save as patch
|
// Save as patch
|
||||||
var patch = new MenuItem();
|
var patch = new MenuItem();
|
||||||
patch.Header = "Save As Patch";
|
patch.Header = "Save as Patch";
|
||||||
patch.Click += (o, e) => {
|
patch.Click += (o, e) => {
|
||||||
FolderDailog.Open("Save patch to ...", saveTo => {
|
FolderDailog.Open("Save patch to ...", saveTo => {
|
||||||
Repo.RunCommand($"format-patch {commit.SHA} -1 -o \"{saveTo}\"", null);
|
Repo.RunCommand($"format-patch {commit.SHA} -1 -o \"{saveTo}\"", null);
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
Data="M 0,0 L 0,6 6,6 C 6,6 0,6 0,0 Z"
|
Data="M 0,0 L 0,6 6,6 C 6,6 0,6 0,0 Z"
|
||||||
Fill="Transparent"/>
|
Fill="Transparent"/>
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal" Margin="8,0" VerticalAlignment="Center">
|
<StackPanel Orientation="Horizontal" Margin="12,0" VerticalAlignment="Center">
|
||||||
<Path Grid.Column="0" Width="14" Height="14" x:Name="Icon" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Git}"/>
|
<Path Grid.Column="0" Width="14" Height="14" x:Name="Icon" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Git}"/>
|
||||||
|
|
||||||
<ContentPresenter
|
<ContentPresenter
|
||||||
|
@ -119,15 +119,8 @@
|
||||||
TextElement.Foreground="{DynamicResource Brush.FG}"
|
TextElement.Foreground="{DynamicResource Brush.FG}"
|
||||||
TextElement.FontWeight="Bold"
|
TextElement.FontWeight="Bold"
|
||||||
ContentSource="Header"
|
ContentSource="Header"
|
||||||
Margin="8,0"
|
Margin="8,0,0,0"
|
||||||
RecognizesAccessKey="True" />
|
RecognizesAccessKey="True" />
|
||||||
|
|
||||||
<Button x:Name="Closer" Background="Transparent" Grid.Column="2" Click="CloseRepo" Visibility="Hidden">
|
|
||||||
<Button.ToolTip>
|
|
||||||
<ToolTip Content="CLOSE" FontWeight="Normal"/>
|
|
||||||
</Button.ToolTip>
|
|
||||||
<Path Width="8" Height="8" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Close}"/>
|
|
||||||
</Button>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
<ControlTemplate.Triggers>
|
<ControlTemplate.Triggers>
|
||||||
|
@ -139,16 +132,8 @@
|
||||||
<Setter TargetName="CornerRight" Property="Fill" Value="{StaticResource Brush.BG1}"/>
|
<Setter TargetName="CornerRight" Property="Fill" Value="{StaticResource Brush.BG1}"/>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<Trigger Property="AllowDrop" Value="False">
|
<Trigger Property="AllowDrop" Value="False">
|
||||||
<Setter TargetName="Icon" Property="Fill" Value="#FFF05133"/>
|
<Setter TargetName="Icon" Property="Data" Value="{StaticResource Icon.Home}"/>
|
||||||
<Setter TargetName="Closer" Property="Visibility" Value="Collapsed"/>
|
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<MultiTrigger>
|
|
||||||
<MultiTrigger.Conditions>
|
|
||||||
<Condition Property="AllowDrop" Value="True"/>
|
|
||||||
<Condition Property="IsMouseOver" Value="True"/>
|
|
||||||
</MultiTrigger.Conditions>
|
|
||||||
<Setter TargetName="Closer" Property="Visibility" Value="Visible"/>
|
|
||||||
</MultiTrigger>
|
|
||||||
<MultiTrigger>
|
<MultiTrigger>
|
||||||
<MultiTrigger.Conditions>
|
<MultiTrigger.Conditions>
|
||||||
<Condition Property="IsSelected" Value="False"/>
|
<Condition Property="IsSelected" Value="False"/>
|
||||||
|
@ -166,6 +151,7 @@
|
||||||
|
|
||||||
<EventSetter Event="MouseMove" Handler="TabsMouseMove"/>
|
<EventSetter Event="MouseMove" Handler="TabsMouseMove"/>
|
||||||
<EventSetter Event="Drop" Handler="TabsDrop"/>
|
<EventSetter Event="Drop" Handler="TabsDrop"/>
|
||||||
|
<EventSetter Event="ContextMenuOpening" Handler="TabsContextMenuOpening"/>
|
||||||
</Style>
|
</Style>
|
||||||
</TabControl.ItemContainerStyle>
|
</TabControl.ItemContainerStyle>
|
||||||
|
|
||||||
|
|
|
@ -36,26 +36,9 @@ namespace SourceGit.UI {
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Launcher() {
|
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() {
|
Tabs.Add(new Tab() {
|
||||||
Title = "SOURCE GIT",
|
Title = "HOME",
|
||||||
Tooltip = "Welcome Page",
|
Tooltip = "Repositories Manager",
|
||||||
AllowDragDrop = false,
|
AllowDragDrop = false,
|
||||||
Page = new Manager(),
|
Page = new Manager(),
|
||||||
});
|
});
|
||||||
|
@ -64,21 +47,87 @@ namespace SourceGit.UI {
|
||||||
openedTabs.SelectedItem = Tabs[0];
|
openedTabs.SelectedItem = Tabs[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Open repository
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="repo"></param>
|
||||||
|
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
|
#region LAYOUT_CONTENT
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Close repository tab.
|
/// Context menu for tab items.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
private void CloseRepo(object sender, RoutedEventArgs e) {
|
private void TabsContextMenuOpening(object sender, ContextMenuEventArgs ev) {
|
||||||
var tab = (sender as Button).DataContext as Tab;
|
var tab = (sender as TabItem).DataContext as Tab;
|
||||||
if (tab == null || tab.Repo == null) return;
|
if (tab == null) {
|
||||||
|
ev.Handled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Tabs.Remove(tab);
|
var repo = tab.Repo;
|
||||||
tab.Page = null;
|
if (repo == null) {
|
||||||
tab.Repo.RemovePopup();
|
ev.Handled = true;
|
||||||
tab.Repo.Close();
|
return;
|
||||||
tab.Repo = null;
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -189,29 +238,4 @@ namespace SourceGit.UI {
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Extension methods for repository.
|
|
||||||
/// </summary>
|
|
||||||
public static class RepositoryTabBindings {
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Bring up tab of repository if it was opened before.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="repo"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -429,7 +429,7 @@ namespace SourceGit.UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
var repo = App.Preference.AddRepository(path, "");
|
var repo = App.Preference.AddRepository(path, "");
|
||||||
if (!repo.BringUpTab()) repo.Open();
|
App.Open(repo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
xmlns:git="clr-namespace:SourceGit.Git"
|
xmlns:git="clr-namespace:SourceGit.Git"
|
||||||
xmlns:converters="clr-namespace:SourceGit.Converters"
|
xmlns:converters="clr-namespace:SourceGit.Converters"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450" d:DesignWidth="800"
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
Unloaded="Cleanup">
|
|
||||||
<Grid Background="{StaticResource Brush.BG3}">
|
<Grid Background="{StaticResource Brush.BG3}">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="300"/>
|
<ColumnDefinition Width="300"/>
|
||||||
|
|
|
@ -34,9 +34,7 @@ namespace SourceGit.UI {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Cleanup
|
/// Cleanup
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
public void Cleanup() {
|
||||||
/// <param name="e"></param>
|
|
||||||
private void Cleanup(object sender, RoutedEventArgs e) {
|
|
||||||
stashList.ItemsSource = null;
|
stashList.ItemsSource = null;
|
||||||
changeList.ItemsSource = null;
|
changeList.ItemsSource = null;
|
||||||
diff.Reset();
|
diff.Reset();
|
||||||
|
|
|
@ -112,6 +112,18 @@ namespace SourceGit.UI {
|
||||||
Validation.ClearInvalid(txtCommitMsg.GetBindingExpression(TextBox.TextProperty));
|
Validation.ClearInvalid(txtCommitMsg.GetBindingExpression(TextBox.TextProperty));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cleanup
|
||||||
|
/// </summary>
|
||||||
|
public void Cleanup() {
|
||||||
|
Repo = null;
|
||||||
|
unstagedList.ItemsSource = null;
|
||||||
|
unstagedList.ItemsSource = null;
|
||||||
|
stageList.ItemsSource = null;
|
||||||
|
stageTree.ItemsSource = null;
|
||||||
|
diffViewer.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
#region UNSTAGED
|
#region UNSTAGED
|
||||||
private void UnstagedTreeMultiSelectionChanged(object sender, RoutedEventArgs e) {
|
private void UnstagedTreeMultiSelectionChanged(object sender, RoutedEventArgs e) {
|
||||||
mergePanel.Visibility = Visibility.Collapsed;
|
mergePanel.Visibility = Visibility.Collapsed;
|
||||||
|
|
Loading…
Reference in a new issue