diff --git a/src/ViewModels/FileTreeNode.cs b/src/Models/FileTreeNode.cs similarity index 84% rename from src/ViewModels/FileTreeNode.cs rename to src/Models/FileTreeNode.cs index 8e3ba076..ad1298c9 100644 --- a/src/ViewModels/FileTreeNode.cs +++ b/src/Models/FileTreeNode.cs @@ -1,24 +1,17 @@ using System; using System.Collections.Generic; -using CommunityToolkit.Mvvm.ComponentModel; - -namespace SourceGit.ViewModels +namespace SourceGit.Models { - public class FileTreeNode : ObservableObject + public class FileTreeNode { public string FullPath { get; set; } = string.Empty; public bool IsFolder { get; set; } = false; + public bool IsExpanded { get; set; } = false; public object Backend { get; set; } = null; public List Children { get; set; } = new List(); - public bool IsExpanded - { - get => _isExpanded; - set => SetProperty(ref _isExpanded, value); - } - - public static List Build(List changes, bool expanded) + public static List Build(List changes, bool expanded) { var nodes = new List(); var folders = new Dictionary(); @@ -93,7 +86,7 @@ namespace SourceGit.ViewModels return nodes; } - public static List Build(List files, bool expanded) + public static List Build(List files, bool expanded) { var nodes = new List(); var folders = new Dictionary(); @@ -168,27 +161,6 @@ namespace SourceGit.ViewModels return nodes; } - public static FileTreeNode SelectByPath(List nodes, string path) - { - foreach (var node in nodes) - { - if (node.FullPath == path) - return node; - - if (node.IsFolder && path.StartsWith(node.FullPath + "/", StringComparison.Ordinal)) - { - var foundInChildren = SelectByPath(node.Children, path); - if (foundInChildren != null) - { - node.IsExpanded = true; - } - return foundInChildren; - } - } - - return null; - } - private static void Sort(List nodes) { nodes.Sort((l, r) => @@ -209,7 +181,5 @@ namespace SourceGit.ViewModels Sort(node.Children); } } - - private bool _isExpanded = true; } } diff --git a/src/Models/TreeDataGridSelectionModel.cs b/src/Models/TreeDataGridSelectionModel.cs index efdda2a4..b016d739 100644 --- a/src/Models/TreeDataGridSelectionModel.cs +++ b/src/Models/TreeDataGridSelectionModel.cs @@ -188,7 +188,12 @@ namespace SourceGit.Models } else if (e.ClickCount % 2 == 0) { - _rowDoubleTapped?.Invoke(this, e); + var focus = _source.Rows[row.RowIndex]; + if (focus is IExpander expander && HasChildren(focus)) + expander.IsExpanded = !expander.IsExpanded; + else + _rowDoubleTapped?.Invoke(this, e); + e.Handled = true; } else if (sender.RowSelection.Count > 1) @@ -420,7 +425,22 @@ namespace SourceGit.Models protected override IEnumerable GetChildren(TModel node) { + if (node == null) + return null; + return _childrenGetter?.Invoke(node); } + + private bool HasChildren(IRow row) + { + var children = GetChildren(row.Model as TModel); + if (children != null) + { + foreach (var c in children) + return true; + } + + return false; + } } } diff --git a/src/Resources/Styles.axaml b/src/Resources/Styles.axaml index 37a0670f..6b76c2cf 100644 --- a/src/Resources/Styles.axaml +++ b/src/Resources/Styles.axaml @@ -1123,6 +1123,10 @@ + + diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index 6f26465f..b96c1fe1 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Controls.Models.TreeDataGrid; -using Avalonia.Interactivity; using Avalonia.Media.Imaging; using Avalonia.Platform.Storage; using Avalonia.Threading; @@ -77,7 +76,7 @@ namespace SourceGit.ViewModels } } - public HierarchicalTreeDataGridSource RevisionFiles + public HierarchicalTreeDataGridSource RevisionFiles { get => _revisionFiles; private set => SetProperty(ref _revisionFiles, value); @@ -336,7 +335,6 @@ namespace SourceGit.ViewModels } } - var tree = FileTreeNode.Build(visible, true); Dispatcher.UIThread.Invoke(() => { Changes = changes; @@ -362,7 +360,7 @@ namespace SourceGit.ViewModels } } - var tree = FileTreeNode.Build(visible, isSearching || visible.Count <= 100); + var tree = Models.FileTreeNode.Build(visible, isSearching || visible.Count <= 100); Dispatcher.UIThread.Invoke(() => BuildRevisionFilesSource(tree)); }); } @@ -406,7 +404,7 @@ namespace SourceGit.ViewModels } } - BuildRevisionFilesSource(FileTreeNode.Build(visible, isSearching || visible.Count < 100)); + BuildRevisionFilesSource(Models.FileTreeNode.Build(visible, isSearching || visible.Count < 100)); } private void RefreshViewRevisionFile(Models.Object file) @@ -493,29 +491,29 @@ namespace SourceGit.ViewModels } } - private void BuildRevisionFilesSource(List tree) + private void BuildRevisionFilesSource(List tree) { - var source = new HierarchicalTreeDataGridSource(tree) + var source = new HierarchicalTreeDataGridSource(tree) { Columns = { - new HierarchicalExpanderColumn( - new TemplateColumn("Icon", "FileTreeNodeExpanderTemplate", null, GridLength.Auto), + new HierarchicalExpanderColumn( + new TemplateColumn("Icon", "FileTreeNodeExpanderTemplate", null, GridLength.Auto), x => x.Children, x => x.Children.Count > 0, x => x.IsExpanded), - new TextColumn( + new TextColumn( null, x => string.Empty, GridLength.Star) } }; - var selection = new Models.TreeDataGridSelectionModel(source, x => x.Children); + var selection = new Models.TreeDataGridSelectionModel(source, x => x.Children); selection.SingleSelect = true; selection.SelectionChanged += (s, _) => { - if (s is Models.TreeDataGridSelectionModel selection) + if (s is Models.TreeDataGridSelectionModel selection) RefreshViewRevisionFile(selection.SelectedItem?.Backend as Models.Object); }; @@ -537,7 +535,7 @@ namespace SourceGit.ViewModels private string _searchChangeFilter = string.Empty; private DiffContext _diffContext = null; private List _revisionFilesBackup = null; - private HierarchicalTreeDataGridSource _revisionFiles = null; + private HierarchicalTreeDataGridSource _revisionFiles = null; private string _searchFileFilter = string.Empty; private object _viewRevisionFileContent = null; private Commands.Command.CancelToken _cancelToken = null; diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index e0fda542..c05ae641 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -389,6 +389,7 @@ namespace SourceGit.ViewModels App.RaiseException(_fullpath, "Can NOT found current branch!!!"); return; } + PopupHost.ShowPopup(new Push(this, null)); } diff --git a/src/ViewModels/RevisionCompare.cs b/src/ViewModels/RevisionCompare.cs index 536d71bc..9026aa7f 100644 --- a/src/ViewModels/RevisionCompare.cs +++ b/src/ViewModels/RevisionCompare.cs @@ -99,11 +99,7 @@ namespace SourceGit.ViewModels } } - var tree = FileTreeNode.Build(visible, true); - Dispatcher.UIThread.Invoke(() => - { - VisibleChanges = visible; - }); + Dispatcher.UIThread.Invoke(() => VisibleChanges = visible); }); } diff --git a/src/Views/ChangeCollectionView.axaml b/src/Views/ChangeCollectionView.axaml index 9b37cb17..b09d76d2 100644 --- a/src/Views/ChangeCollectionView.axaml +++ b/src/Views/ChangeCollectionView.axaml @@ -16,7 +16,7 @@ CanUserSortColumns="False" ScrollViewer.BringIntoViewOnFocusChange="True"> - + diff --git a/src/Views/ChangeCollectionView.axaml.cs b/src/Views/ChangeCollectionView.axaml.cs index a2dd928d..6ce04ff6 100644 --- a/src/Views/ChangeCollectionView.axaml.cs +++ b/src/Views/ChangeCollectionView.axaml.cs @@ -91,29 +91,25 @@ namespace SourceGit.Views var viewMode = ViewMode; if (viewMode == Models.ChangeViewMode.Tree) { - var filetree = ViewModels.FileTreeNode.Build(changes, true); - var source = new HierarchicalTreeDataGridSource(filetree) + var filetree = Models.FileTreeNode.Build(changes, true); + var source = new HierarchicalTreeDataGridSource(filetree) { Columns = { - new HierarchicalExpanderColumn( - new TemplateColumn(null, "TreeModeTemplate", null, GridLength.Auto), + new HierarchicalExpanderColumn( + new TemplateColumn(null, "TreeModeTemplate", null, GridLength.Auto), x => x.Children, x => x.Children.Count > 0, - x => x.IsExpanded), - new TextColumn( - null, - x => string.Empty, - GridLength.Star) + x => x.IsExpanded) } }; - var selection = new Models.TreeDataGridSelectionModel(source, x => x.Children); + var selection = new Models.TreeDataGridSelectionModel(source, x => x.Children); selection.SingleSelect = SingleSelect; selection.RowDoubleTapped += (_, e) => RaiseEvent(new RoutedEventArgs(ChangeDoubleTappedEvent)); selection.SelectionChanged += (s, _) => { - if (!_isSelecting && s is Models.TreeDataGridSelectionModel model) + if (!_isSelecting && s is Models.TreeDataGridSelectionModel model) { var selection = new List(); foreach (var c in model.SelectedItems) @@ -202,7 +198,7 @@ namespace SourceGit.Views else changeSelection.Select(selected); } - else if (tree.Source.Selection is Models.TreeDataGridSelectionModel treeSelection) + else if (tree.Source.Selection is Models.TreeDataGridSelectionModel treeSelection) { if (selected == null || selected.Count == 0) { @@ -215,9 +211,9 @@ namespace SourceGit.Views foreach (var c in selected) set.Add(c); - var nodes = new List(); + var nodes = new List(); foreach (var node in tree.Source.Items) - CollectSelectedNodeByChange(nodes, node as ViewModels.FileTreeNode, set); + CollectSelectedNodeByChange(nodes, node as Models.FileTreeNode, set); if (nodes.Count == 0) { @@ -231,7 +227,7 @@ namespace SourceGit.Views _isSelecting = false; } - private void CollectChangesInNode(List outs, ViewModels.FileTreeNode node) + private void CollectChangesInNode(List outs, Models.FileTreeNode node) { if (node.IsFolder) { @@ -246,7 +242,7 @@ namespace SourceGit.Views } } - private void CollectSelectedNodeByChange(List outs, ViewModels.FileTreeNode node, HashSet selected) + private void CollectSelectedNodeByChange(List outs, Models.FileTreeNode node, HashSet selected) { if (node == null) return; diff --git a/src/Views/RevisionFiles.axaml b/src/Views/RevisionFiles.axaml index c46632f6..82d2651c 100644 --- a/src/Views/RevisionFiles.axaml +++ b/src/Views/RevisionFiles.axaml @@ -48,7 +48,7 @@ Source="{Binding RevisionFiles}" ContextRequested="OnFileContextRequested"> - + diff --git a/src/Views/RevisionFiles.axaml.cs b/src/Views/RevisionFiles.axaml.cs index 730e9b34..2720009b 100644 --- a/src/Views/RevisionFiles.axaml.cs +++ b/src/Views/RevisionFiles.axaml.cs @@ -217,7 +217,7 @@ namespace SourceGit.Views { if (DataContext is ViewModels.CommitDetail vm && sender is TreeDataGrid tree) { - var selected = tree.RowSelection.SelectedItem as ViewModels.FileTreeNode; + var selected = tree.RowSelection.SelectedItem as Models.FileTreeNode; if (selected != null && !selected.IsFolder && selected.Backend is Models.Object obj) { var menu = vm.CreateRevisionFileContextMenu(obj);