diff --git a/src/Resources/Locales/en_US.xaml b/src/Resources/Locales/en_US.xaml index 878a6364..adc447c2 100644 --- a/src/Resources/Locales/en_US.xaml +++ b/src/Resources/Locales/en_US.xaml @@ -297,8 +297,9 @@ Merge Option : SourceGit - Open Local Repository - Clone Remote Repository + Open local repository + Open terminal + Clone remote repository DRAG-DROP YOUR FOLDER START RECENT OPENED diff --git a/src/Resources/Locales/zh_CN.xaml b/src/Resources/Locales/zh_CN.xaml index e6d8d12f..5bc498af 100644 --- a/src/Resources/Locales/zh_CN.xaml +++ b/src/Resources/Locales/zh_CN.xaml @@ -297,6 +297,7 @@ 欢迎使用本软件 打开本地仓库 + 打开GIT终端 克隆远程仓库 支持拖放操作 开始使用 diff --git a/src/Views/Widgets/Welcome.xaml b/src/Views/Widgets/Welcome.xaml index 17b162cd..2eca856f 100644 --- a/src/Views/Widgets/Welcome.xaml +++ b/src/Views/Widgets/Welcome.xaml @@ -52,16 +52,22 @@ Text="{DynamicResource Text.Welcome.Start}" FontSize="13pt"/> - - + diff --git a/src/Views/Widgets/Welcome.xaml.cs b/src/Views/Widgets/Welcome.xaml.cs index fac0fdd5..8f82f48f 100644 --- a/src/Views/Widgets/Welcome.xaml.cs +++ b/src/Views/Widgets/Welcome.xaml.cs @@ -1,329 +1,354 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Media; - -namespace SourceGit.Views.Widgets { - - /// - /// 新标签页 - /// - public partial class Welcome : UserControl, Controls.IPopupContainer { - - /// - /// 树节点数据 - /// - public class Node : Controls.BindableBase { - public string Id { get; set; } - public string ParentId { get; set; } - - private string name; - public string Name { - get => name; - set => SetProperty(ref name, value); - } - - public bool IsGroup { get; set; } - - private bool isEditing = false; - public bool IsEditing { - get => isEditing; - set => SetProperty(ref isEditing, value); - } - - public bool IsExpanded { get; set; } - - private int bookmark = 0; - public int Bookmark { - get => bookmark; - set => SetProperty(ref bookmark, value); - } - - public List Children { get; set; } - } - - /// - /// 仓库节点编辑事件参数 - /// - public event Action OnNodeEdited; - - public Welcome() { - InitializeComponent(); - UpdateTree(); - UpdateRecents(); - } - - #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 OnCloneClicked(object sender, RoutedEventArgs e) { - if (MakeSureReady()) new Popups.Clone().Show(); - } - - private void OnRecentContextMenuOpening(object sender, ContextMenuEventArgs e) { - var repo = (sender as DataGridRow).DataContext as Models.Repository; - if (repo != null) { - var remove = new MenuItem(); - remove.Header = App.Text("Welcome.Delete"); - remove.Click += (o, ev) => { - Models.Preference.Instance.RemoveRecent(repo.Path); - UpdateRecents(); - ev.Handled = true; - }; - - var menu = new ContextMenu(); - menu.Items.Add(remove); - menu.IsOpen = true; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; + +namespace SourceGit.Views.Widgets { + + /// + /// 新标签页 + /// + public partial class Welcome : UserControl, Controls.IPopupContainer { + + /// + /// 树节点数据 + /// + public class Node : Controls.BindableBase { + public string Id { get; set; } + public string ParentId { get; set; } + + private string name; + public string Name { + get => name; + set => SetProperty(ref name, value); + } + + public bool IsGroup { get; set; } + + private bool isEditing = false; + public bool IsEditing { + get => isEditing; + set => SetProperty(ref isEditing, value); + } + + public bool IsExpanded { get; set; } + + private int bookmark = 0; + public int Bookmark { + get => bookmark; + set => SetProperty(ref bookmark, value); + } + + public List Children { get; set; } + } + + /// + /// 仓库节点编辑事件参数 + /// + public event Action OnNodeEdited; + + public Welcome() { + InitializeComponent(); + UpdateTree(); + UpdateRecents(); + } + + #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; + } + + if (Models.Preference.Instance.General.UseWindowsTerminal) { + Process.Start(new ProcessStartInfo { + FileName = "wt", + Arguments = "\"{bash}\"", + UseShellExecute = false, + }); + } else { + Process.Start(new ProcessStartInfo { + FileName = bash, + UseShellExecute = true, + }); + } + e.Handled = true; } - } - + } + + private void OnCloneClicked(object sender, RoutedEventArgs e) { + if (MakeSureReady()) new Popups.Clone().Show(); + } + + private void OnRecentContextMenuOpening(object sender, ContextMenuEventArgs e) { + var repo = (sender as DataGridRow).DataContext as Models.Repository; + if (repo != null) { + var remove = new MenuItem(); + remove.Header = App.Text("Welcome.Delete"); + remove.Click += (o, ev) => { + Models.Preference.Instance.RemoveRecent(repo.Path); + UpdateRecents(); + ev.Handled = true; + }; + + var menu = new ContextMenu(); + menu.Items.Add(remove); + menu.IsOpen = true; + e.Handled = true; + } + } + private void OnRecentDoubleClick(object sender, MouseButtonEventArgs e) { - var repo = (sender as DataGridRow).DataContext as Models.Repository; + var repo = (sender as DataGridRow).DataContext as Models.Repository; if (repo != null) CheckAndOpen(repo.Path); e.Handled = true; - } - + } + private void OnRecentLostFocus(object sender, RoutedEventArgs e) { list.UnselectAll(); e.Handled = true; - } - + } + private void OnTreeLostFocus(object sender, RoutedEventArgs e) { var child = FocusManager.GetFocusedElement(body); if (child == null) return; if (!tree.IsAncestorOf(child as UIElement)) tree.UnselectAll(); e.Handled = true; - } - - private void OnTreeNodeStatusChange(object sender, RoutedEventArgs e) { - var node = (sender as Controls.TreeItem).DataContext as Node; - if (node != null) { - var group = Models.Preference.Instance.FindGroup(node.Id); - group.IsExpanded = node.IsExpanded; - e.Handled = true; - } - } - - private void OnTreeNodeDoubleClick(object sender, MouseButtonEventArgs e) { - var node = (sender as Controls.TreeItem).DataContext as Node; - if (node != null && !node.IsGroup) { - CheckAndOpen(node.Id); - e.Handled = true; - } - } - - private void OnTreeContextMenuOpening(object sender, ContextMenuEventArgs e) { - var item = tree.FindItem(e.OriginalSource as DependencyObject); - if (item == null) { - var addFolder = new MenuItem(); - addFolder.Header = App.Text("Welcome.NewFolder"); - addFolder.Click += (o, ev) => { - var group = Models.Preference.Instance.AddGroup("New Group", ""); - UpdateTree(group.Id); - ev.Handled = true; - }; - - var menu = new ContextMenu(); - menu.Items.Add(addFolder); - menu.IsOpen = true; - e.Handled = true; - } else { - var node = item.DataContext as Node; - if (node == null) return; - - var menu = new ContextMenu(); - if (!node.IsGroup) { - var open = new MenuItem(); - open.Header = App.Text("RepoCM.Open"); - open.Click += (o, ev) => { - CheckAndOpen(node.Id); - ev.Handled = true; - }; - - var explore = new MenuItem(); - explore.Header = App.Text("RepoCM.Explore"); - explore.Click += (o, ev) => { - Process.Start("explorer", node.Id); - ev.Handled = true; - }; - - var iconBookmark = FindResource("Icon.Bookmark") as Geometry; - var bookmark = new MenuItem(); - bookmark.Header = App.Text("RepoCM.Bookmark"); - for (int i = 0; i < Controls.Bookmark.COLORS.Length; i++) { - var icon = new System.Windows.Shapes.Path(); - icon.Data = iconBookmark; - icon.Fill = Controls.Bookmark.COLORS[i]; - icon.Width = 8; - - var mark = new MenuItem(); - mark.Icon = icon; - mark.Header = $"{i}"; - - var refIdx = i; - mark.Click += (o, ev) => { - var repo = Models.Preference.Instance.FindRepository(node.Id); - if (repo != null) { - repo.Bookmark = refIdx; - node.Bookmark = refIdx; - UpdateRecents(); - OnNodeEdited?.Invoke(node); - } - ev.Handled = true; - }; - - bookmark.Items.Add(mark); - } - - menu.Items.Add(open); - menu.Items.Add(explore); - menu.Items.Add(bookmark); - } else { - var addSubFolder = new MenuItem(); - addSubFolder.Header = App.Text("Welcome.NewSubFolder"); - addSubFolder.Click += (o, ev) => { - var parent = Models.Preference.Instance.FindGroup(node.Id); - if (parent != null) parent.IsExpanded = true; - - var group = Models.Preference.Instance.AddGroup("New Group", node.Id); - UpdateTree(group.Id); - ev.Handled = true; - }; - - menu.Items.Add(addSubFolder); - } - - var rename = new MenuItem(); - rename.Header = App.Text("Welcome.Rename"); - rename.Click += (o, ev) => { - UpdateTree(node.Id); - ev.Handled = true; - }; - - var delete = new MenuItem(); - delete.Header = App.Text("Welcome.Delete"); - delete.Click += (o, ev) => { - DeleteNode(node); - ev.Handled = true; - }; - - menu.Items.Add(rename); - menu.Items.Add(delete); - menu.IsOpen = true; - e.Handled = true; - } - } - #endregion - - #region DRAP_DROP_EVENTS - private void OnPageDragEnter(object sender, DragEventArgs e) { - if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent(typeof(Node))) { - 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 OnTreeMouseMove(object sender, MouseEventArgs e) { - if (e.LeftButton != MouseButtonState.Pressed) return; - - var item = tree.FindItem(e.OriginalSource as DependencyObject); - if (item == null) return; - - tree.UnselectAll(); - - var adorner = new Controls.DragDropAdorner(item); - DragDrop.DoDragDrop(item, item.DataContext, DragDropEffects.Move); - adorner.Remove(); - } - - private void OnTreeDragOver(object sender, DragEventArgs e) { - if (!e.Data.GetDataPresent(DataFormats.FileDrop) && !e.Data.GetDataPresent(typeof(Node))) return; - - var item = tree.FindItem(e.OriginalSource as DependencyObject); - if (item == null) return; - - var node = item.DataContext as Node; - if (node.IsGroup && !item.IsExpanded) item.IsExpanded = true; - e.Handled = true; - } - - private void OnTreeDrop(object sender, DragEventArgs e) { - bool rebuild = false; - dropArea.Visibility = Visibility.Hidden; - - var parent = ""; - var to = tree.FindItem(e.OriginalSource as DependencyObject); - if (to != null) { - var dst = to.DataContext as Node; - parent = dst.IsGroup ? dst.Id : dst.ParentId; - } - - 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, parent); - rebuild = true; - } - } - } else if (e.Data.GetDataPresent(typeof(Node))) { - var src = e.Data.GetData(typeof(Node)) as Node; - if (src.IsGroup) { - if (!Models.Preference.Instance.IsSubGroup(src.Id, parent)) { - Models.Preference.Instance.FindGroup(src.Id).Parent = parent; - rebuild = true; - } - } else { - Models.Preference.Instance.FindRepository(src.Id).GroupId = parent; - rebuild = true; - } - } - - if (rebuild) UpdateTree(); - e.Handled = true; - } - #endregion - - #region DATA - private void UpdateRecents() { - var repos = new List(); - var dirty = new List(); - + } + + private void OnTreeNodeStatusChange(object sender, RoutedEventArgs e) { + var node = (sender as Controls.TreeItem).DataContext as Node; + if (node != null) { + var group = Models.Preference.Instance.FindGroup(node.Id); + group.IsExpanded = node.IsExpanded; + e.Handled = true; + } + } + + private void OnTreeNodeDoubleClick(object sender, MouseButtonEventArgs e) { + var node = (sender as Controls.TreeItem).DataContext as Node; + if (node != null && !node.IsGroup) { + CheckAndOpen(node.Id); + e.Handled = true; + } + } + + private void OnTreeContextMenuOpening(object sender, ContextMenuEventArgs e) { + var item = tree.FindItem(e.OriginalSource as DependencyObject); + if (item == null) { + var addFolder = new MenuItem(); + addFolder.Header = App.Text("Welcome.NewFolder"); + addFolder.Click += (o, ev) => { + var group = Models.Preference.Instance.AddGroup("New Group", ""); + UpdateTree(group.Id); + ev.Handled = true; + }; + + var menu = new ContextMenu(); + menu.Items.Add(addFolder); + menu.IsOpen = true; + e.Handled = true; + } else { + var node = item.DataContext as Node; + if (node == null) return; + + var menu = new ContextMenu(); + if (!node.IsGroup) { + var open = new MenuItem(); + open.Header = App.Text("RepoCM.Open"); + open.Click += (o, ev) => { + CheckAndOpen(node.Id); + ev.Handled = true; + }; + + var explore = new MenuItem(); + explore.Header = App.Text("RepoCM.Explore"); + explore.Click += (o, ev) => { + Process.Start("explorer", node.Id); + ev.Handled = true; + }; + + var iconBookmark = FindResource("Icon.Bookmark") as Geometry; + var bookmark = new MenuItem(); + bookmark.Header = App.Text("RepoCM.Bookmark"); + for (int i = 0; i < Controls.Bookmark.COLORS.Length; i++) { + var icon = new System.Windows.Shapes.Path(); + icon.Data = iconBookmark; + icon.Fill = Controls.Bookmark.COLORS[i]; + icon.Width = 8; + + var mark = new MenuItem(); + mark.Icon = icon; + mark.Header = $"{i}"; + + var refIdx = i; + mark.Click += (o, ev) => { + var repo = Models.Preference.Instance.FindRepository(node.Id); + if (repo != null) { + repo.Bookmark = refIdx; + node.Bookmark = refIdx; + UpdateRecents(); + OnNodeEdited?.Invoke(node); + } + ev.Handled = true; + }; + + bookmark.Items.Add(mark); + } + + menu.Items.Add(open); + menu.Items.Add(explore); + menu.Items.Add(bookmark); + } else { + var addSubFolder = new MenuItem(); + addSubFolder.Header = App.Text("Welcome.NewSubFolder"); + addSubFolder.Click += (o, ev) => { + var parent = Models.Preference.Instance.FindGroup(node.Id); + if (parent != null) parent.IsExpanded = true; + + var group = Models.Preference.Instance.AddGroup("New Group", node.Id); + UpdateTree(group.Id); + ev.Handled = true; + }; + + menu.Items.Add(addSubFolder); + } + + var rename = new MenuItem(); + rename.Header = App.Text("Welcome.Rename"); + rename.Click += (o, ev) => { + UpdateTree(node.Id); + ev.Handled = true; + }; + + var delete = new MenuItem(); + delete.Header = App.Text("Welcome.Delete"); + delete.Click += (o, ev) => { + DeleteNode(node); + ev.Handled = true; + }; + + menu.Items.Add(rename); + menu.Items.Add(delete); + menu.IsOpen = true; + e.Handled = true; + } + } + #endregion + + #region DRAP_DROP_EVENTS + private void OnPageDragEnter(object sender, DragEventArgs e) { + if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent(typeof(Node))) { + 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 OnTreeMouseMove(object sender, MouseEventArgs e) { + if (e.LeftButton != MouseButtonState.Pressed) return; + + var item = tree.FindItem(e.OriginalSource as DependencyObject); + if (item == null) return; + + tree.UnselectAll(); + + var adorner = new Controls.DragDropAdorner(item); + DragDrop.DoDragDrop(item, item.DataContext, DragDropEffects.Move); + adorner.Remove(); + } + + private void OnTreeDragOver(object sender, DragEventArgs e) { + if (!e.Data.GetDataPresent(DataFormats.FileDrop) && !e.Data.GetDataPresent(typeof(Node))) return; + + var item = tree.FindItem(e.OriginalSource as DependencyObject); + if (item == null) return; + + var node = item.DataContext as Node; + if (node.IsGroup && !item.IsExpanded) item.IsExpanded = true; + e.Handled = true; + } + + private void OnTreeDrop(object sender, DragEventArgs e) { + bool rebuild = false; + dropArea.Visibility = Visibility.Hidden; + + var parent = ""; + var to = tree.FindItem(e.OriginalSource as DependencyObject); + if (to != null) { + var dst = to.DataContext as Node; + parent = dst.IsGroup ? dst.Id : dst.ParentId; + } + + 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, parent); + rebuild = true; + } + } + } else if (e.Data.GetDataPresent(typeof(Node))) { + var src = e.Data.GetData(typeof(Node)) as Node; + if (src.IsGroup) { + if (!Models.Preference.Instance.IsSubGroup(src.Id, parent)) { + Models.Preference.Instance.FindGroup(src.Id).Parent = parent; + rebuild = true; + } + } else { + Models.Preference.Instance.FindRepository(src.Id).GroupId = parent; + rebuild = true; + } + } + + if (rebuild) UpdateTree(); + e.Handled = true; + } + #endregion + + #region DATA + private void UpdateRecents() { + var repos = new List(); + var dirty = new List(); + foreach (var path in Models.Preference.Instance.Recents) { var repo = Models.Preference.Instance.FindRepository(path); if (repo != null) { @@ -331,160 +356,160 @@ namespace SourceGit.Views.Widgets { } else { dirty.Add(path); } - } - - foreach (var path in dirty) Models.Preference.Instance.RemoveRecent(path); - list.ItemsSource = repos; - } - - private void UpdateTree(string editingNodeId = null) { - var groupNodes = new Dictionary(); - var nodes = new List(); - - foreach (var group in Models.Preference.Instance.Groups) { - Node node = new Node() { - Id = group.Id, - ParentId = group.Parent, - Name = group.Name, - IsGroup = true, - IsEditing = group.Id == editingNodeId, - IsExpanded = group.IsExpanded, - Bookmark = 0, - Children = new List(), - }; - - groupNodes.Add(node.Id, node); - } - - nodes.Clear(); - - foreach (var kv in groupNodes) { - if (groupNodes.ContainsKey(kv.Value.ParentId)) { - groupNodes[kv.Value.ParentId].Children.Add(kv.Value); - } else { - nodes.Add(kv.Value); - } - } - - foreach (var repo in Models.Preference.Instance.Repositories) { - Node node = new Node() { - Id = repo.Path, - ParentId = repo.GroupId, - Name = repo.Name, - IsGroup = false, - IsEditing = repo.Path == editingNodeId, - IsExpanded = false, - Bookmark = repo.Bookmark, - Children = new List(), - }; - - if (groupNodes.ContainsKey(repo.GroupId)) { - groupNodes[repo.GroupId].Children.Add(node); - } else { - nodes.Add(node); - } - } - - tree.ItemsSource = nodes; - } - - private void DeleteNode(Node node) { - if (node.IsGroup) { - Models.Preference.Instance.RemoveGroup(node.Id); - } else { - Models.Preference.Instance.RemoveRepository(node.Id); - } - + } + + foreach (var path in dirty) Models.Preference.Instance.RemoveRecent(path); + list.ItemsSource = repos; + } + + private void UpdateTree(string editingNodeId = null) { + var groupNodes = new Dictionary(); + var nodes = new List(); + + foreach (var group in Models.Preference.Instance.Groups) { + Node node = new Node() { + Id = group.Id, + ParentId = group.Parent, + Name = group.Name, + IsGroup = true, + IsEditing = group.Id == editingNodeId, + IsExpanded = group.IsExpanded, + Bookmark = 0, + Children = new List(), + }; + + groupNodes.Add(node.Id, node); + } + + nodes.Clear(); + + foreach (var kv in groupNodes) { + if (groupNodes.ContainsKey(kv.Value.ParentId)) { + groupNodes[kv.Value.ParentId].Children.Add(kv.Value); + } else { + nodes.Add(kv.Value); + } + } + + foreach (var repo in Models.Preference.Instance.Repositories) { + Node node = new Node() { + Id = repo.Path, + ParentId = repo.GroupId, + Name = repo.Name, + IsGroup = false, + IsEditing = repo.Path == editingNodeId, + IsExpanded = false, + Bookmark = repo.Bookmark, + Children = new List(), + }; + + if (groupNodes.ContainsKey(repo.GroupId)) { + groupNodes[repo.GroupId].Children.Add(node); + } else { + nodes.Add(node); + } + } + + tree.ItemsSource = nodes; + } + + private void DeleteNode(Node node) { + if (node.IsGroup) { + Models.Preference.Instance.RemoveGroup(node.Id); + } else { + Models.Preference.Instance.RemoveRepository(node.Id); + } + UpdateTree(); - UpdateRecents(); - } - - 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); - Models.Preference.Instance.AddRecent(repo.Path); - } - - public void UpdateNodes(string id, int bookmark, IEnumerable nodes = null) { - if (nodes == null) nodes = tree.ItemsSource.OfType(); - foreach (var node in nodes) { - if (!node.IsGroup) { - if (node.Id == id) { - node.Bookmark = bookmark; - break; - } - } else if (node.Children.Count > 0) { - UpdateNodes(id, bookmark, node.Children); - } - } - } - #endregion - - #region RENAME_NODES - private void RenameStart(object sender, RoutedEventArgs e) { - var edit = sender as Controls.TextEdit; - if (edit == null || !edit.IsVisible) return; - - edit.SelectAll(); - edit.Focus(); - } - - private void RenameKeyDown(object sender, KeyEventArgs e) { - if (e.Key == Key.Escape) { - UpdateTree(); - e.Handled = true; - } else if (e.Key == Key.Enter) { - RenameEnd(sender, e); - e.Handled = true; - } - } - - private void RenameEnd(object sender, RoutedEventArgs e) { - var edit = sender as Controls.TextEdit; - if (edit == null) return; - - if (string.IsNullOrWhiteSpace(edit.Text)) { - UpdateTree(); - e.Handled = false; - return; - } - - var node = edit.DataContext as Node; - if (node != null) { - node.Name = edit.Text; - node.IsEditing = false; - if (node.IsGroup) { - Models.Preference.Instance.RenameGroup(node.Id, edit.Text); - } else { + UpdateRecents(); + } + + 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); + Models.Preference.Instance.AddRecent(repo.Path); + } + + public void UpdateNodes(string id, int bookmark, IEnumerable nodes = null) { + if (nodes == null) nodes = tree.ItemsSource.OfType(); + foreach (var node in nodes) { + if (!node.IsGroup) { + if (node.Id == id) { + node.Bookmark = bookmark; + break; + } + } else if (node.Children.Count > 0) { + UpdateNodes(id, bookmark, node.Children); + } + } + } + #endregion + + #region RENAME_NODES + private void RenameStart(object sender, RoutedEventArgs e) { + var edit = sender as Controls.TextEdit; + if (edit == null || !edit.IsVisible) return; + + edit.SelectAll(); + edit.Focus(); + } + + private void RenameKeyDown(object sender, KeyEventArgs e) { + if (e.Key == Key.Escape) { + UpdateTree(); + e.Handled = true; + } else if (e.Key == Key.Enter) { + RenameEnd(sender, e); + e.Handled = true; + } + } + + private void RenameEnd(object sender, RoutedEventArgs e) { + var edit = sender as Controls.TextEdit; + if (edit == null) return; + + if (string.IsNullOrWhiteSpace(edit.Text)) { + UpdateTree(); + e.Handled = false; + return; + } + + var node = edit.DataContext as Node; + if (node != null) { + node.Name = edit.Text; + node.IsEditing = false; + if (node.IsGroup) { + Models.Preference.Instance.RenameGroup(node.Id, edit.Text); + } else { Models.Preference.Instance.RenameRepository(node.Id, node.Name); - UpdateRecents(); - OnNodeEdited?.Invoke(node); - } - e.Handled = false; - } - } - #endregion - } -} + UpdateRecents(); + OnNodeEdited?.Invoke(node); + } + e.Handled = false; + } + } + #endregion + } +}