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

View file

@ -16,7 +16,6 @@ namespace SourceGit.Git {
#region HOOKS
public static Action<Repository> OnOpen = null;
public static Action OnClose = null;
[XmlIgnore] public Action<string> OnNavigateCommit = null;
[XmlIgnore] public Action OnWorkingCopyChanged = null;
[XmlIgnore] public Action OnTagChanged = null;
@ -355,7 +354,7 @@ namespace SourceGit.Git {
releasePrefix = null;
hotfixPrefix = null;
OnClose?.Invoke();
GC.Collect();
}
#endregion

View file

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

View file

@ -52,7 +52,8 @@ namespace SourceGit.UI {
/// </summary>
/// <param name="opened"></param>
public static void Show(Git.Repository opened) {
PopupManager.Show(new Apply(opened));
var popup = App.Launcher.GetPopupManager(opened);
popup?.Show(new Apply(opened));
}
/// <summary>
@ -82,13 +83,14 @@ namespace SourceGit.UI {
txtPatchFile.GetBindingExpression(TextBox.TextProperty).UpdateSource();
if (Validation.GetHasError(txtPatchFile)) return;
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
var mode = combWhitespaceOptions.SelectedItem as WhitespaceOption;
var ignoreSpaceChanges = chkIgnoreWhitespace.IsChecked == true;
await Task.Run(() => repo.Apply(PatchFile, ignoreSpaceChanges, mode.Arg));
PopupManager.Close(true);
popup?.Close(true);
}
/// <summary>
@ -97,7 +99,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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;
// Move to center.
var parent = App.Current.MainWindow;
var parent = App.Launcher;
Left = parent.Left + (parent.Width - Width) * 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;
namespace SourceGit.UI {
@ -29,7 +29,8 @@ namespace SourceGit.UI {
/// <param name="repo"></param>
/// <param name="commit"></param>
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>
@ -39,7 +40,9 @@ namespace SourceGit.UI {
/// <param name="e"></param>
private void Start(object sender, RoutedEventArgs e) {
repo.CherryPick(commitSHA, chkCommitChanges.IsChecked != true);
PopupManager.Close();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Close();
}
/// <summary>
@ -48,7 +51,8 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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.
/// </summary>
public static void Show() {
PopupManager.Show(new Clone());
var popup = App.Launcher.GetPopupManager(null);
popup?.Show(new Clone());
}
/// <summary>
@ -91,16 +92,17 @@ namespace SourceGit.UI {
rName = RemoteName;
}
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(null);
popup.Lock();
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) {
PopupManager.Unlock();
popup.Unlock();
} else {
PopupManager.Close(true);
popup.Close(true);
repo.Open();
}
}
@ -111,7 +113,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close();
App.Launcher.GetPopupManager(null).Close();
}
}
}

View file

@ -43,7 +43,8 @@ namespace SourceGit.UI {
/// </summary>
/// <param name="repo"></param>
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
@ -63,7 +64,7 @@ namespace SourceGit.UI {
}
private void Close(object sender, RoutedEventArgs e) {
PopupManager.Close();
App.Launcher.GetPopupManager(repo)?.Close();
}
#endregion
}

View file

