feature(*): supports multi-repo editing

This commit is contained in:
leo 2020-08-03 16:23:00 +08:00
parent 3c80f2700c
commit 81a3cb9566
41 changed files with 666 additions and 450 deletions

View file

@ -36,6 +36,14 @@ namespace SourceGit {
set; set;
} }
/// <summary>
/// Get main window.
/// </summary>
public static UI.Launcher Launcher {
get;
private set;
}
/// <summary> /// <summary>
/// Raise error message. /// Raise error message.
/// </summary> /// </summary>
@ -92,8 +100,8 @@ namespace SourceGit {
} }
// Show main window // Show main window
var launcher = new UI.Launcher(); Launcher = new UI.Launcher();
launcher.Show(); Launcher.Show();
} }
/// <summary> /// <summary>

View file

@ -16,7 +16,6 @@ namespace SourceGit.Git {
#region HOOKS #region HOOKS
public static Action<Repository> OnOpen = null; public static Action<Repository> OnOpen = null;
public static Action OnClose = 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;
@ -355,7 +354,7 @@ namespace SourceGit.Git {
releasePrefix = null; releasePrefix = null;
hotfixPrefix = null; hotfixPrefix = null;
OnClose?.Invoke(); GC.Collect();
} }
#endregion #endregion

View file

@ -34,7 +34,8 @@ namespace SourceGit.UI {
/// </summary> /// </summary>
/// <param name="repo"></param> /// <param name="repo"></param>
public static void Show(Git.Repository repo) { public static void Show(Git.Repository repo) {
PopupManager.Show(new AddSubmodule(repo)); var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(new AddSubmodule(repo));
} }
#region EVENTS #region EVENTS
@ -57,14 +58,17 @@ namespace SourceGit.UI {
if (Validation.GetHasError(txtPath)) return; if (Validation.GetHasError(txtPath)) return;
var recursive = chkRecursive.IsChecked == true; var recursive = chkRecursive.IsChecked == true;
var popup = App.Launcher.GetPopupManager(repo);
PopupManager.Lock(); popup?.Lock();
await Task.Run(() => repo.AddSubmodule(RepoURL, LocalPath, recursive, PopupManager.UpdateStatus)); await Task.Run(() => repo.AddSubmodule(RepoURL, LocalPath, recursive, msg => {
PopupManager.Close(true); popup?.UpdateStatus(msg);
}));
popup?.Close(true);
} }
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
#endregion #endregion
} }

View file

@ -52,7 +52,8 @@ namespace SourceGit.UI {
/// </summary> /// </summary>
/// <param name="opened"></param> /// <param name="opened"></param>
public static void Show(Git.Repository opened) { public static void Show(Git.Repository opened) {
PopupManager.Show(new Apply(opened)); var popup = App.Launcher.GetPopupManager(opened);
popup?.Show(new Apply(opened));
} }
/// <summary> /// <summary>
@ -82,13 +83,14 @@ namespace SourceGit.UI {
txtPatchFile.GetBindingExpression(TextBox.TextProperty).UpdateSource(); txtPatchFile.GetBindingExpression(TextBox.TextProperty).UpdateSource();
if (Validation.GetHasError(txtPatchFile)) return; if (Validation.GetHasError(txtPatchFile)) return;
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
var mode = combWhitespaceOptions.SelectedItem as WhitespaceOption; var mode = combWhitespaceOptions.SelectedItem as WhitespaceOption;
var ignoreSpaceChanges = chkIgnoreWhitespace.IsChecked == true; var ignoreSpaceChanges = chkIgnoreWhitespace.IsChecked == true;
await Task.Run(() => repo.Apply(PatchFile, ignoreSpaceChanges, mode.Arg)); await Task.Run(() => repo.Apply(PatchFile, ignoreSpaceChanges, mode.Arg));
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -97,7 +99,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -36,7 +36,7 @@ namespace SourceGit.UI {
double minWidth = content.ActualWidth; double minWidth = content.ActualWidth;
// Move to center. // Move to center.
var parent = App.Current.MainWindow; var parent = App.Launcher;
Left = parent.Left + (parent.Width - Width) * 0.5; Left = parent.Left + (parent.Width - Width) * 0.5;
Top = parent.Top + (parent.Height - Height) * 0.5; Top = parent.Top + (parent.Height - Height) * 0.5;

View file

@ -1,4 +1,4 @@
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
namespace SourceGit.UI { namespace SourceGit.UI {
@ -29,7 +29,8 @@ namespace SourceGit.UI {
/// <param name="repo"></param> /// <param name="repo"></param>
/// <param name="commit"></param> /// <param name="commit"></param>
public static void Show(Git.Repository repo, Git.Commit commit) { public static void Show(Git.Repository repo, Git.Commit commit) {
PopupManager.Show(new CherryPick(repo, commit)); var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(new CherryPick(repo, commit));
} }
/// <summary> /// <summary>
@ -39,7 +40,9 @@ namespace SourceGit.UI {
/// <param name="e"></param> /// <param name="e"></param>
private void Start(object sender, RoutedEventArgs e) { private void Start(object sender, RoutedEventArgs e) {
repo.CherryPick(commitSHA, chkCommitChanges.IsChecked != true); repo.CherryPick(commitSHA, chkCommitChanges.IsChecked != true);
PopupManager.Close();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Close();
} }
/// <summary> /// <summary>
@ -48,7 +51,8 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Close();
} }
} }
} }

View file

@ -42,7 +42,8 @@ namespace SourceGit.UI {
/// Show clone dialog. /// Show clone dialog.
/// </summary> /// </summary>
public static void Show() { public static void Show() {
PopupManager.Show(new Clone()); var popup = App.Launcher.GetPopupManager(null);
popup?.Show(new Clone());
} }
/// <summary> /// <summary>
@ -91,16 +92,17 @@ namespace SourceGit.UI {
rName = RemoteName; rName = RemoteName;
} }
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(null);
popup.Lock();
var repo = await Task.Run(() => { var repo = await Task.Run(() => {
return Git.Repository.Clone(RemoteUri, ParentFolder, rName, repoName, PopupManager.UpdateStatus); return Git.Repository.Clone(RemoteUri, ParentFolder, rName, repoName, popup.UpdateStatus);
}); });
if (repo == null) { if (repo == null) {
PopupManager.Unlock(); popup.Unlock();
} else { } else {
PopupManager.Close(true); popup.Close(true);
repo.Open(); repo.Open();
} }
} }
@ -111,7 +113,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(null).Close();
} }
} }
} }

View file

@ -43,7 +43,8 @@ namespace SourceGit.UI {
/// </summary> /// </summary>
/// <param name="repo"></param> /// <param name="repo"></param>
public static void Show(Git.Repository repo) { public static void Show(Git.Repository repo) {
PopupManager.Show(new Configure(repo)); var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(new Configure(repo));
} }
#region EVENTS #region EVENTS
@ -63,7 +64,7 @@ namespace SourceGit.UI {
} }
private void Close(object sender, RoutedEventArgs e) { private void Close(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
#endregion #endregion
} }

View file

