Răsfoiți Sursa

Fix file association selection after R3

Ruben 3 luni în urmă
părinte
comite
bb8e0f5996
1 a modificat fișierele cu 71 adăugiri și 67 ștergeri
  1. 71 67
      src/PicView.Avalonia/Views/FileAssociationsView.axaml.cs

+ 71 - 67
src/PicView.Avalonia/Views/FileAssociationsView.axaml.cs

@@ -1,6 +1,7 @@
 using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Input;
+using Avalonia.LogicalTree;
 using Avalonia.Media;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
@@ -16,11 +17,11 @@ public partial class FileAssociationsView : UserControl
 {
     private readonly List<(CheckBox CheckBox, string SearchText)> _allCheckBoxes = [];
     private readonly CompositeDisposable _disposables = new();
-        
+
     public FileAssociationsView()
     {
         InitializeComponent();
-        
+
         FileTypesScrollViewer.Height = ScreenHelper.ScreenSize.WorkingAreaHeight switch
         {
             > 500 and <= 650 => 340,
@@ -43,7 +44,7 @@ public partial class FileAssociationsView : UserControl
             };
         };
     }
-        
+
     private void InitializeCheckBoxesCollection()
     {
         var container = FileTypesContainer;
@@ -52,14 +53,18 @@ public partial class FileAssociationsView : UserControl
         {
             return;
         }
-        
+
         vm.AssociationsViewModel ??= new FileAssociationsViewModel();
-            
+
         // Subscribe to changes in the filter text
         Observable.EveryValueChanged(vm.AssociationsViewModel, x => x.FilterText.Value, UIHelper.GetFrameProvider)
             .Subscribe(FilterCheckBoxes)
             .AddTo(_disposables);
-            
+
+        vm.AssociationsViewModel.ResetCommand.Subscribe(UpdateCheckBoxesFromViewModel).AddTo(_disposables);
+        vm.AssociationsViewModel.SelectAllCommand.Subscribe(UpdateCheckBoxesFromViewModel).AddTo(_disposables);
+        vm.AssociationsViewModel.UnselectAllCommand.Subscribe(UpdateCheckBoxesFromViewModel).AddTo(_disposables);
+
         // Create checkboxes for each file type group and item
         foreach (var fileTypeGroup in vm.AssociationsViewModel.FileTypeGroups)
         {
@@ -87,6 +92,7 @@ public partial class FileAssociationsView : UserControl
                     fileTypeGroup.Name = TranslationManager.Translation.Archives!;
                 }
             }
+
             // Create group header checkbox
             var groupCheckBox = new CheckBox
             {
@@ -96,22 +102,22 @@ public partial class FileAssociationsView : UserControl
                 IsThreeState = true,
                 IsChecked = fileTypeGroup.IsSelected.CurrentValue
             };
-                
+
             var groupTextBlock = new TextBlock
             {
                 Classes = { "txt" },
                 Text = fileTypeGroup.Name,
                 FontFamily = new FontFamily("avares://PicView.Avalonia/Assets/Fonts/Roboto-Bold.ttf#Roboto")
             };
-                
+
             groupCheckBox.Content = groupTextBlock;
-                
+
             // Add to container
             container.Children.Add(groupCheckBox);
-                
+
             // Add to the collection for filtering
             _allCheckBoxes.Add((groupCheckBox, fileTypeGroup.Name));
-                
+
             // Handle group checkbox changes to update all items in the group
             groupCheckBox.Click += delegate
             {
@@ -121,9 +127,8 @@ public partial class FileAssociationsView : UserControl
                 {
                     fileType.IsSelected.Value = isChecked;
                 }
-                UpdateCheckBoxesFromViewModel();
             };
-                
+
             // Create checkboxes for each file type item in the group
             foreach (var fileType in fileTypeGroup.FileTypes)
             {
@@ -134,64 +139,57 @@ public partial class FileAssociationsView : UserControl
                     IsChecked = fileType.IsSelected.CurrentValue,
                     IsThreeState = true
                 };
-                    
+
                 var fileTextBlock = new TextBlock
                 {
                     Classes = { "txt" },
                     Text = $"{fileType.Description} ({fileType.Extension})",
                     Margin = new Thickness(0),
-                    Padding = new Thickness(0, 1, 5, 0),
+                    Padding = new Thickness(0, 1, 5, 0)
                 };
-                    
+
                 fileCheckBox.Content = fileTextBlock;
-                    
+
                 // Add to container
                 container.Children.Add(fileCheckBox);
-                    
+
                 // Add to the collection for filtering
                 _allCheckBoxes.Add((fileCheckBox, $"{fileType.Description} {fileType.Extension}"));
-                    
+
                 // Bind the checkbox to the file type's IsSelected property
                 fileCheckBox.IsCheckedChanged += delegate
                 {
                     // Update the model - important to handle null state correctly
                     fileType.IsSelected.Value = fileCheckBox.IsChecked;
-    
+
                     // Now update the group checkbox state
                     UpdateGroupCheckboxState(fileTypeGroup);
                 };
-                    
+
                 // Subscribe to changes in the file type's IsSelected property
                 Observable.EveryValueChanged(fileType, x => x.IsSelected, UIHelper.GetFrameProvider)
-                    .Subscribe( isSelected =>
-                    {
-                        fileCheckBox.IsChecked = isSelected.CurrentValue;
-                    })
+                    .Subscribe(isSelected => { fileCheckBox.IsChecked = isSelected.CurrentValue; })
                     .AddTo(_disposables);