@ -58,7 +58,9 @@ namespace SourceGit.UI {
dialog.basedOnDesc.Content = branch.Name;
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>
@ -71,7 +73,9 @@ namespace SourceGit.UI {
dialog.based = tag.Name;
dialog.basedOnType.Data = dialog.FindResource("Icon.Tag") as Geometry;
dialog.basedOnDesc.Content = tag.Name;
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(dialog);
}
/// <summary>
@ -84,7 +88,9 @@ namespace SourceGit.UI {
dialog.based = commit.SHA;
dialog.basedOnType.Data = dialog.FindResource("Icon.Commit") as Geometry;
dialog.basedOnDesc.Content = $"{commit.ShortSHA} {commit.Subject}";
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(dialog);
}
/// <summary>
@ -96,7 +102,8 @@ namespace SourceGit.UI {
txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
if (Validation.GetHasError(txtName)) return;
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
bool checkout = chkCheckout.IsChecked == true;
await Task.Run(() => {
@ -119,7 +126,7 @@ namespace SourceGit.UI {
}
});
PopupManager.Close(true);
popup?.Close(true);
}
/// <summary>
@ -128,7 +135,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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.Controls;
using System.Windows.Media;
@ -51,7 +51,9 @@ namespace SourceGit.UI {
dialog.based = branch.Head;
dialog.basedOnType.Data = dialog.FindResource("Icon.Branch") as Geometry;
dialog.basedOnDesc.Content = branch.Name;
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(dialog);
}
/// <summary>
@ -64,7 +66,9 @@ namespace SourceGit.UI {
dialog.based = commit.SHA;
dialog.basedOnType.Data = dialog.FindResource("Icon.Commit") as Geometry;
dialog.basedOnDesc.Content = $"{commit.ShortSHA} {commit.Subject}";
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(repo);
popup?.Show(dialog);
}
/// <summary>
@ -77,7 +81,9 @@ namespace SourceGit.UI {
if (Validation.GetHasError(tagName)) return;
Git.Tag.Add(repo, TagName, based, tagMessage.Text);
PopupManager.Close();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Close();
}
/// <summary>
@ -86,7 +92,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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:converters="clr-namespace:SourceGit.Converters"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Unloaded="Cleanup">
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<RoutedUICommand x:Key="OpenSearchBarCommand" Text="OpenSearchBar"/>
<RoutedUICommand x:Key="HideSearchBarCommand" Text="HideSearchBar"/>
@ -34,41 +33,19 @@
<Grid Grid.Row="0" Panel.ZIndex="9999">
<Border Background="{StaticResource Brush.BG1}">
<Border.Effect>
<DropShadowEffect ShadowDepth="2" Direction="270" Opacity=".3"/>
<DropShadowEffect ShadowDepth="2" Direction="270" Opacity=".5" Color="Black"/>
</Border.Effect>
</Border>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</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 -->
<StackPanel Grid.Column="1" Orientation="Horizontal">
<StackPanel Grid.Column="0" Orientation="Horizontal" Margin="6,0">
<Button Click="OpenFetch" Margin="4,0">
<StackPanel Orientation="Horizontal">
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Fetch}"/>
@ -87,12 +64,18 @@
<Label Content="Push"/>
</StackPanel>
</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">
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.SaveStash}"/>
<Label Content="Stash"/>
</StackPanel>
</Button>
<Rectangle Margin="4,0,8,0" Width="1" Height="20" Fill="{StaticResource Brush.Border1}"/>
<Button Click="OpenApply" Margin="4,0">
<StackPanel Orientation="Horizontal">
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Apply}"/>
@ -539,6 +522,6 @@
</Grid>
<!-- Popups -->
<local:PopupManager Grid.Row="1"/>
<local:PopupManager x:Name="popupManager" Grid.Row="1"/>
</Grid>
</UserControl>

View file

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

View file

@ -28,7 +28,8 @@ namespace SourceGit.UI {
/// <param name="opened"></param>
/// <param name="branch"></param>
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>
@ -37,9 +38,10 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
private async void Sure(object sender, RoutedEventArgs e) {
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => branch.Delete(repo));
PopupManager.Close(true);
popup?.Close(true);
}
/// <summary>
@ -48,7 +50,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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="remote"></param>
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>
@ -38,9 +39,10 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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));
PopupManager.Close(true);
popup?.Close(true);
}
/// <summary>
@ -49,7 +51,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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="tag"></param>
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>
@ -39,12 +40,13 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
private async void Start(object sender, RoutedEventArgs e) {
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
var push = chkWithRemote.IsChecked == true;
await Task.Run(() => Git.Tag.Delete(repo, tag.Name, push));
PopupManager.Close(true);
popup?.Close(true);
}
/// <summary>
@ -53,7 +55,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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="targets"></param>
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) {
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => repo.Discard(changes));
PopupManager.Close(true);
popup?.Close(true);
}
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="preferRemote"></param>
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>
@ -51,16 +52,17 @@ namespace SourceGit.UI {
private async void Start(object sender, RoutedEventArgs e) {
bool prune = chkPrune.IsChecked == true;
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
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 {
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>
@ -69,7 +71,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close();
App.Launcher.GetPopupManager(repo)?.Close();
}
}
}