@ -58,7 +58,9 @@ namespace SourceGit.UI {
dialog.basedOnDesc.Content = branch.Name; dialog.basedOnDesc.Content = branch.Name;
if (!branch.IsLocal) dialog.txtName.Text = branch.Name.Substring(branch.Remote.Length + 1); if (!branch.IsLocal) dialog.txtName.Text = branch.Name.Substring(branch.Remote.Length + 1);
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(dialog);
} }
/// <summary> /// <summary>
@ -71,7 +73,9 @@ namespace SourceGit.UI {
dialog.based = tag.Name; dialog.based = tag.Name;
dialog.basedOnType.Data = dialog.FindResource("Icon.Tag") as Geometry; dialog.basedOnType.Data = dialog.FindResource("Icon.Tag") as Geometry;
dialog.basedOnDesc.Content = tag.Name; dialog.basedOnDesc.Content = tag.Name;
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(dialog);
} }
/// <summary> /// <summary>
@ -84,7 +88,9 @@ namespace SourceGit.UI {
dialog.based = commit.SHA; dialog.based = commit.SHA;
dialog.basedOnType.Data = dialog.FindResource("Icon.Commit") as Geometry; dialog.basedOnType.Data = dialog.FindResource("Icon.Commit") as Geometry;
dialog.basedOnDesc.Content = $"{commit.ShortSHA} {commit.Subject}"; dialog.basedOnDesc.Content = $"{commit.ShortSHA} {commit.Subject}";
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(dialog);
} }
/// <summary> /// <summary>
@ -96,7 +102,8 @@ namespace SourceGit.UI {
txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource(); txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
if (Validation.GetHasError(txtName)) return; if (Validation.GetHasError(txtName)) return;
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
bool checkout = chkCheckout.IsChecked == true; bool checkout = chkCheckout.IsChecked == true;
await Task.Run(() => { await Task.Run(() => {
@ -119,7 +126,7 @@ namespace SourceGit.UI {
} }
}); });
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -128,7 +135,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
@ -51,7 +51,9 @@ namespace SourceGit.UI {
dialog.based = branch.Head; dialog.based = branch.Head;
dialog.basedOnType.Data = dialog.FindResource("Icon.Branch") as Geometry; dialog.basedOnType.Data = dialog.FindResource("Icon.Branch") as Geometry;
dialog.basedOnDesc.Content = branch.Name; dialog.basedOnDesc.Content = branch.Name;
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(dialog);
} }
/// <summary> /// <summary>
@ -64,7 +66,9 @@ namespace SourceGit.UI {
dialog.based = commit.SHA; dialog.based = commit.SHA;
dialog.basedOnType.Data = dialog.FindResource("Icon.Commit") as Geometry; dialog.basedOnType.Data = dialog.FindResource("Icon.Commit") as Geometry;
dialog.basedOnDesc.Content = $"{commit.ShortSHA} {commit.Subject}"; dialog.basedOnDesc.Content = $"{commit.ShortSHA} {commit.Subject}";
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(dialog);
} }
/// <summary> /// <summary>
@ -77,7 +81,9 @@ namespace SourceGit.UI {
if (Validation.GetHasError(tagName)) return; if (Validation.GetHasError(tagName)) return;
Git.Tag.Add(repo, TagName, based, tagMessage.Text); Git.Tag.Add(repo, TagName, based, tagMessage.Text);
PopupManager.Close();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Close();
} }
/// <summary> /// <summary>
@ -86,7 +92,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -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"/>
@ -34,41 +33,19 @@
<Grid Grid.Row="0" Panel.ZIndex="9999"> <Grid Grid.Row="0" Panel.ZIndex="9999">
<Border Background="{StaticResource Brush.BG1}"> <Border Background="{StaticResource Brush.BG1}">
<Border.Effect> <Border.Effect>
<DropShadowEffect ShadowDepth="2" Direction="270" Opacity=".3"/> <DropShadowEffect ShadowDepth="2" Direction="270" Opacity=".5" Color="Black"/>
</Border.Effect> </Border.Effect>
</Border> </Border>
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!-- Navigation -->
<StackPanel Grid.Column="0" Margin="8,0,0,0" Orientation="Horizontal" HorizontalAlignment="Left">
<Button Click="Close" ToolTip="Back To Welcome" Padding="0">
<StackPanel Orientation="Horizontal">
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Manager}"/>
<Label Content="Repositories"/>
<Path Width="12" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Navigator}"/>
</StackPanel>
</Button>
<Button x:Name="btnParent" Click="GotoParent" ToolTip="Open Parent Repository" Padding="0" Margin="6,0,0,0" Visibility="Collapsed">
<StackPanel Orientation="Horizontal">
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Git}"/>
<Label x:Name="txtParent"/>
<Path Width="12" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Navigator}"/>
</StackPanel>
</Button>
<Path Margin="6,0,0,0" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Git}"/>
<Label x:Name="repoName"/>
</StackPanel>
<!-- Common Git Options --> <!-- Common Git Options -->
<StackPanel Grid.Column="1" Orientation="Horizontal"> <StackPanel Grid.Column="0" Orientation="Horizontal" Margin="6,0">
<Button Click="OpenFetch" Margin="4,0"> <Button Click="OpenFetch" Margin="4,0">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Fetch}"/> <Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Fetch}"/>
@ -87,12 +64,18 @@
<Label Content="Push"/> <Label Content="Push"/>
</StackPanel> </StackPanel>
</Button> </Button>
<Button Click="OpenStash" Margin="2,0,0,0">
<Rectangle Margin="4,0,8,0" Width="1" Height="20" Fill="{StaticResource Brush.Border1}"/>
<Button Click="OpenStash" Margin="4,0">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.SaveStash}"/> <Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.SaveStash}"/>
<Label Content="Stash"/> <Label Content="Stash"/>
</StackPanel> </StackPanel>
</Button> </Button>
<Rectangle Margin="4,0,8,0" Width="1" Height="20" Fill="{StaticResource Brush.Border1}"/>
<Button Click="OpenApply" Margin="4,0"> <Button Click="OpenApply" Margin="4,0">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Apply}"/> <Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Apply}"/>
@ -539,6 +522,6 @@
</Grid> </Grid>
<!-- Popups --> <!-- Popups -->
<local:PopupManager Grid.Row="1"/> <local:PopupManager x:Name="popupManager" Grid.Row="1"/>
</Grid> </Grid>
</UserControl> </UserControl>

View file