-                    
+
                 // Subscribe to changes in the file type's IsVisible property
                 Observable.EveryValueChanged(fileType, x => x.IsVisible, UIHelper.GetFrameProvider)
-                    .Subscribe(isVisible =>
-                    {
-                        fileCheckBox.IsVisible = isVisible.CurrentValue;
-                    })
+                    .Subscribe(isVisible => { fileCheckBox.IsVisible = isVisible.CurrentValue; })
                     .AddTo(_disposables);
             }
         }
-        
     }
-    
+
     private void UpdateGroupCheckboxState(FileTypeGroup group)
     {
         // Find all checkboxes that are part of this group
         var fileTypeCheckboxes = FileTypesContainer.Children.OfType<CheckBox>()
-            .Where(c => c.Tag != null && c.Tag.ToString() != "group" && 
+            .Where(c => c.Tag != null && c.Tag.ToString() != "group" &&
                         c.IsVisible && IsCheckboxInGroup(c, group));
-                   
+
         var allTrue = true;
         var allFalse = true;
         var anyNull = false;
-    
+
         foreach (var cb in fileTypeCheckboxes)
         {
             if (!cb.IsChecked.HasValue || cb.IsChecked == null)
@@ -209,7 +207,7 @@ public partial class FileAssociationsView : UserControl
                 allTrue = false;
             }
         }
-    
+
         // Find the group checkbox
         var groupCheckbox = FileTypesContainer.Children.OfType<CheckBox>()
             .FirstOrDefault(c => c.Tag?.ToString() == "group" && c.Name == group.Name.Trim());
@@ -220,14 +218,22 @@ public partial class FileAssociationsView : UserControl
         }
 
         if (anyNull)
+        {
             groupCheckbox.IsChecked = null;
+        }
         else if (allTrue)
+        {
             groupCheckbox.IsChecked = true;
+        }
         else if (allFalse)
+        {
             groupCheckbox.IsChecked = false;
+        }
         else
+        {
             groupCheckbox.IsChecked = null;
-            
+        }
+
         // Update the ViewModel
         group.IsSelected.Value = groupCheckbox.IsChecked;
     }
@@ -237,71 +243,68 @@ public partial class FileAssociationsView : UserControl
         // You can determine this by position in the UI or by extension tag
         var extension = checkbox.Tag?.ToString();
         if (string.IsNullOrEmpty(extension))
+        {
             return false;
-        
-        return group.FileTypes.Any(ft => ft.Extensions.Contains(extension) || 
+        }
+
+        return group.FileTypes.Any(ft => ft.Extensions.Contains(extension) ||
                                          extension.Contains(ft.Extensions.FirstOrDefault() ?? ""));
     }
-        
-    private void UpdateCheckBoxesFromViewModel()
+
+    private void UpdateCheckBoxesFromViewModel(Unit unit)
     {
         if (DataContext is not MainViewModel vm)
+        {
             return;
-            
+        }
+
         foreach (var group in vm.AssociationsViewModel.FileTypeGroups)
         {
-            // Find the group checkbox
-            var groupName = $"{group.Name.Replace(" ", "")}Group";
-            var groupCheckBox = FindLogicalDescendant<CheckBox>(groupName);
-            if (groupCheckBox == null)
+
+            if (group?.Name is null)
             {
                 continue;
             }
+            // Find the group checkbox
+            var boxes = FileTypesContainer.GetLogicalChildren().OfType<CheckBox>();
+            var checkBoxes = boxes.ToList();
 
-            // Check if all children are selected
-            bool? allSelected = true;
-            bool? anySelected = false;
-                    
             foreach (var fileType in group.FileTypes)
             {
-                if (!fileType.IsSelected.CurrentValue.HasValue)
-                    anySelected = null;
-                else if (!fileType.IsSelected.CurrentValue.Value)
-                    allSelected = false;
-                else
-                    anySelected = true;
+                foreach (var checkBox in checkBoxes.Where(x => x.Tag.Equals(fileType.Extension)))
+                {
+                    checkBox.IsChecked = fileType.IsSelected.Value ?? false;
+                }
             }
-            
-            // Update the group checkbox
-            groupCheckBox.IsChecked = allSelected;
-            groupCheckBox.IsThreeState = anySelected == null;
         }
     }
-        
-    private T? FindLogicalDescendant<T>(string name) where T : Control
+
+    private T? FindLogicalDescendant<T>(string tag) where T : Control
     {
         foreach (var child in LogicalChildren)
         {
             switch (child)
             {
-                case T control when control.Name == name:
+                case T control when control.Tag == tag:
                     return control;
                 case not null:
                 {
                     foreach (var grandchild in child.LogicalChildren)
                     {
-                        if (grandchild is T grandControl && grandControl.Name == name)
+                        if (grandchild is T grandControl && grandControl.Tag == tag)
+                        {
                             return grandControl;
+                        }
                     }
 
                     break;
                 }
             }
         }
-            
+
         return null;
     }
-        
+
     private void FilterCheckBoxes(string? filterText)
     {
         if (string.IsNullOrWhiteSpace(filterText))
@@ -311,9 +314,10 @@ public partial class FileAssociationsView : UserControl
             {
                 checkBox.IsVisible = true;
             }
+
             return;
         }
-            
+
         foreach (var (checkBox, searchText) in _allCheckBoxes)
         {
             checkBox.IsVisible = searchText.Contains(filterText, StringComparison.InvariantCultureIgnoreCase);