View file

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

View file

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

View file

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

View file

@ -51,7 +51,8 @@ namespace SourceGit.UI {
nameValidator.Prefix = hotfixPrefix;
break;
default:
PopupManager.Close();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Close();
return;
}
}
@ -62,7 +63,8 @@ namespace SourceGit.UI {
/// <param name="repo"></param>
/// <param name="type"></param>
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>
@ -74,9 +76,10 @@ namespace SourceGit.UI {
txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
if (Validation.GetHasError(txtName)) return;
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => repo.StartGitFlowBranch(type, SubName));
PopupManager.Close(true);
popup?.Close(true);
}
/// <summary>
@ -85,7 +88,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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);
dialog.Owner = App.Current.MainWindow;
dialog.Owner = App.Launcher;
dialog.ShowDialog();
} else {
Rebase.Show(Repo, commit);

View file

@ -25,7 +25,8 @@ namespace SourceGit.UI {
/// </summary>
/// <param name="path"></param>
public static void Show(string path) {
PopupManager.Show(new Init(path));
var popup = App.Launcher.GetPopupManager(null);
popup.Show(new Init(path));
}
/// <summary>
@ -34,7 +35,8 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
private async void Sure(object sender, RoutedEventArgs e) {
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(null);
popup.Lock();
await Task.Run(() => {
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);
if (repo != null) repo.Open();
@ -57,7 +59,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:source="clr-namespace:SourceGit"
xmlns:local="clr-namespace:SourceGit.UI"
mc:Ignorable="d"
MinWidth="800" MinHeight="600"
Title="Source Git"
@ -34,22 +35,22 @@
</Style>
</Border.Style>
<Grid>
<!-- Window Content -->
<Grid Background="{StaticResource Brush.BG4}">
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Titlebar -->
<Grid Grid.Row="0" Background="{StaticResource Brush.BG4}">
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="110"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- Logo & Title -->
<StackPanel Grid.Column="0" Orientation="Horizontal">
<!-- LOGO & Title -->
<StackPanel Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" Height="32">
<Path
Width="20" Height="20" Margin="6,-1,2,0"
Style="{StaticResource Style.Icon}"
@ -60,8 +61,103 @@
<Label Content="SOURCE GIT" FontWeight="Light"/>
</StackPanel>
<!-- Commands -->
<StackPanel Grid.Column="2" Orientation="Horizontal" WindowChrome.IsHitTestVisibleInChrome="True">
<!-- Tabs -->
<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">
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Preference}"/>
</Button>
@ -105,11 +201,32 @@
</StackPanel>
</Grid>
<!-- Body -->
<ContentControl Grid.Row="1" x:Name="body"/>
<!-- Pages -->
<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 -->
<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.ItemTemplate>
<DataTemplate>

View file

@ -1,4 +1,3 @@
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
@ -11,6 +10,16 @@ namespace SourceGit.UI {
/// </summary>
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>
/// Alert data.
/// </summary>
@ -24,37 +33,82 @@ namespace SourceGit.UI {
/// </summary>
public ObservableCollection<Alert> Alerts { get; set; } = new ObservableCollection<Alert>();
/// <summary>
/// Opened tabs.
/// </summary>
public ObservableCollection<Tab> Tabs { get; set; } = new ObservableCollection<Tab>();
/// <summary>
/// Constructor
/// </summary>
public Launcher() {
Git.Repository.OnOpen = ShowDashboard;
Git.Repository.OnClose = ShowManager;
App.OnError = msg => {
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();
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
/// <summary>
/// Show manager.
/// Close repository tab.
/// </summary>
private void ShowManager() {
Dispatcher.Invoke(() => {
body.Content = new Manager();
});
}
/// <param name="sender"></param>
/// <param name="e"></param>
private void CloseRepo(object sender, RoutedEventArgs e) {
var tab = (sender as Button).DataContext as Tab;
if (tab == null || tab.Repo == null) return;
/// <summary>
/// Show dashboard.
/// </summary>
/// <param name="repo"></param>
private void ShowDashboard(Git.Repository repo) {
Dispatcher.Invoke(() => {
body.Content = new Dashboard(repo);
});
var popup = (tab.Page as Dashboard).popupManager;
if (popup.IsLocked()) popup.Close(true);
Tabs.Remove(tab);
tab.Page = null;
tab.Repo.Close();
}
/// <summary>
@ -63,7 +117,9 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
private void ShowPreference(object sender, RoutedEventArgs e) {
Preference.Show();
var dialog = new Preference();
dialog.Owner = this;
dialog.ShowDialog();
}
/// <summary>

View file

@ -9,28 +9,8 @@
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<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 -->
<Grid Grid.Row="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" MinWidth="200" MaxWidth="360"/>
<ColumnDefinition Width="2"/>
@ -38,7 +18,7 @@
</Grid.ColumnDefinitions>
<!-- Left panel -->
<Grid Grid.Column="0">
<Grid Grid.Column="0" Background="{StaticResource Brush.BG1}">
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="Auto"/>
@ -148,7 +128,7 @@
</TreeView>
</Grid>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" Background="Transparent"/>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" Background="{StaticResource Brush.BG1}"/>
<!-- Right Panel -->
<Grid Grid.Column="2" Background="{StaticResource Brush.BG3}">
@ -218,7 +198,7 @@
</Grid>
</Grid>
<!-- Popups -->
<local:PopupManager Grid.Row="1"/>
<!-- Popup -->
<local:PopupManager x:Name="popupManager"/>
</Grid>
</UserControl>

View file

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

View file

@ -53,7 +53,8 @@ namespace SourceGit.UI {
/// <param name="source"></param>
/// <param name="dest"></param>
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>
@ -64,13 +65,14 @@ namespace SourceGit.UI {
/// <param name="dest"></param>
public static void StartDirectly(Git.Repository opened, string source, string dest) {
var merge = new Merge(opened, source, dest);
PopupManager.Show(merge);
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(opened);
popup?.Show(merge);
popup?.Lock();
Task.Run(() => {
opened.Merge(source, "");
merge.Dispatcher.Invoke(() => {
PopupManager.Close(true);
popup?.Close(true);
});
});
}
@ -81,13 +83,14 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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 opt = combOptions.SelectedItem as Option;
await Task.Run(() => repo.Merge(branch, opt.Arg));
PopupManager.Close(true);
popup?.Close(true);
}
/// <summary>
@ -96,7 +99,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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.
/// </summary>
public partial class PopupManager : UserControl {
private static PopupManager instance = null;
private static bool locked = false;
private bool locked = false;
/// <summary>
/// Constructor.
/// </summary>
public PopupManager() {
instance = this;
InitializeComponent();
}
@ -25,8 +23,8 @@ namespace SourceGit.UI {
/// Show content as popup.
/// </summary>
/// <param name="elem"></param>
public static void Show(UIElement elem) {
if (instance == null || locked) return;
public void Show(UIElement elem) {
if (locked) return;
var gone = new Thickness(0, -(double)elem.GetValue(HeightProperty) - 16, 0, 0);
@ -35,53 +33,49 @@ namespace SourceGit.UI {
anim.From = gone;
anim.To = new Thickness(0);
instance.statusMsg.Content = "";
instance.popupContent.Child = elem;
instance.popupContent.Margin = gone;
instance.Visibility = Visibility.Visible;
instance.popupContent.BeginAnimation(MarginProperty, anim);
statusMsg.Content = "";
popupContent.Child = elem;
popupContent.Margin = gone;
Visibility = Visibility.Visible;
popupContent.BeginAnimation(MarginProperty, anim);
}
/// <summary>
/// Is current locked.
/// </summary>
/// <returns></returns>
public static bool IsLocked() {
public bool IsLocked() {
return locked;
}
/// <summary>
/// Lock
/// </summary>
public static void Lock() {
if (instance == null) return;
public void Lock() {
locked = true;
status.Visibility = Visibility.Visible;
instance.status.Visibility = Visibility.Visible;
DoubleAnimation anim = new DoubleAnimation(0, 360, TimeSpan.FromSeconds(1));
anim.RepeatBehavior = RepeatBehavior.Forever;
instance.statusIcon.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, anim);
statusIcon.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, anim);
}
/// <summary>
/// Unlock
/// </summary>
public static void Unlock() {
if (instance == null) return;
public void Unlock() {
locked = false;
instance.statusIcon.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, null);
instance.status.Visibility = Visibility.Collapsed;
statusIcon.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, null);
status.Visibility = Visibility.Collapsed;
}
/// <summary>
/// Update status description
/// </summary>
/// <param name="desc"></param>
public static void UpdateStatus(string desc) {
if (instance == null) return;
instance.Dispatcher.Invoke(() => {
instance.statusMsg.Content = desc;
public void UpdateStatus(string desc) {
Dispatcher.Invoke(() => {
statusMsg.Content = desc;
});
}
@ -89,23 +83,23 @@ namespace SourceGit.UI {
/// Close current popup.
/// </summary>
/// <param name="unlockFirst"></param>
public static void Close(bool unlockFirst = false) {
if (instance == null) return;
if (instance.popupContent.Child == null) return;
public void Close(bool unlockFirst = false) {
if (popupContent.Child == null) return;
if (locked && !unlockFirst) return;
locked = false;
ThicknessAnimation anim = new ThicknessAnimation();
anim.Duration = TimeSpan.FromMilliseconds(150);
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) => {
instance.Visibility = Visibility.Collapsed;
instance.popupContent.Child = null;
Visibility = Visibility.Collapsed;
popupContent.Child = null;
};
instance.popupContent.BeginAnimation(MarginProperty, anim);
instance.statusIcon.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, null);
instance.status.Visibility = Visibility.Collapsed;
popupContent.BeginAnimation(MarginProperty, anim);
statusIcon.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, null);
status.Visibility = Visibility.Collapsed;
}
/// <summary>

View file

@ -1,4 +1,4 @@
<UserControl x:Class="SourceGit.UI.Preference"
<Window x:Class="SourceGit.UI.Preference"
x:Name="me"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@ -8,8 +8,56 @@
xmlns:app="clr-namespace:SourceGit"
xmlns:git="clr-namespace:SourceGit.Git"
mc:Ignorable="d"
Height="500" Width="500">
Height="520" Width="500"
Title="Preference"
WindowStartupLocation="CenterOwner" ResizeMode="NoResize">
<!-- Enable WindowChrome Feature -->
<WindowChrome.WindowChrome>
<WindowChrome UseAeroCaptionButtons="False" CornerRadius="0" CaptionHeight="32"/>
</WindowChrome.WindowChrome>
<!-- Window Layout -->
<Border Background="{StaticResource Brush.BG1}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Titlebar -->
<Grid Grid.Row="0" Background="{StaticResource Brush.BG4}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</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"/>
@ -27,8 +75,6 @@
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="18"/>
<RowDefinition Height="32"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
@ -137,12 +183,7 @@
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>
</Grid>
</Border>
</Window>

View file

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

View file

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

View file

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

View file

@ -32,7 +32,8 @@ namespace SourceGit.UI {
/// <param name="repo"></param>
/// <param name="tag"></param>
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>
@ -44,9 +45,10 @@ namespace SourceGit.UI {
var remote = combRemotes.SelectedItem as Git.Remote;
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));
PopupManager.Close(true);
popup?.Close(true);
}
/// <summary>
@ -55,7 +57,8 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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.type.Data = dialog.FindResource("Icon.Branch") as Geometry;
dialog.desc.Content = branch.Name;
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(opened);
popup?.Show(dialog);
}
/// <summary>
@ -54,7 +56,9 @@ namespace SourceGit.UI {
dialog.branch.Content = current.Name;
dialog.type.Data = dialog.FindResource("Icon.Commit") as Geometry;
dialog.desc.Content = $"{commit.ShortSHA} {commit.Subject}";
PopupManager.Show(dialog);
var popup = App.Launcher.GetPopupManager(opened);
popup?.Show(dialog);
}
/// <summary>
@ -63,16 +67,17 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
private async void Start(object sender, RoutedEventArgs e) {
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
var autoStash = chkAutoStash.IsChecked == true;
await Task.Run(() => repo.Rebase(based, autoStash));
PopupManager.Close(true);
popup?.Close(true);
}
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="editing"></param>
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>
@ -59,7 +59,8 @@ namespace SourceGit.UI {
txtUrl.GetBindingExpression(TextBox.TextProperty).UpdateSource();
if (Validation.GetHasError(txtUrl)) return;
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => {
if (remote != null) {
@ -69,7 +70,7 @@ namespace SourceGit.UI {
}
});
PopupManager.Close(true);
popup?.Close(true);
}
/// <summary>
@ -78,7 +79,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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="branch"></param>
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>
@ -50,9 +50,10 @@ namespace SourceGit.UI {
txtNewName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
if (Validation.GetHasError(txtNewName)) return;
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => branch.Rename(repo, NewName));
PopupManager.Close(true);
popup?.Close(true);
}
/// <summary>
@ -61,7 +62,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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();
if (current == null) return;
PopupManager.Show(new Reset(repo, current, commit));
App.Launcher.GetPopupManager(repo)?.Show(new Reset(repo, current, commit));
}
/// <summary>
@ -71,9 +71,10 @@ namespace SourceGit.UI {
var mode = combMode.SelectedItem as Mode;
if (mode == null) return;
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => repo.Reset(revision, mode.Arg));
PopupManager.Close(true);
popup?.Close(true);
}
/// <summary>
@ -82,7 +83,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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="commit"></param>
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>
@ -40,10 +41,10 @@ namespace SourceGit.UI {
/// <param name="e"></param>
private async void Sure(object sender, RoutedEventArgs e) {
bool autoCommit = chkCommit.IsChecked == true;
PopupManager.Lock();
var popup = App.Launcher.GetPopupManager(repo);
popup?.Lock();
await Task.Run(() => repo.Revert(sha, autoCommit));
PopupManager.Close(true);
popup?.Close(true);
}
/// <summary>
@ -52,7 +53,8 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
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.Controls;
@ -28,7 +28,8 @@ namespace SourceGit.UI {
/// <param name="repo">Opened repository</param>
/// <param name="files">Special files to stash</param>
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>
@ -41,7 +42,7 @@ namespace SourceGit.UI {
string message = txtName.Text;
Git.Stash.Push(repo, includeUntracked, message, files);
PopupManager.Close();
App.Launcher.GetPopupManager(repo)?.Close();
}
/// <summary>
@ -50,7 +51,7 @@ namespace SourceGit.UI {
/// <param name="sender"></param>
/// <param name="e"></param>
private void Cancel(object sender, RoutedEventArgs e) {
PopupManager.Close();
App.Launcher.GetPopupManager(repo)?.Close();
}
}
}

View file

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