@ -67,17 +67,9 @@ namespace SourceGit.UI {
InitializeComponent(); InitializeComponent();
repo = opened; repo = opened;
repoName.Content = repo.Name;
histories.Repo = opened; histories.Repo = opened;
commits.Repo = opened; commits.Repo = opened;
if (repo.Parent != null) {
btnParent.Visibility = Visibility.Visible;
txtParent.Content = repo.Parent.Name;
} else {
btnParent.Visibility = Visibility.Collapsed;
}
UpdateBranches(); UpdateBranches();
UpdateHistories(); UpdateHistories();
UpdateLocalChanges(); UpdateLocalChanges();
@ -86,6 +78,17 @@ namespace SourceGit.UI {
UpdateSubmodules(); UpdateSubmodules();
} }
/// <summary>
/// Cleanup all items
/// </summary>
public void Cleanup() {
localBranchTree.ItemsSource = null;
remoteBranchTree.ItemsSource = null;
tagList.ItemsSource = null;
cachedLocalBranches.Clear();
cachedRemotes.Clear();
}
#region DATA_UPDATE #region DATA_UPDATE
private void UpdateHistories() { private void UpdateHistories() {
Dispatcher.Invoke(() => { Dispatcher.Invoke(() => {
@ -244,8 +247,8 @@ namespace SourceGit.UI {
MakeBranchNode(b, remote.Children, folders, states, "remotes"); MakeBranchNode(b, remote.Children, folders, states, "remotes");
} else { } else {
/// 对于 SUBMODULE HEAD 出于游离状态detached on commit id /// 对于 SUBMODULE HEAD 出于游离状态detached on commit id
/// 此时,分支既不是 本地分支,也不是远程分支 /// 此时,分支既不是 本地分支,也不是远程分支
IsDetached = b.IsCurrent; IsDetached = b.IsCurrent;
} }
} }
@ -297,33 +300,9 @@ 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
private void Close(object sender, RoutedEventArgs e) {
if (PopupManager.IsLocked()) return;
PopupManager.Close();
cachedLocalBranches.Clear();
cachedRemotes.Clear();
repo.Close();
}
private void GotoParent(object sender, RoutedEventArgs e) {
if (repo.Parent == null) return;
repo.Parent.Open();
e.Handled = true;
}
private void OpenFetch(object sender, RoutedEventArgs e) { private void OpenFetch(object sender, RoutedEventArgs e) {
Fetch.Show(repo); Fetch.Show(repo);
} }
@ -345,7 +324,7 @@ namespace SourceGit.UI {
} }
private void OpenSearch(object sender, RoutedEventArgs e) { private void OpenSearch(object sender, RoutedEventArgs e) {
if (PopupManager.IsLocked()) return; if (popupManager.IsLocked()) return;
workspace.SelectedItem = historiesSwitch; workspace.SelectedItem = historiesSwitch;
if (histories.searchBar.Margin.Top == 0) { if (histories.searchBar.Margin.Top == 0) {
@ -936,7 +915,7 @@ namespace SourceGit.UI {
} }
private void UpdateSubmodule(object sender, RoutedEventArgs e) { private void UpdateSubmodule(object sender, RoutedEventArgs e) {
Waiting.Show(() => repo.UpdateSubmodule()); Waiting.Show(repo, () => repo.UpdateSubmodule());
} }
private void SubmoduleLostFocus(object sender, RoutedEventArgs e) { private void SubmoduleLostFocus(object sender, RoutedEventArgs e) {

View file

@ -28,7 +28,8 @@ namespace SourceGit.UI {
/// <param name="opened"></param> /// <param name="opened"></param>
/// <param name="branch"></param> /// <param name="branch"></param>
public static void Show(Git.Repository opened, Git.Branch branch) { public static void Show(Git.Repository opened, Git.Branch branch) {
PopupManager.Show(new DeleteBranch(opened, branch)); var popup = App.Launcher.GetPopupManager(opened);
popup?.Show(new DeleteBranch(opened, branch));
} }
/// <summary> /// <summary>
@ -37,9 +38,10 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private async void Sure(object sender, RoutedEventArgs e) { private async void Sure(object sender, RoutedEventArgs e) {
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => branch.Delete(repo)); await Task.Run(() => branch.Delete(repo));
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -48,7 +50,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -29,7 +29,8 @@ namespace SourceGit.UI {
/// <param name="opened"></param> /// <param name="opened"></param>
/// <param name="remote"></param> /// <param name="remote"></param>
public static void Show(Git.Repository opened, string remote) { public static void Show(Git.Repository opened, string remote) {
PopupManager.Show(new DeleteRemote(opened, remote)); var popup = App.Launcher.GetPopupManager(opened);
popup?.Show(new DeleteRemote(opened, remote));
} }
/// <summary> /// <summary>
@ -38,9 +39,10 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private async void Sure(object sender, RoutedEventArgs e) { private async void Sure(object sender, RoutedEventArgs e) {
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => Git.Remote.Delete(repo, remote)); await Task.Run(() => Git.Remote.Delete(repo, remote));
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -49,7 +51,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -30,7 +30,8 @@ namespace SourceGit.UI {
/// <param name="repo"></param> /// <param name="repo"></param>
/// <param name="tag"></param> /// <param name="tag"></param>
public static void Show(Git.Repository repo, Git.Tag tag) { public static void Show(Git.Repository repo, Git.Tag tag) {
PopupManager.Show(new DeleteTag(repo, tag)); var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(new DeleteTag(repo, tag));
} }
/// <summary> /// <summary>
@ -39,12 +40,13 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private async void Start(object sender, RoutedEventArgs e) { private async void Start(object sender, RoutedEventArgs e) {
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
var push = chkWithRemote.IsChecked == true; var push = chkWithRemote.IsChecked == true;
await Task.Run(() => Git.Tag.Delete(repo, tag.Name, push)); await Task.Run(() => Git.Tag.Delete(repo, tag.Name, push));
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -53,7 +55,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -40,17 +40,19 @@ namespace SourceGit.UI {
/// <param name="opened"></param> /// <param name="opened"></param>
/// <param name="targets"></param> /// <param name="targets"></param>
public static void Show(Git.Repository opened, List<Git.Change> targets) { public static void Show(Git.Repository opened, List<Git.Change> targets) {
PopupManager.Show(new Discard(opened, targets)); var popup = App.Launcher.GetPopupManager(opened);
popup?.Show(new Discard(opened, targets));
} }
private async void Sure(object sender, RoutedEventArgs e) { private async void Sure(object sender, RoutedEventArgs e) {
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => repo.Discard(changes)); await Task.Run(() => repo.Discard(changes));
PopupManager.Close(true); popup?.Close(true);
} }
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -40,7 +40,8 @@ namespace SourceGit.UI {
/// <param name="repo"></param> /// <param name="repo"></param>
/// <param name="preferRemote"></param> /// <param name="preferRemote"></param>
public static void Show(Git.Repository repo, string preferRemote = null) { public static void Show(Git.Repository repo, string preferRemote = null) {
PopupManager.Show(new Fetch(repo, preferRemote)); var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(new Fetch(repo, preferRemote));
} }
/// <summary> /// <summary>
@ -51,16 +52,17 @@ namespace SourceGit.UI {
private async void Start(object sender, RoutedEventArgs e) { private async void Start(object sender, RoutedEventArgs e) {
bool prune = chkPrune.IsChecked == true; bool prune = chkPrune.IsChecked == true;
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
if (chkFetchAll.IsChecked == true) { if (chkFetchAll.IsChecked == true) {
await Task.Run(() => repo.Fetch(null, prune, PopupManager.UpdateStatus)); await Task.Run(() => repo.Fetch(null, prune, msg => popup?.UpdateStatus(msg)));
} else { } else {
var remote = combRemotes.SelectedItem as Git.Remote; var remote = combRemotes.SelectedItem as Git.Remote;
await Task.Run(() => repo.Fetch(remote, prune, PopupManager.UpdateStatus)); await Task.Run(() => repo.Fetch(remote, prune, msg => popup?.UpdateStatus(msg)));
} }
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -69,7 +71,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -29,7 +29,7 @@ namespace SourceGit.UI {
InitializeComponent(); InitializeComponent();
// Move to center // Move to center
var parent = App.Current.MainWindow; var parent = App.Launcher;
Left = parent.Left + (parent.Width - Width) * 0.5; Left = parent.Left + (parent.Width - Width) * 0.5;
Top = parent.Top + (parent.Height - Height) * 0.5; Top = parent.Top + (parent.Height - Height) * 0.5;

View file

@ -36,7 +36,8 @@ namespace SourceGit.UI {
txtBranchType.Content = "Hotfix :"; txtBranchType.Content = "Hotfix :";
break; break;
default: default:
PopupManager.Close(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Close();
return; return;
} }
@ -49,7 +50,8 @@ namespace SourceGit.UI {
/// <param name="repo"></param> /// <param name="repo"></param>
/// <param name="branch"></param> /// <param name="branch"></param>
public static void Show(Git.Repository repo, Git.Branch branch) { public static void Show(Git.Repository repo, Git.Branch branch) {
PopupManager.Show(new GitFlowFinishBranch(repo, branch)); var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(new GitFlowFinishBranch(repo, branch));
} }
/// <summary> /// <summary>
@ -58,9 +60,10 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private async void Sure(object sender, RoutedEventArgs e) { private async void Sure(object sender, RoutedEventArgs e) {
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => repo.FinishGitFlowBranch(branch)); await Task.Run(() => repo.FinishGitFlowBranch(branch));
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -69,7 +72,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -26,7 +26,8 @@ namespace SourceGit.UI {
/// </summary> /// </summary>
/// <param name="repo"></param> /// <param name="repo"></param>
public static void Show(Git.Repository repo) { public static void Show(Git.Repository repo) {
PopupManager.Show(new GitFlowSetup(repo)); var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(new GitFlowSetup(repo));
} }
/// <summary> /// <summary>
@ -35,7 +36,8 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private async void Sure(object sender, RoutedEventArgs e) { private async void Sure(object sender, RoutedEventArgs e) {
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
var master = txtMaster.Text; var master = txtMaster.Text;
var dev = txtDevelop.Text; var dev = txtDevelop.Text;
@ -45,7 +47,7 @@ namespace SourceGit.UI {
var version = txtVersion.Text; var version = txtVersion.Text;
await Task.Run(() => repo.EnableGitFlow(master, dev, feature, release, hotfix, version)); await Task.Run(() => repo.EnableGitFlow(master, dev, feature, release, hotfix, version));
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -54,7 +56,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
/// <summary> /// <summary>

View file

@ -51,7 +51,8 @@ namespace SourceGit.UI {
nameValidator.Prefix = hotfixPrefix; nameValidator.Prefix = hotfixPrefix;
break; break;
default: default:
PopupManager.Close(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Close();
return; return;
} }
} }
@ -62,7 +63,8 @@ namespace SourceGit.UI {
/// <param name="repo"></param> /// <param name="repo"></param>
/// <param name="type"></param> /// <param name="type"></param>
public static void Show(Git.Repository repo, Git.Branch.Type type) { public static void Show(Git.Repository repo, Git.Branch.Type type) {
PopupManager.Show(new GitFlowStartBranch(repo, type)); var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(new GitFlowStartBranch(repo, type));
} }
/// <summary> /// <summary>
@ -74,9 +76,10 @@ namespace SourceGit.UI {
txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource(); txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
if (Validation.GetHasError(txtName)) return; if (Validation.GetHasError(txtName)) return;
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => repo.StartGitFlowBranch(type, SubName)); await Task.Run(() => repo.StartGitFlowBranch(type, SubName));
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -85,7 +88,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -526,7 +526,7 @@ namespace SourceGit.UI {
} }
var dialog = new InteractiveRebase(Repo, commit); var dialog = new InteractiveRebase(Repo, commit);
dialog.Owner = App.Current.MainWindow; dialog.Owner = App.Launcher;
dialog.ShowDialog(); dialog.ShowDialog();
} else { } else {
Rebase.Show(Repo, commit); Rebase.Show(Repo, commit);

View file

@ -25,7 +25,8 @@ namespace SourceGit.UI {
/// </summary> /// </summary>
/// <param name="path"></param> /// <param name="path"></param>
public static void Show(string path) { public static void Show(string path) {
PopupManager.Show(new Init(path)); var popup = App.Launcher.GetPopupManager(null);
popup.Show(new Init(path));
} }
/// <summary> /// <summary>
@ -34,7 +35,8 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private async void Sure(object sender, RoutedEventArgs e) { private async void Sure(object sender, RoutedEventArgs e) {
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(null);
popup.Lock();
await Task.Run(() => { await Task.Run(() => {
var errs = Git.Repository.RunCommand(workingDir, "init -q", null); var errs = Git.Repository.RunCommand(workingDir, "init -q", null);
@ -45,7 +47,7 @@ namespace SourceGit.UI {
} }
}); });
PopupManager.Close(true); popup.Close(true);
var repo = App.Preference.FindRepository(workingDir); var repo = App.Preference.FindRepository(workingDir);
if (repo != null) repo.Open(); if (repo != null) repo.Open();
@ -57,7 +59,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(null).Close();
} }
} }
} }

View file

@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:source="clr-namespace:SourceGit" xmlns:source="clr-namespace:SourceGit"
xmlns:local="clr-namespace:SourceGit.UI"
mc:Ignorable="d" mc:Ignorable="d"
MinWidth="800" MinHeight="600" MinWidth="800" MinHeight="600"
Title="Source Git" Title="Source Git"
@ -33,23 +34,23 @@
</Style.Triggers> </Style.Triggers>
</Style> </Style>
</Border.Style> </Border.Style>
<Grid> <!-- Window Content -->
<Grid Background="{StaticResource Brush.BG4}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="32"/> <RowDefinition Height="32"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Titlebar --> <Grid Grid.Row="0">
<Grid Grid.Row="0" Background="{StaticResource Brush.BG4}">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="110"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!-- Logo & Title --> <!-- LOGO & Title -->
<StackPanel Grid.Column="0" Orientation="Horizontal"> <StackPanel Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" Height="32">
<Path <Path
Width="20" Height="20" Margin="6,-1,2,0" Width="20" Height="20" Margin="6,-1,2,0"
Style="{StaticResource Style.Icon}" Style="{StaticResource Style.Icon}"
@ -60,8 +61,103 @@
<Label Content="SOURCE GIT" FontWeight="Light"/> <Label Content="SOURCE GIT" FontWeight="Light"/>
</StackPanel> </StackPanel>
<!-- Commands --> <!-- Tabs -->
<StackPanel Grid.Column="2" Orientation="Horizontal" WindowChrome.IsHitTestVisibleInChrome="True"> <TabControl
x:Name="openedTabs"
Grid.Column="1"
Padding="0"
ItemsSource="{Binding ElementName=me, Path=Tabs}">
<TabControl.Style>
<Style TargetType="{x:Type TabControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid KeyboardNavigation.TabNavigation="Local" Height="32">
<StackPanel Orientation="Horizontal"
x:Name="HeaderPanel"
Grid.Row="0"
Margin="0,6,0,0"
IsItemsHost="True"
KeyboardNavigation.TabIndex="1"
Background="Transparent" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Style>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="IsSelected" Value="{Binding IsActive, Mode=TwoWay}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="Container" Opacity=".7" Height="26" WindowChrome.IsHitTestVisibleInChrome="True">
<Border x:Name="BG" Background="Transparent" BorderThickness="0" BorderBrush="{StaticResource Brush.BG3}" CornerRadius="4,4,0,0">
<Border.Effect>
<DropShadowEffect ShadowDepth="2" Direction="90" Color="Black" Opacity=".3"/>
</Border.Effect>
</Border>
<ContentPresenter
x:Name="ContentSite"
VerticalAlignment="Center" HorizontalAlignment="Center"
TextElement.Foreground="{DynamicResource Brush.FG}"
TextElement.FontWeight="Bold"
ContentSource="Header"
Margin="4,0"
RecognizesAccessKey="True" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="BG" Property="Background" Value="{DynamicResource Brush.BG1}"/>
<Setter TargetName="BG" Property="BorderThickness" Value="1,1,1,0"/>
<Setter TargetName="Container" Property="Opacity" Value="1"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="False"/>
<Condition Property="IsMouseOver" Value="True"/>
</MultiTrigger.Conditions>
<Setter TargetName="BG" Property="Background" Value="{DynamicResource Brush.BG5}"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.ItemContainerStyle>
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="6,0">
<Path Grid.Column="0" Width="14" Height="14" x:Name="Icon" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Git}"/>
<TextBlock Grid.Column="1" Text="{Binding Title}" Foreground="{StaticResource Brush.FG}" Margin="8,0,0,0"/>
<Button x:Name="Closer" Margin="8,0,0,0" Grid.Column="2" Click="CloseRepo" ToolTip="CLOSE">
<Path Width="8" Height="8" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Close}"/>
</Button>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Repo}" Value="{x:Null}">
<Setter TargetName="Icon" Property="Data" Value="{StaticResource Icon.Manager}"/>
<Setter TargetName="Closer" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
<!-- Window Command -->
<StackPanel
Grid.Column="2"
Margin="32,0,0,0"
Orientation="Horizontal"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Height="32"
WindowChrome.IsHitTestVisibleInChrome="True">
<Button Click="ShowPreference" Width="24" ToolTip="PREFERENCE"> <Button Click="ShowPreference" Width="24" ToolTip="PREFERENCE">
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Preference}"/> <Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Preference}"/>
</Button> </Button>
@ -105,11 +201,32 @@
</StackPanel> </StackPanel>
</Grid> </Grid>
<!-- Body --> <!-- Pages -->
<ContentControl Grid.Row="1" x:Name="body"/> <ItemsControl Grid.Row="1" ItemsSource="{Binding ElementName=me, Path=Tabs}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Resources>
<BooleanToVisibilityConverter x:Key="Bool2Visible"/>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding Page}" Visibility="{Binding IsActive, Converter={StaticResource Bool2Visible}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- Alerts --> <!-- Alerts -->
<ScrollViewer Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Top" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"> <ScrollViewer
Grid.Row="1"
Margin="0,32,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto"
Panel.ZIndex="100">
<ItemsControl Margin="4" Width="300" Height="Auto" ItemsSource="{Binding Alerts, ElementName=me}"> <ItemsControl Margin="4" Width="300" Height="Auto" ItemsSource="{Binding Alerts, ElementName=me}">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate> <DataTemplate>

View file

@ -1,4 +1,3 @@
using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
@ -11,6 +10,16 @@ namespace SourceGit.UI {
/// </summary> /// </summary>
public partial class Launcher : Window { public partial class Launcher : Window {
/// <summary>
/// Tab data.
/// </summary>
public class Tab {
public string Title { get; set; }
public bool IsActive { get; set; }
public Git.Repository Repo { get; set; }
public object Page { get; set; }
}
/// <summary> /// <summary>
/// Alert data. /// Alert data.
/// </summary> /// </summary>
@ -24,37 +33,82 @@ namespace SourceGit.UI {
/// </summary> /// </summary>
public ObservableCollection<Alert> Alerts { get; set; } = new ObservableCollection<Alert>(); public ObservableCollection<Alert> Alerts { get; set; } = new ObservableCollection<Alert>();
/// <summary>
/// Opened tabs.
/// </summary>
public ObservableCollection<Tab> Tabs { get; set; } = new ObservableCollection<Tab>();
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public Launcher() { public Launcher() {
Git.Repository.OnOpen = ShowDashboard; App.OnError = msg => {
Git.Repository.OnClose = ShowManager; ShowAlert(new Alert() { Title = "ERROR", Message = msg });
};
App.OnError = msg => ShowAlert(new Alert() { Title = "ERROR", Message = msg }); Git.Repository.OnOpen = repo => {
Dispatcher.Invoke(() => {
foreach (var item in openedTabs.Items) {
var opened = item as Tab;
if (opened != null && opened.Repo != null && repo.Path == opened.Repo.Path) {
openedTabs.SelectedItem = opened;
return;
}
}
var tab = new Tab() {
Title = repo.Parent == null ? repo.Name : $"{repo.Parent.Name} : {repo.Name}",
Repo = repo,
Page = new Dashboard(repo),
};
Tabs.Add(tab);
openedTabs.SelectedItem = tab;
});
};
Tabs.Add(new Tab() {
Title = "Repositories",
Page = new Manager(),
});
InitializeComponent(); InitializeComponent();
ShowManager(); openedTabs.SelectedItem = Tabs[0];
}
/// <summary>
/// Get popup manager from given active page.
/// </summary>
/// <param name="repo"></param>
/// <returns></returns>
public PopupManager GetPopupManager(Git.Repository repo) {
if (repo == null) return (Tabs[0].Page as Manager).popupManager;
foreach (var tab in Tabs) {
if (tab.Repo != null && tab.Repo.Path == repo.Path) {
return (tab.Page as Dashboard).popupManager;
}
}
return null;
} }
#region LAYOUT_CONTENT #region LAYOUT_CONTENT
/// <summary> /// <summary>
/// Show manager. /// Close repository tab.
/// </summary> /// </summary>
private void ShowManager() { /// <param name="sender"></param>
Dispatcher.Invoke(() => { /// <param name="e"></param>
body.Content = new Manager(); private void CloseRepo(object sender, RoutedEventArgs e) {
}); var tab = (sender as Button).DataContext as Tab;
} if (tab == null || tab.Repo == null) return;
/// <summary> var popup = (tab.Page as Dashboard).popupManager;
/// Show dashboard. if (popup.IsLocked()) popup.Close(true);
/// </summary> Tabs.Remove(tab);
/// <param name="repo"></param>
private void ShowDashboard(Git.Repository repo) { tab.Page = null;
Dispatcher.Invoke(() => { tab.Repo.Close();
body.Content = new Dashboard(repo);
});
} }
/// <summary> /// <summary>
@ -63,7 +117,9 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void ShowPreference(object sender, RoutedEventArgs e) { private void ShowPreference(object sender, RoutedEventArgs e) {
Preference.Show(); var dialog = new Preference();
dialog.Owner = this;
dialog.ShowDialog();
} }
/// <summary> /// <summary>

View file

@ -8,37 +8,17 @@
xmlns:git="clr-namespace:SourceGit.Git" xmlns:git="clr-namespace:SourceGit.Git"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="450" d:DesignWidth="800">
<Grid> <Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Toolbar -->
<Grid Grid.Row="0" Panel.ZIndex="9999">
<Border Background="{StaticResource Brush.BG1}">
<Border.Effect>
<DropShadowEffect ShadowDepth="2" Direction="270" Opacity=".3"/>
</Border.Effect>
</Border>
<!-- Navigation -->
<StackPanel Grid.Column="0" Margin="8,0,0,0" Orientation="Horizontal">
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Manager}"/>
<Label Content="Repositories"/>
</StackPanel>
</Grid>
<!-- Main Body --> <!-- Main Body -->
<Grid Grid.Row="1"> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="200" MinWidth="200" MaxWidth="360"/> <ColumnDefinition Width="200" MinWidth="200" MaxWidth="360"/>
<ColumnDefinition Width="2"/> <ColumnDefinition Width="2"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!-- Left panel --> <!-- Left panel -->
<Grid Grid.Column="0"> <Grid Grid.Column="0" Background="{StaticResource Brush.BG1}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="32"/> <RowDefinition Height="32"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
@ -148,7 +128,7 @@
</TreeView> </TreeView>
</Grid> </Grid>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" Background="Transparent"/> <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" Background="{StaticResource Brush.BG1}"/>
<!-- Right Panel --> <!-- Right Panel -->
<Grid Grid.Column="2" Background="{StaticResource Brush.BG3}"> <Grid Grid.Column="2" Background="{StaticResource Brush.BG3}">
@ -161,7 +141,7 @@
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Name & Path & OpenButton --> <!-- Name & Path & OpenButton -->
<Grid Grid.Row="0"> <Grid Grid.Row="0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@ -176,7 +156,7 @@
<Path Width="20" Height="20" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Folder}"/> <Path Width="20" Height="20" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Folder}"/>
</Button> </Button>
</Grid> </Grid>
<!-- Status of selected repository --> <!-- Status of selected repository -->
<Label Grid.Row="1" Content="STATUS" FontSize="16" Margin="0,16,0,4" FontWeight="Bold" Opacity=".8"/> <Label Grid.Row="1" Content="STATUS" FontSize="16" Margin="0,16,0,4" FontWeight="Bold" Opacity=".8"/>
<StackPanel Grid.Row="2" Orientation="Horizontal"> <StackPanel Grid.Row="2" Orientation="Horizontal">
@ -198,16 +178,16 @@
<Border Grid.Row="4" Margin="6,0,0,0" BorderBrush="{StaticResource Brush.BG4}" BorderThickness="1"> <Border Grid.Row="4" Margin="6,0,0,0" BorderBrush="{StaticResource Brush.BG4}" BorderThickness="1">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<TextBlock FontSize="10pt" <TextBlock FontSize="10pt"
FontFamily="Consolas" FontFamily="Consolas"
Padding="8" Padding="8"
Opacity="0.8" Opacity="0.8"
Background="{StaticResource Brush.BG2}" Background="{StaticResource Brush.BG2}"
Foreground="{StaticResource Brush.FG}" Foreground="{StaticResource Brush.FG}"
x:Name="readme"/> x:Name="readme"/>
</ScrollViewer> </ScrollViewer>
</Border> </Border>
</Grid> </Grid>
<!-- Mask --> <!-- Mask -->
<Border x:Name="briefMask" Background="{StaticResource Brush.BG3}" IsHitTestVisible="False"> <Border x:Name="briefMask" Background="{StaticResource Brush.BG3}" IsHitTestVisible="False">
<StackPanel Orientation="Vertical" VerticalAlignment="Center" Opacity=".2"> <StackPanel Orientation="Vertical" VerticalAlignment="Center" Opacity=".2">
@ -217,8 +197,8 @@
</Border> </Border>
</Grid> </Grid>
</Grid> </Grid>
<!-- Popups --> <!-- Popup -->
<local:PopupManager Grid.Row="1"/> <local:PopupManager x:Name="popupManager"/>
</Grid> </Grid>
</UserControl> </UserControl>

View file

@ -33,11 +33,6 @@ namespace SourceGit.UI {
/// Constructor. /// Constructor.
/// </summary> /// </summary>
public Manager() { public Manager() {
Loaded += async (o, e) => {
await Task.Delay(500);
GC.Collect();
};
InitializeComponent(); InitializeComponent();
UpdateRecentOpened(); UpdateRecentOpened();
UpdateTree(); UpdateTree();

View file

@ -53,7 +53,8 @@ namespace SourceGit.UI {
/// <param name="source"></param> /// <param name="source"></param>
/// <param name="dest"></param> /// <param name="dest"></param>
public static void Show(Git.Repository opened, string source, string dest) { public static void Show(Git.Repository opened, string source, string dest) {
PopupManager.Show(new Merge(opened, source, dest)); var popup = App.Launcher.GetPopupManager(opened);
popup?.Show(new Merge(opened, source, dest));
} }
/// <summary> /// <summary>
@ -64,13 +65,14 @@ namespace SourceGit.UI {
/// <param name="dest"></param> /// <param name="dest"></param>
public static void StartDirectly(Git.Repository opened, string source, string dest) { public static void StartDirectly(Git.Repository opened, string source, string dest) {
var merge = new Merge(opened, source, dest); var merge = new Merge(opened, source, dest);
PopupManager.Show(merge); var popup = App.Launcher.GetPopupManager(opened);
PopupManager.Lock(); popup?.Show(merge);
popup?.Lock();
Task.Run(() => { Task.Run(() => {
opened.Merge(source, ""); opened.Merge(source, "");
merge.Dispatcher.Invoke(() => { merge.Dispatcher.Invoke(() => {
PopupManager.Close(true); popup?.Close(true);
}); });
}); });
} }
@ -81,13 +83,14 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private async void Start(object sender, RoutedEventArgs e) { private async void Start(object sender, RoutedEventArgs e) {
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
var branch = sourceBranch.Content as string; var branch = sourceBranch.Content as string;
var opt = combOptions.SelectedItem as Option; var opt = combOptions.SelectedItem as Option;
await Task.Run(() => repo.Merge(branch, opt.Arg)); await Task.Run(() => repo.Merge(branch, opt.Arg));
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -96,7 +99,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -10,14 +10,12 @@ namespace SourceGit.UI {
/// Common popup manager. /// Common popup manager.
/// </summary> /// </summary>
public partial class PopupManager : UserControl { public partial class PopupManager : UserControl {
private static PopupManager instance = null; private bool locked = false;
private static bool locked = false;
/// <summary> /// <summary>
/// Constructor. /// Constructor.
/// </summary> /// </summary>
public PopupManager() { public PopupManager() {
instance = this;
InitializeComponent(); InitializeComponent();
} }
@ -25,8 +23,8 @@ namespace SourceGit.UI {
/// Show content as popup. /// Show content as popup.
/// </summary> /// </summary>
/// <param name="elem"></param> /// <param name="elem"></param>
public static void Show(UIElement elem) { public void Show(UIElement elem) {
if (instance == null || locked) return; if (locked) return;
var gone = new Thickness(0, -(double)elem.GetValue(HeightProperty) - 16, 0, 0); var gone = new Thickness(0, -(double)elem.GetValue(HeightProperty) - 16, 0, 0);
@ -35,53 +33,49 @@ namespace SourceGit.UI {
anim.From = gone; anim.From = gone;
anim.To = new Thickness(0); anim.To = new Thickness(0);
instance.statusMsg.Content = ""; statusMsg.Content = "";
instance.popupContent.Child = elem; popupContent.Child = elem;
instance.popupContent.Margin = gone; popupContent.Margin = gone;
instance.Visibility = Visibility.Visible; Visibility = Visibility.Visible;
instance.popupContent.BeginAnimation(MarginProperty, anim); popupContent.BeginAnimation(MarginProperty, anim);
} }
/// <summary> /// <summary>
/// Is current locked. /// Is current locked.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static bool IsLocked() { public bool IsLocked() {
return locked; return locked;
} }
/// <summary> /// <summary>
/// Lock /// Lock
/// </summary> /// </summary>
public static void Lock() { public void Lock() {
if (instance == null) return;
locked = true; locked = true;
status.Visibility = Visibility.Visible;
instance.status.Visibility = Visibility.Visible;
DoubleAnimation anim = new DoubleAnimation(0, 360, TimeSpan.FromSeconds(1)); DoubleAnimation anim = new DoubleAnimation(0, 360, TimeSpan.FromSeconds(1));
anim.RepeatBehavior = RepeatBehavior.Forever; anim.RepeatBehavior = RepeatBehavior.Forever;
instance.statusIcon.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, anim); statusIcon.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, anim);
} }
/// <summary> /// <summary>
/// Unlock /// Unlock
/// </summary> /// </summary>
public static void Unlock() { public void Unlock() {
if (instance == null) return;
locked = false; locked = false;
instance.statusIcon.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, null); statusIcon.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, null);
instance.status.Visibility = Visibility.Collapsed; status.Visibility = Visibility.Collapsed;
} }
/// <summary> /// <summary>
/// Update status description /// Update status description
/// </summary> /// </summary>
/// <param name="desc"></param> /// <param name="desc"></param>
public static void UpdateStatus(string desc) { public void UpdateStatus(string desc) {
if (instance == null) return; Dispatcher.Invoke(() => {
statusMsg.Content = desc;
instance.Dispatcher.Invoke(() => {
instance.statusMsg.Content = desc;
}); });
} }
@ -89,23 +83,23 @@ namespace SourceGit.UI {
/// Close current popup. /// Close current popup.
/// </summary> /// </summary>
/// <param name="unlockFirst"></param> /// <param name="unlockFirst"></param>
public static void Close(bool unlockFirst = false) { public void Close(bool unlockFirst = false) {
if (instance == null) return; if (popupContent.Child == null) return;
if (instance.popupContent.Child == null) return;
if (locked && !unlockFirst) return; if (locked && !unlockFirst) return;
locked = false; locked = false;
ThicknessAnimation anim = new ThicknessAnimation(); ThicknessAnimation anim = new ThicknessAnimation();
anim.Duration = TimeSpan.FromMilliseconds(150); anim.Duration = TimeSpan.FromMilliseconds(150);
anim.From = new Thickness(0); anim.From = new Thickness(0);
anim.To = new Thickness(0, -(double)instance.popupContent.Child.GetValue(HeightProperty) - 16, 0, 0); anim.To = new Thickness(0, -(double)popupContent.Child.GetValue(HeightProperty) - 16, 0, 0);
anim.Completed += (obj, ev) => { anim.Completed += (obj, ev) => {
instance.Visibility = Visibility.Collapsed; Visibility = Visibility.Collapsed;
instance.popupContent.Child = null; popupContent.Child = null;
}; };
instance.popupContent.BeginAnimation(MarginProperty, anim);
instance.statusIcon.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, null); popupContent.BeginAnimation(MarginProperty, anim);
instance.status.Visibility = Visibility.Collapsed; statusIcon.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, null);
status.Visibility = Visibility.Collapsed;
} }
/// <summary> /// <summary>

View file

@ -1,4 +1,4 @@
<UserControl x:Class="SourceGit.UI.Preference" <Window x:Class="SourceGit.UI.Preference"
x:Name="me" x:Name="me"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@ -8,141 +8,182 @@
xmlns:app="clr-namespace:SourceGit" xmlns:app="clr-namespace:SourceGit"
xmlns:git="clr-namespace:SourceGit.Git" xmlns:git="clr-namespace:SourceGit.Git"
mc:Ignorable="d" mc:Ignorable="d"
Height="500" Width="500"> Height="520" Width="500"
<Grid> Title="Preference"
<Grid.RowDefinitions> WindowStartupLocation="CenterOwner" ResizeMode="NoResize">
<RowDefinition Height="36"/>
<RowDefinition Height="28"/>
<RowDefinition Height="18"/>
<RowDefinition Height="36"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="18"/>
<RowDefinition Height="36"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="18"/>
<RowDefinition Height="36"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="18"/>
<RowDefinition Height="32"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions> <!-- Enable WindowChrome Feature -->
<ColumnDefinition Width="120"/> <WindowChrome.WindowChrome>
<ColumnDefinition MinWidth="200" Width="*"/> <WindowChrome UseAeroCaptionButtons="False" CornerRadius="0" CaptionHeight="32"/>
</Grid.ColumnDefinitions> </WindowChrome.WindowChrome>
<!-- 显示 -->
<Label Grid.Row="0" Grid.ColumnSpan="2" Content="APPEARANCE" FontSize="16" FontWeight="DemiBold" Opacity=".85"/>
<Label Grid.Row="1" Grid.Column="0" Content="Light Theme :" HorizontalAlignment="Right"/>
<CheckBox
Grid.Row="1"
Grid.Column="1"
IsChecked="{Binding Source={x:Static app:App.Preference}, Path=UIUseLightTheme, Mode=TwoWay}"
Content="Restart required"
TextElement.FontStyle="Italic"/>
<!-- GIT相关配置 --> <!-- Window Layout -->
<Label Grid.Row="3" Grid.ColumnSpan="2" Content="GIT INSTANCE" FontSize="16" FontWeight="DemiBold" Opacity=".85"/> <Border Background="{StaticResource Brush.BG1}">
<Label Grid.Row="4" Grid.Column="0" Content="Install Path :" HorizontalAlignment="Right"/> <Grid>
<Grid Grid.Row="4" Grid.Column="1"> <Grid.RowDefinitions>
<Grid.ColumnDefinitions> <RowDefinition Height="32"/>
<ColumnDefinition Width="*"/> <RowDefinition Height="*"/>
<ColumnDefinition Width="28"/> </Grid.RowDefinitions>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" <!-- Titlebar -->
x:Name="txtGitPath" <Grid Grid.Row="0" Background="{StaticResource Brush.BG4}">
Height="24" <Grid.ColumnDefinitions>
Text="{Binding Source={x:Static app:App.Preference}, Path=GitExecutable, Mode=TwoWay}" <ColumnDefinition Width="Auto"/>
helpers:TextBoxHelper.Placeholder="Input path for git.exe"/> <ColumnDefinition Width="Auto"/>
<Button Grid.Column="1" Width="24" Height="24" Click="SelectGitPath" Padding="0" BorderThickness="1" Style="{StaticResource Style.Button.Bordered}"> <ColumnDefinition Width="*"/>
<Path Width="14" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Folder}"/> <ColumnDefinition Width="Auto"/>
</Button> </Grid.ColumnDefinitions>
<!-- LOGO -->
<Path Width="20" Height="20" Margin="6,-1,2,0" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Git}" Fill="#FFF05133"/>
<!-- Title -->
<Label Grid.Column="1" Content="Preference" FontWeight="Light"/>
<!-- Close Button -->
<Button Click="Close" Width="32" Grid.Column="3" WindowChrome.IsHitTestVisibleInChrome="True">
<Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource Style.Button.HighlightHover}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<Path Width="10" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Close}"/>
</Button>
</Grid>
<!-- Content -->
<Grid Grid.Row="1" Margin="16,8">
<Grid.RowDefinitions>
<RowDefinition Height="36"/>
<RowDefinition Height="28"/>
<RowDefinition Height="18"/>
<RowDefinition Height="36"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="18"/>
<RowDefinition Height="36"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="18"/>
<RowDefinition Height="36"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition MinWidth="200" Width="*"/>
</Grid.ColumnDefinitions>
<!-- 显示 -->
<Label Grid.Row="0" Grid.ColumnSpan="2" Content="APPEARANCE" FontSize="16" FontWeight="DemiBold" Opacity=".85"/>
<Label Grid.Row="1" Grid.Column="0" Content="Light Theme :" HorizontalAlignment="Right"/>
<CheckBox
Grid.Row="1"
Grid.Column="1"
IsChecked="{Binding Source={x:Static app:App.Preference}, Path=UIUseLightTheme, Mode=TwoWay}"
Content="Restart required"
TextElement.FontStyle="Italic"/>
<!-- GIT相关配置 -->
<Label Grid.Row="3" Grid.ColumnSpan="2" Content="GIT INSTANCE" FontSize="16" FontWeight="DemiBold" Opacity=".85"/>
<Label Grid.Row="4" Grid.Column="0" Content="Install Path :" HorizontalAlignment="Right"/>
<Grid Grid.Row="4" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="28"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
x:Name="txtGitPath"
Height="24"
Text="{Binding Source={x:Static app:App.Preference}, Path=GitExecutable, Mode=TwoWay}"
helpers:TextBoxHelper.Placeholder="Input path for git.exe"/>
<Button Grid.Column="1" Width="24" Height="24" Click="SelectGitPath" Padding="0" BorderThickness="1" Style="{StaticResource Style.Button.Bordered}">
<Path Width="14" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Folder}"/>
</Button>
</Grid>
<Label Grid.Row="5" Grid.Column="0" Content="Default Clone Dir :" HorizontalAlignment="Right"/>
<Grid Grid.Row="5" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="28"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
x:Name="txtGitCloneDir"
Height="24"
Text="{Binding Source={x:Static app:App.Preference}, Path=GitDefaultCloneDir, Mode=TwoWay}"
helpers:TextBoxHelper.Placeholder="Default path to clone repo into"/>
<Button Grid.Column="1" Width="24" Height="24" Click="SelectDefaultClonePath" Padding="0" BorderThickness="1" Style="{StaticResource Style.Button.Bordered}">
<Path Width="14" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Folder}"/>
</Button>
</Grid>
<!-- Global User -->
<Label Grid.Row="7" Grid.ColumnSpan="2" Content="GLOBAL SETTING" FontSize="16" FontWeight="DemiBold" Opacity=".85"/>
<Label Grid.Row="8" Grid.Column="0" Content="Name :" HorizontalAlignment="Right"/>
<TextBox Grid.Row="8" Grid.Column="1" Height="24" helpers:TextBoxHelper.Placeholder="Global git user name" Text="{Binding ElementName=me, Path=GlobalUser, Mode=TwoWay}"/>
<Label Grid.Row="9" Grid.Column="0" Content="Email :" HorizontalAlignment="Right"/>
<TextBox Grid.Row="9" Grid.Column="1" Height="24" helpers:TextBoxHelper.Placeholder="Global git user email" Text="{Binding ElementName=me, Path=GlobalUserEmail, Mode=TwoWay}"/>
<Label Grid.Row="10" Grid.Column="0" Content="Auto CRLF :" HorizontalAlignment="Right"/>
<ComboBox Grid.Row="10" Grid.Column="1"
x:Name="cmbAutoCRLF"
Height="24"
HorizontalAlignment="Stretch"
VerticalContentAlignment="Center"
SelectionChanged="AutoCRLFSelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="20">
<Label Content="{Binding Value}" Padding="0" VerticalContentAlignment="Center"/>
<Label Content="{Binding Desc}" Foreground="{StaticResource Brush.FG2}" FontSize="10" Margin="8,0,0,0" Padding="0"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!-- 合并工具配置 -->
<Label Grid.Row="12" Grid.ColumnSpan="2" Content="MERGE TOOL" FontSize="16" FontWeight="DemiBold" Opacity=".85"/>
<Label Grid.Row="13" Grid.Column="0" Content="Merger :" HorizontalAlignment="Right"/>
<ComboBox Grid.Row="13" Grid.Column="1"
Height="24"
Padding="2,0,0,0"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
SelectedIndex="{Binding Source={x:Static app:App.Preference}, Path=MergeTool, Mode=TwoWay}"
ItemsSource="{Binding Source={x:Static git:MergeTool.Supported}}"
DisplayMemberPath="Name"
SelectionChanged="ChangeMergeTool"/>
<Label Grid.Row="14" Grid.Column="0" Content="Install Path :" HorizontalAlignment="Right"/>
<Grid Grid.Row="14" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="28"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
x:Name="txtMergePath"
Height="24"
Text="{Binding Source={x:Static app:App.Preference}, Path=MergeExecutable, Mode=TwoWay}"
helpers:TextBoxHelper.Placeholder="Input path for merge tool"/>
<Button Grid.Column="1" Width="24" Height="24" Click="SelectMergeToolPath" Padding="0" BorderThickness="1" Style="{StaticResource Style.Button.Bordered}">
<Path Width="14" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Folder}"/>
</Button>
</Grid>
<Label Grid.Row="15" Grid.Column="0" Content="Command :" HorizontalAlignment="Right"/>
<TextBlock Grid.Row="15" Grid.Column="1"
x:Name="txtMergeParam"
VerticalAlignment="Center"
Foreground="{StaticResource Brush.FG2}"/>
</Grid>
</Grid> </Grid>
<Label Grid.Row="5" Grid.Column="0" Content="Default Clone Dir :" HorizontalAlignment="Right"/> </Border>
<Grid Grid.Row="5" Grid.Column="1"> </Window>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="28"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
x:Name="txtGitCloneDir"
Height="24"
Text="{Binding Source={x:Static app:App.Preference}, Path=GitDefaultCloneDir, Mode=TwoWay}"
helpers:TextBoxHelper.Placeholder="Default path to clone repo into"/>
<Button Grid.Column="1" Width="24" Height="24" Click="SelectDefaultClonePath" Padding="0" BorderThickness="1" Style="{StaticResource Style.Button.Bordered}">
<Path Width="14" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Folder}"/>
</Button>
</Grid>
<!-- Global User -->
<Label Grid.Row="7" Grid.ColumnSpan="2" Content="GLOBAL SETTING" FontSize="16" FontWeight="DemiBold" Opacity=".85"/>
<Label Grid.Row="8" Grid.Column="0" Content="Name :" HorizontalAlignment="Right"/>
<TextBox Grid.Row="8" Grid.Column="1" Height="24" helpers:TextBoxHelper.Placeholder="Global git user name" Text="{Binding ElementName=me, Path=GlobalUser, Mode=TwoWay}"/>
<Label Grid.Row="9" Grid.Column="0" Content="Email :" HorizontalAlignment="Right"/>
<TextBox Grid.Row="9" Grid.Column="1" Height="24" helpers:TextBoxHelper.Placeholder="Global git user email" Text="{Binding ElementName=me, Path=GlobalUserEmail, Mode=TwoWay}"/>
<Label Grid.Row="10" Grid.Column="0" Content="Auto CRLF :" HorizontalAlignment="Right"/>
<ComboBox Grid.Row="10" Grid.Column="1"
x:Name="cmbAutoCRLF"
Height="24"
HorizontalAlignment="Stretch"
VerticalContentAlignment="Center"
SelectionChanged="AutoCRLFSelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="20">
<Label Content="{Binding Value}" Padding="0" VerticalContentAlignment="Center"/>
<Label Content="{Binding Desc}" Foreground="{StaticResource Brush.FG2}" FontSize="10" Margin="8,0,0,0" Padding="0"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!-- 合并工具配置 -->
<Label Grid.Row="12" Grid.ColumnSpan="2" Content="MERGE TOOL" FontSize="16" FontWeight="DemiBold" Opacity=".85"/>
<Label Grid.Row="13" Grid.Column="0" Content="Merger :" HorizontalAlignment="Right"/>
<ComboBox Grid.Row="13" Grid.Column="1"
Height="24"
Padding="2,0,0,0"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
SelectedIndex="{Binding Source={x:Static app:App.Preference}, Path=MergeTool, Mode=TwoWay}"
ItemsSource="{Binding Source={x:Static git:MergeTool.Supported}}"
DisplayMemberPath="Name"
SelectionChanged="ChangeMergeTool"/>
<Label Grid.Row="14" Grid.Column="0" Content="Install Path :" HorizontalAlignment="Right"/>
<Grid Grid.Row="14" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="28"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
x:Name="txtMergePath"
Height="24"
Text="{Binding Source={x:Static app:App.Preference}, Path=MergeExecutable, Mode=TwoWay}"
helpers:TextBoxHelper.Placeholder="Input path for merge tool"/>
<Button Grid.Column="1" Width="24" Height="24" Click="SelectMergeToolPath" Padding="0" BorderThickness="1" Style="{StaticResource Style.Button.Bordered}">
<Path Width="14" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Folder}"/>
</Button>
</Grid>
<Label Grid.Row="15" Grid.Column="0" Content="Command :" HorizontalAlignment="Right"/>
<TextBlock Grid.Row="15" Grid.Column="1"
x:Name="txtMergeParam"
VerticalAlignment="Center"
Foreground="{StaticResource Brush.FG2}"/>
<Button Grid.Row="17" Grid.Column="1"
Content="CLOSE"
Click="Close"
Width="80"
Style="{StaticResource Style.Button.AccentBordered}"
HorizontalAlignment="Right"/>
</Grid>
</UserControl>

View file

@ -11,7 +11,7 @@ namespace SourceGit.UI {
/// <summary> /// <summary>
/// Preference window. /// Preference window.
/// </summary> /// </summary>
public partial class Preference : UserControl { public partial class Preference : Window {
/// <summary> /// <summary>
/// Git global user name. /// Git global user name.
@ -75,13 +75,6 @@ namespace SourceGit.UI {
cmbAutoCRLF.SelectedItem = crlfOptions.Find(o => o.Value == AutoCRLF); cmbAutoCRLF.SelectedItem = crlfOptions.Find(o => o.Value == AutoCRLF);
} }
/// <summary>
/// Show preference.
/// </summary>
public static void Show() {
PopupManager.Show(new Preference());
}
/// <summary> /// <summary>
/// Close this dialog /// Close this dialog
/// </summary> /// </summary>
@ -95,7 +88,7 @@ namespace SourceGit.UI {
var oldAutoCRLF = GetConfig("core.autocrlf"); var oldAutoCRLF = GetConfig("core.autocrlf");
if (oldAutoCRLF != AutoCRLF) SetConfig("core.autocrlf", AutoCRLF); if (oldAutoCRLF != AutoCRLF) SetConfig("core.autocrlf", AutoCRLF);
PopupManager.Close(); Close();
} }
/// <summary> /// <summary>

View file

@ -30,7 +30,8 @@ namespace SourceGit.UI {
/// <param name="opened">Opened repository</param> /// <param name="opened">Opened repository</param>
/// <param name="preferRemoteBranch">Prefered remote branch</param> /// <param name="preferRemoteBranch">Prefered remote branch</param>
public static void Show(Git.Repository opened, string preferRemoteBranch = null) { public static void Show(Git.Repository opened, string preferRemoteBranch = null) {
PopupManager.Show(new Pull(opened, preferRemoteBranch)); var popup = App.Launcher.GetPopupManager(opened);
popup?.Show(new Pull(opened, preferRemoteBranch));
} }
/// <summary> /// <summary>
@ -76,9 +77,10 @@ namespace SourceGit.UI {
if (remote == null || branch == null) return; if (remote == null || branch == null) return;
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
await Task.Run(() => repo.Pull(remote, branch.Substring(branch.IndexOf('/')+1), PopupManager.UpdateStatus, rebase, autoStash)); popup?.Lock();
PopupManager.Close(true); await Task.Run(() => repo.Pull(remote, branch.Substring(branch.IndexOf('/')+1), msg => popup?.UpdateStatus(msg), rebase, autoStash));
popup?.Close(true);
} }
/// <summary> /// <summary>
@ -87,7 +89,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
/// <summary> /// <summary>

View file

@ -29,7 +29,8 @@ namespace SourceGit.UI {
/// <param name="repo"></param> /// <param name="repo"></param>
/// <param name="prefer"></param> /// <param name="prefer"></param>
public static void Show(Git.Repository repo, Git.Branch prefer = null) { public static void Show(Git.Repository repo, Git.Branch prefer = null) {
PopupManager.Show(new Push(repo, prefer)); var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(new Push(repo, prefer));
} }
/// <summary> /// <summary>
@ -44,8 +45,9 @@ namespace SourceGit.UI {
} }
var push = new Push(repo, current); var push = new Push(repo, current);
PopupManager.Show(push); var popup = App.Launcher.GetPopupManager(repo);
PopupManager.Lock(); popup?.Show(push);
popup?.Lock();
var upstream = current.Upstream.Substring(13); var upstream = current.Upstream.Substring(13);
var remoteIdx = upstream.IndexOf('/'); var remoteIdx = upstream.IndexOf('/');
@ -53,9 +55,9 @@ namespace SourceGit.UI {
var remoteBranch = upstream.Substring(remoteIdx + 1); var remoteBranch = upstream.Substring(remoteIdx + 1);
Task.Run(() => { Task.Run(() => {
repo.Push(remote, current.Name, remoteBranch, PopupManager.UpdateStatus); repo.Push(remote, current.Name, remoteBranch, msg => popup?.UpdateStatus(msg));
push.Dispatcher.Invoke(() => { push.Dispatcher.Invoke(() => {
PopupManager.Close(true); popup?.Close(true);
}); });
}); });
} }
@ -96,9 +98,10 @@ namespace SourceGit.UI {
remoteBranch = remoteBranch.Substring(0, remoteBranch.Length - 6); remoteBranch = remoteBranch.Substring(0, remoteBranch.Length - 6);
} }
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
await Task.Run(() => repo.Push(remote, localBranch.Name, remoteBranch, PopupManager.UpdateStatus, tags, track, force)); popup?.Lock();
PopupManager.Close(true); await Task.Run(() => repo.Push(remote, localBranch.Name, remoteBranch, msg => popup?.UpdateStatus(msg), tags, track, force));
popup?.Close(true);
} }
/// <summary> /// <summary>
@ -107,7 +110,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
/// <summary> /// <summary>

View file

@ -32,7 +32,8 @@ namespace SourceGit.UI {
/// <param name="repo"></param> /// <param name="repo"></param>
/// <param name="tag"></param> /// <param name="tag"></param>
public static void Show(Git.Repository repo, Git.Tag tag) { public static void Show(Git.Repository repo, Git.Tag tag) {
PopupManager.Show(new PushTag(repo, tag)); var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(new PushTag(repo, tag));
} }
/// <summary> /// <summary>
@ -44,9 +45,10 @@ namespace SourceGit.UI {
var remote = combRemotes.SelectedItem as Git.Remote; var remote = combRemotes.SelectedItem as Git.Remote;
if (remote == null) return; if (remote == null) return;
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => Git.Tag.Push(repo, tag.Name, remote.Name)); await Task.Run(() => Git.Tag.Push(repo, tag.Name, remote.Name));
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -55,7 +57,8 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Close();
} }
} }
} }

View file

@ -37,7 +37,9 @@ namespace SourceGit.UI {
dialog.branch.Content = current.Name; dialog.branch.Content = current.Name;
dialog.type.Data = dialog.FindResource("Icon.Branch") as Geometry; dialog.type.Data = dialog.FindResource("Icon.Branch") as Geometry;
dialog.desc.Content = branch.Name; dialog.desc.Content = branch.Name;
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(opened);
popup?.Show(dialog);
} }
/// <summary> /// <summary>
@ -54,7 +56,9 @@ namespace SourceGit.UI {
dialog.branch.Content = current.Name; dialog.branch.Content = current.Name;
dialog.type.Data = dialog.FindResource("Icon.Commit") as Geometry; dialog.type.Data = dialog.FindResource("Icon.Commit") as Geometry;
dialog.desc.Content = $"{commit.ShortSHA} {commit.Subject}"; dialog.desc.Content = $"{commit.ShortSHA} {commit.Subject}";
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(opened);
popup?.Show(dialog);
} }
/// <summary> /// <summary>
@ -63,16 +67,17 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private async void Start(object sender, RoutedEventArgs e) { private async void Start(object sender, RoutedEventArgs e) {
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
var autoStash = chkAutoStash.IsChecked == true; var autoStash = chkAutoStash.IsChecked == true;
await Task.Run(() => repo.Rebase(based, autoStash)); await Task.Run(() => repo.Rebase(based, autoStash));
PopupManager.Close(true); popup?.Close(true);
} }
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -44,7 +44,7 @@ namespace SourceGit.UI {
/// <param name="opened"></param> /// <param name="opened"></param>
/// <param name="editing"></param> /// <param name="editing"></param>
public static void Show(Git.Repository opened, Git.Remote editing = null) { public static void Show(Git.Repository opened, Git.Remote editing = null) {
PopupManager.Show(new Remote(opened, editing)); App.Launcher.GetPopupManager(opened)?.Show(new Remote(opened, editing));
} }
/// <summary> /// <summary>
@ -59,7 +59,8 @@ namespace SourceGit.UI {
txtUrl.GetBindingExpression(TextBox.TextProperty).UpdateSource(); txtUrl.GetBindingExpression(TextBox.TextProperty).UpdateSource();
if (Validation.GetHasError(txtUrl)) return; if (Validation.GetHasError(txtUrl)) return;
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => { await Task.Run(() => {
if (remote != null) { if (remote != null) {
@ -69,7 +70,7 @@ namespace SourceGit.UI {
} }
}); });
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -78,7 +79,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -38,7 +38,7 @@ namespace SourceGit.UI {
/// <param name="opened"></param> /// <param name="opened"></param>
/// <param name="branch"></param> /// <param name="branch"></param>
public static void Show(Git.Repository opened, Git.Branch branch) { public static void Show(Git.Repository opened, Git.Branch branch) {
PopupManager.Show(new RenameBranch(opened, branch)); App.Launcher.GetPopupManager(opened)?.Show(new RenameBranch(opened, branch));
} }
/// <summary> /// <summary>
@ -50,9 +50,10 @@ namespace SourceGit.UI {
txtNewName.GetBindingExpression(TextBox.TextProperty).UpdateSource(); txtNewName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
if (Validation.GetHasError(txtNewName)) return; if (Validation.GetHasError(txtNewName)) return;
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => branch.Rename(repo, NewName)); await Task.Run(() => branch.Rename(repo, NewName));
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -61,7 +62,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -59,7 +59,7 @@ namespace SourceGit.UI {
var current = repo.CurrentBranch(); var current = repo.CurrentBranch();
if (current == null) return; if (current == null) return;
PopupManager.Show(new Reset(repo, current, commit)); App.Launcher.GetPopupManager(repo)?.Show(new Reset(repo, current, commit));
} }
/// <summary> /// <summary>
@ -71,9 +71,10 @@ namespace SourceGit.UI {
var mode = combMode.SelectedItem as Mode; var mode = combMode.SelectedItem as Mode;
if (mode == null) return; if (mode == null) return;
PopupManager.Lock(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => repo.Reset(revision, mode.Arg)); await Task.Run(() => repo.Reset(revision, mode.Arg));
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -82,7 +83,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -30,7 +30,8 @@ namespace SourceGit.UI {
/// <param name="repo"></param> /// <param name="repo"></param>
/// <param name="commit"></param> /// <param name="commit"></param>
public static void Show(Git.Repository repo, Git.Commit commit) { public static void Show(Git.Repository repo, Git.Commit commit) {
PopupManager.Show(new Revert(repo, commit)); var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(new Revert(repo, commit));
} }
/// <summary> /// <summary>
@ -40,10 +41,10 @@ namespace SourceGit.UI {
/// <param name="e"></param> /// <param name="e"></param>
private async void Sure(object sender, RoutedEventArgs e) { private async void Sure(object sender, RoutedEventArgs e) {
bool autoCommit = chkCommit.IsChecked == true; bool autoCommit = chkCommit.IsChecked == true;
var popup = App.Launcher.GetPopupManager(repo);
PopupManager.Lock(); popup?.Lock();
await Task.Run(() => repo.Revert(sha, autoCommit)); await Task.Run(() => repo.Revert(sha, autoCommit));
PopupManager.Close(true); popup?.Close(true);
} }
/// <summary> /// <summary>
@ -52,7 +53,8 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); var popup = App.Launcher.GetPopupManager(repo);
popup?.Close();
} }
} }
} }

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
@ -28,7 +28,8 @@ namespace SourceGit.UI {
/// <param name="repo">Opened repository</param> /// <param name="repo">Opened repository</param>
/// <param name="files">Special files to stash</param> /// <param name="files">Special files to stash</param>
public static void Show(Git.Repository repo, List<string> files) { public static void Show(Git.Repository repo, List<string> files) {
PopupManager.Show(new Stash(repo, files)); var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(new Stash(repo, files));
} }
/// <summary> /// <summary>
@ -41,7 +42,7 @@ namespace SourceGit.UI {
string message = txtName.Text; string message = txtName.Text;
Git.Stash.Push(repo, includeUntracked, message, files); Git.Stash.Push(repo, includeUntracked, message, files);
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
/// <summary> /// <summary>
@ -50,7 +51,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) { private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close(); App.Launcher.GetPopupManager(repo)?.Close();
} }
} }
} }

View file

@ -19,15 +19,18 @@ namespace SourceGit.UI {
/// <summary> /// <summary>
/// Show this dialog. /// Show this dialog.
/// </summary> /// </summary>
/// <param name="repo"></param>
/// <param name="job"></param> /// <param name="job"></param>
public static void Show(Action job) { public static void Show(Git.Repository repo, Action job) {
var dialog = new Waiting(); var dialog = new Waiting();
PopupManager.Show(dialog); var popup = App.Launcher.GetPopupManager(repo);
PopupManager.Lock();
popup?.Show(dialog);
popup?.Lock();
Task.Run(() => { Task.Run(() => {
job.Invoke(); job.Invoke();
dialog.Dispatcher.Invoke(() => { dialog.Dispatcher.Invoke(() => {
PopupManager.Close(true); popup?.Close(true);
}); });
}); });
} }