sourcegit/src/Views/Widgets/Welcome.xaml.cs

289 lines
10 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Linq;
namespace SourceGit.Views.Widgets {
/// <summary>
/// 新标签页
/// </summary>
public partial class Welcome : UserControl, Controls.IPopupContainer {
/// <summary>
/// 修改仓库标签颜色的回调
/// </summary>
public event Action<Models.Repository> OnBookmarkChanged;
public Welcome() {
InitializeComponent();
UpdateVisibles();
Models.Theme.AddListener(this, UpdateVisibles);
}
#region POPUP_CONTAINER
public void Show(Controls.PopupWidget widget) {
popup.Show(widget);
}
public void ShowAndStart(Controls.PopupWidget widget) {
popup.ShowAndStart(widget);
}
public void UpdateProgress(string message) {
popup.UpdateProgress(message);
}
#endregion
#region FUNC_EVENTS
private void OnOpenClicked(object sender, RoutedEventArgs e) {
var dialog = new Controls.FolderDialog();
if (dialog.ShowDialog() == true) CheckAndOpen(dialog.SelectedPath);
}
private void OnOpenTerminalClicked(object sender, RoutedEventArgs e) {
if (MakeSureReady()) {
var bash = Path.Combine(Models.Preference.Instance.Git.Path, "..", "bash.exe");
if (!File.Exists(bash)) {
Models.Exception.Raise(App.Text("MissingBash"));
return;
}
Process.Start(new ProcessStartInfo {
FileName = bash,
UseShellExecute = true,
});
e.Handled = true;
}
}
private void OnCloneClicked(object sender, RoutedEventArgs e) {
if (MakeSureReady()) new Popups.Clone().Show();
}
2022-10-16 19:12:59 -07:00
private void FillSortMenu(ContextMenu menu, Models.Preference.SortMethod desired, string label) {
var item = new MenuItem();
item.Header = App.Text(label);
item.Click += (s, ev) => {
Models.Preference.Instance.General.SortBy = desired;
UpdateVisibles();
};
if (Models.Preference.Instance.General.SortBy == desired) {
var icon = new System.Windows.Shapes.Path();
icon.Data = FindResource("Icon.Check") as Geometry;
icon.Fill = FindResource("Brush.FG1") as Brush;
icon.Width = 12;
item.Icon = icon;
}
menu.Items.Add(item);
}
private void OnSortMethodClicked(object sender, RoutedEventArgs e) {
var menu = new ContextMenu();
menu.Placement = PlacementMode.Bottom;
menu.PlacementTarget = sender as Button;
menu.StaysOpen = false;
menu.Focusable = true;
FillSortMenu(menu, Models.Preference.SortMethod.ByNameASC, "Sort.NameAsc");
FillSortMenu(menu, Models.Preference.SortMethod.ByNameDESC, "Sort.NameDesc");
FillSortMenu(menu, Models.Preference.SortMethod.ByRecentlyOpened, "Sort.RecentlyOpened");
menu.IsOpen = true;
e.Handled = true;
}
private void OnRemoveRepository(object sender, RoutedEventArgs e) {
var repo = (sender as Button).DataContext as Models.Repository;
if (repo == null) return;
Models.Preference.Instance.RemoveRepository(repo.Path);
UpdateVisibles();
e.Handled = true;
}
private void OnOpenRepository(object sender, RoutedEventArgs e) {
var repo = (sender as Control).DataContext as Models.Repository;
if (repo == null) return;
CheckAndOpen(repo.Path);
e.Handled = true;
}
private void OnExploreRepository(object sender, RoutedEventArgs e) {
var repo = (sender as Control).DataContext as Models.Repository;
if (repo == null) return;
Process.Start("explorer", repo.Path);
e.Handled = true;
}
private void OnChangeRepositoryBookmark(object sender, RoutedEventArgs e) {
var btn = (sender as Button);
var repo = btn.DataContext as Models.Repository;
if (repo == null) return;
var menu = new ContextMenu();
menu.Placement = PlacementMode.Bottom;
menu.PlacementTarget = btn;
menu.StaysOpen = false;
menu.Focusable = true;
for (int i = 0; i < Converters.IntToBookmarkBrush.COLORS.Length; i++) {
var icon = new System.Windows.Shapes.Path();
icon.Data = new EllipseGeometry(new Point(0, 0), 8, 8);
icon.Fill = i == 0 ? (FindResource("Brush.FG1") as Brush) : Converters.IntToBookmarkBrush.COLORS[i];
icon.Width = 12;
var mark = new MenuItem();
mark.Icon = icon;
mark.Header = $"{i}";
var refIdx = i;
mark.Click += (o, ev) => {
if (repo != null) {
repo.Bookmark = refIdx;
UpdateVisibles();
OnBookmarkChanged?.Invoke(repo);
}
ev.Handled = true;
};
menu.Items.Add(mark);
}
btn.ContextMenu = menu;
btn.ContextMenu.IsOpen = true;
e.Handled = true;
}
private void OnOpenRepositoryTerminal(object sender, RoutedEventArgs e) {
var repo = (sender as Button).DataContext as Models.Repository;
if (repo == null) return;
var bash = Path.Combine(Models.Preference.Instance.Git.Path, "..", "bash.exe");
if (!File.Exists(bash)) {
Models.Exception.Raise(App.Text("MissingBash"));
return;
}
Process.Start(new ProcessStartInfo {
WorkingDirectory = repo.Path,
FileName = bash,
UseShellExecute = true,
});
}
private void OnSearchFilterChanged(object sender, TextChangedEventArgs e) {
UpdateVisibles();
}
#endregion
#region DRAG_DROP
private void OnPageDragEnter(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
dropArea.Visibility = Visibility.Visible;
}
}
private void OnPageDragLeave(object sender, DragEventArgs e) {
dropArea.Visibility = Visibility.Hidden;
}
private void OnPageDrop(object sender, DragEventArgs e) {
dropArea.Visibility = Visibility.Hidden;
}
private void OnDropFolder(object sender, DragEventArgs e) {
bool rebuild = false;
dropArea.Visibility = Visibility.Hidden;
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
if (!MakeSureReady()) return;
var paths = e.Data.GetData(DataFormats.FileDrop) as string[];
foreach (var path in paths) {
var dir = new Commands.QueryGitDir(path).Result();
if (dir != null) {
var root = new Commands.GetRepositoryRootPath(path).Result();
Models.Preference.Instance.AddRepository(root, dir);
rebuild = true;
}
}
}
if (rebuild) UpdateVisibles();
}
#endregion
#region DATA
public void UpdateVisibles() {
var visibles = new List<Models.Repository>();
var curFilter = filter.Text.ToLower();
if (string.IsNullOrEmpty(curFilter)) {
visibles.AddRange(Models.Preference.Instance.Repositories);
} else {
foreach (var repo in Models.Preference.Instance.Repositories) {
if (repo.Name.ToLower().Contains(curFilter, StringComparison.Ordinal) ||
repo.Path.ToLower().Contains(curFilter, StringComparison.Ordinal)) {
visibles.Add(repo);
}
}
}
2022-10-16 19:12:59 -07:00
switch (Models.Preference.Instance.General.SortBy) {
case Models.Preference.SortMethod.ByNameASC:
visibles.Sort((l, r) => l.Name.CompareTo(r.Name));
break;
case Models.Preference.SortMethod.ByNameDESC:
visibles.Sort((l, r) => r.Name.CompareTo(l.Name));
break;
default:
visibles.Sort((l, r) => r.LastOpenTime.CompareTo(l.LastOpenTime));
break;
}
repoList.ItemsSource = visibles;
}
private bool MakeSureReady() {
if (!Models.Preference.Instance.IsReady) {
Models.Exception.Raise(App.Text("NotConfigured"));
return false;
}
return true;
}
private void CheckAndOpen(string path) {
if (!MakeSureReady()) return;
if (!Directory.Exists(path)) {
Models.Exception.Raise(App.Text("PathNotFound", path));
return;
}
var root = new Commands.GetRepositoryRootPath(path).Result();
if (root == null) {
new Popups.Init(path).Show();
return;
}
var gitDir = new Commands.QueryGitDir(root).Result();
var repo = Models.Preference.Instance.AddRepository(root, gitDir);
Models.Watcher.Open(repo);
UpdateVisibles();
}
#endregion
}
}