2024-03-17 18:37:06 -07:00
|
|
|
using System;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
2024-03-02 06:45:14 -08:00
|
|
|
using Avalonia;
|
2024-02-05 23:08:37 -08:00
|
|
|
using Avalonia.Controls;
|
|
|
|
using Avalonia.Controls.Primitives;
|
|
|
|
using Avalonia.Input;
|
|
|
|
using Avalonia.Interactivity;
|
2024-03-17 18:37:06 -07:00
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
using SourceGit.ViewModels;
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
namespace SourceGit.Views
|
|
|
|
{
|
|
|
|
public class RepositorySubView : Border
|
|
|
|
{
|
2024-03-02 06:45:14 -08:00
|
|
|
public static readonly StyledProperty<object> DataProperty =
|
|
|
|
AvaloniaProperty.Register<RepositorySubView, object>(nameof(Data), false);
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
public object Data
|
|
|
|
{
|
2024-03-02 06:45:14 -08:00
|
|
|
get => GetValue(DataProperty);
|
|
|
|
set => SetValue(DataProperty, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override Type StyleKeyOverride => typeof(Border);
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
static RepositorySubView()
|
|
|
|
{
|
|
|
|
DataProperty.Changed.AddClassHandler<RepositorySubView>((view, ev) =>
|
|
|
|
{
|
2024-03-02 06:45:14 -08:00
|
|
|
var data = view.Data;
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
if (data == null)
|
|
|
|
{
|
2024-03-02 06:45:14 -08:00
|
|
|
view.Child = null;
|
2024-03-17 18:37:06 -07:00
|
|
|
}
|
|
|
|
else if (data is ViewModels.Histories)
|
|
|
|
{
|
2024-03-02 06:45:14 -08:00
|
|
|
view.Child = new Histories { DataContext = data };
|
2024-03-17 18:37:06 -07:00
|
|
|
}
|
|
|
|
else if (data is ViewModels.WorkingCopy)
|
|
|
|
{
|
2024-03-02 06:45:14 -08:00
|
|
|
view.Child = new WorkingCopy { DataContext = data };
|
2024-03-17 18:37:06 -07:00
|
|
|
}
|
|
|
|
else if (data is ViewModels.StashesPage)
|
|
|
|
{
|
2024-03-02 06:45:14 -08:00
|
|
|
view.Child = new StashesPage { DataContext = data };
|
2024-03-17 18:37:06 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-03-02 06:45:14 -08:00
|
|
|
view.Child = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
GC.Collect();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
public partial class Repository : UserControl
|
|
|
|
{
|
|
|
|
public Repository()
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
InitializeComponent();
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnLocalBranchTreeLostFocus(object sender, RoutedEventArgs e)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
if (sender is TreeView tree) tree.UnselectAll();
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnRemoteBranchTreeLostFocus(object sender, RoutedEventArgs e)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
if (sender is TreeView tree) tree.UnselectAll();
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnTagDataGridLostFocus(object sender, RoutedEventArgs e)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
if (sender is DataGrid datagrid) datagrid.SelectedItem = null;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnLocalBranchTreeSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
|
{
|
|
|
|
if (sender is TreeView tree && tree.SelectedItem != null)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
remoteBranchTree.UnselectAll();
|
|
|
|
|
|
|
|
var node = tree.SelectedItem as Models.BranchTreeNode;
|
2024-03-17 18:37:06 -07:00
|
|
|
if (node.IsBranch && DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
repo.NavigateToCommit((node.Backend as Models.Branch).Head);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnRemoteBranchTreeSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
|
{
|
|
|
|
if (sender is TreeView tree && tree.SelectedItem != null)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
localBranchTree.UnselectAll();
|
|
|
|
|
|
|
|
var node = tree.SelectedItem as Models.BranchTreeNode;
|
2024-03-17 18:37:06 -07:00
|
|
|
if (node.IsBranch && DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
repo.NavigateToCommit((node.Backend as Models.Branch).Head);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnTagDataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
|
{
|
|
|
|
if (sender is DataGrid datagrid && datagrid.SelectedItem != null)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var tag = datagrid.SelectedItem as Models.Tag;
|
2024-03-17 18:37:06 -07:00
|
|
|
if (DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
repo.NavigateToCommit(tag.SHA);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnSearchCommitPanelPropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e)
|
|
|
|
{
|
2024-03-07 00:18:51 -08:00
|
|
|
var grid = sender as Grid;
|
2024-03-17 18:37:06 -07:00
|
|
|
if (e.Property == IsVisibleProperty && grid.IsVisible)
|
|
|
|
{
|
2024-03-07 00:18:51 -08:00
|
|
|
txtSearchCommitsBox.Focus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnSearchKeyDown(object sender, KeyEventArgs e)
|
|
|
|
{
|
|
|
|
if (e.Key == Key.Enter)
|
|
|
|
{
|
|
|
|
if (DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
repo.StartSearchCommits();
|
|
|
|
}
|
|
|
|
e.Handled = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnSearchResultDataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
|
{
|
|
|
|
if (sender is DataGrid datagrid && datagrid.SelectedItem != null)
|
|
|
|
{
|
|
|
|
if (DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var commit = datagrid.SelectedItem as Models.Commit;
|
|
|
|
repo.NavigateToCommit(commit.SHA);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e.Handled = true;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnToggleFilter(object sender, RoutedEventArgs e)
|
|
|
|
{
|
|
|
|
if (sender is ToggleButton toggle)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var filter = string.Empty;
|
2024-03-17 18:37:06 -07:00
|
|
|
if (toggle.DataContext is Models.BranchTreeNode node)
|
|
|
|
{
|
|
|
|
if (node.IsBranch)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
filter = (node.Backend as Models.Branch).FullName;
|
|
|
|
}
|
2024-03-17 18:37:06 -07:00
|
|
|
}
|
|
|
|
else if (toggle.DataContext is Models.Tag tag)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
filter = tag.Name;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
if (!string.IsNullOrEmpty(filter) && DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
repo.UpdateFilter(filter, toggle.IsChecked == true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnLocalBranchContextMenuRequested(object sender, ContextRequestedEventArgs e)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
remoteBranchTree.UnselectAll();
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
if (sender is Grid grid && grid.DataContext is Models.BranchTreeNode node)
|
|
|
|
{
|
|
|
|
if (node.IsBranch && DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var menu = repo.CreateContextMenuForLocalBranch(node.Backend as Models.Branch);
|
|
|
|
if (menu != null) menu.Open(grid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnRemoteBranchContextMenuRequested(object sender, ContextRequestedEventArgs e)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
localBranchTree.UnselectAll();
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
if (sender is Grid grid && grid.DataContext is Models.BranchTreeNode node && DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
|
|
|
if (node.IsRemote)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var menu = repo.CreateContextMenuForRemote(node.Backend as Models.Remote);
|
|
|
|
if (menu != null) menu.Open(grid);
|
2024-03-17 18:37:06 -07:00
|
|
|
}
|
|
|
|
else if (node.IsBranch)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var menu = repo.CreateContextMenuForRemoteBranch(node.Backend as Models.Branch);
|
|
|
|
if (menu != null) menu.Open(grid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnTagContextRequested(object sender, ContextRequestedEventArgs e)
|
|
|
|
{
|
|
|
|
if (sender is DataGrid datagrid && datagrid.SelectedItem != null && DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var tag = datagrid.SelectedItem as Models.Tag;
|
|
|
|
var menu = repo.CreateContextMenuForTag(tag);
|
|
|
|
if (menu != null) menu.Open(datagrid);
|
|
|
|
}
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnSubmoduleContextRequested(object sender, ContextRequestedEventArgs e)
|
|
|
|
{
|
|
|
|
if (sender is DataGrid datagrid && datagrid.SelectedItem != null && DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var submodule = datagrid.SelectedItem as string;
|
|
|
|
var menu = repo.CreateContextMenuForSubmodule(submodule);
|
|
|
|
if (menu != null) menu.Open(datagrid);
|
|
|
|
}
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OpenGitFlowMenu(object sender, RoutedEventArgs e)
|
|
|
|
{
|
|
|
|
if (DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var menu = repo.CreateContextMenuForGitFlow();
|
|
|
|
if (menu != null) menu.Open(sender as Button);
|
|
|
|
}
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private async void UpdateSubmodules(object sender, RoutedEventArgs e)
|
|
|
|
{
|
|
|
|
if (DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
repo.SetWatcherEnabled(false);
|
|
|
|
iconSubmoduleUpdate.Classes.Add("rotating");
|
|
|
|
await Task.Run(() => new Commands.Submodule(repo.FullPath).Update());
|
|
|
|
iconSubmoduleUpdate.Classes.Remove("rotating");
|
|
|
|
repo.SetWatcherEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
e.Handled = true;
|
|
|
|
}
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private void OnDoubleTappedLocalBranchNode(object sender, TappedEventArgs e)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
if (!PopupHost.CanCreatePopup()) return;
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
if (sender is Grid grid && DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var node = grid.DataContext as Models.BranchTreeNode;
|
2024-03-17 18:37:06 -07:00
|
|
|
if (node != null && node.IsBranch)
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
var branch = node.Backend as Models.Branch;
|
|
|
|
if (branch.IsCurrent) return;
|
|
|
|
|
|
|
|
PopupHost.ShowAndStartPopup(new ViewModels.Checkout(repo, branch.Name));
|
|
|
|
e.Handled = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-02-23 03:16:28 -08:00
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
private async void OpenStatistics(object sender, RoutedEventArgs e)
|
|
|
|
{
|
|
|
|
if (DataContext is ViewModels.Repository repo)
|
|
|
|
{
|
2024-02-23 03:16:28 -08:00
|
|
|
var dialog = new Statistics() { DataContext = new ViewModels.Statistics(repo.FullPath) };
|
|
|
|
await dialog.ShowDialog(TopLevel.GetTopLevel(this) as Window);
|
|
|
|
e.Handled = true;
|
|
|
|
}
|
|
|
|
}
|
2024-03-27 23:48:20 -07:00
|
|
|
|
|
|
|
private void OpenInVSCode(object sender, RoutedEventArgs e)
|
|
|
|
{
|
|
|
|
(DataContext as ViewModels.Repository).OpenInVSCode();
|
|
|
|
}
|
|
|
|
private void OpenInFleet(object sender, RoutedEventArgs e)
|
|
|
|
{
|
|
|
|
(DataContext as ViewModels.Repository).OpenInFleet();
|
|
|
|
}
|
2024-02-05 23:08:37 -08:00
|
|
|
}
|
2024-03-17 18:37:06 -07:00
|
|
|
}
|