namespace App.UI.Models; using Adw; using System.Collections.ObjectModel; using System.Collections.Specialized; public class PasswordStoreShortcutCollection : ObservableCollection { private readonly PreferencesGroup shortcutsGroup; private readonly Dictionary itemToRowMap = new(); public PasswordStoreShortcutCollection(PreferencesGroup shortcutsGroup) { this.shortcutsGroup = shortcutsGroup; CollectionChanged += OnCollectionChanged; } private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { case NotifyCollectionChangedAction.Add: foreach (PasswordStoreShortcut item in e.NewItems) { var row = CreateShortcutRow(item); itemToRowMap[item] = row; shortcutsGroup.Add(row); // Subscribe to property changes for reactive updates item.PropertyChanged += (sender, args) => UpdateRowFromItem(item, ref row); } break; case NotifyCollectionChangedAction.Remove: foreach (PasswordStoreShortcut item in e.OldItems) { if (itemToRowMap.TryGetValue(item, out var row)) { shortcutsGroup.Remove(row); itemToRowMap.Remove(item); } } break; case NotifyCollectionChangedAction.Reset: foreach (var row in itemToRowMap.Values) { shortcutsGroup.Remove(row); } itemToRowMap.Clear(); break; } } private ActionRow CreateShortcutRow(PasswordStoreShortcut shortcut) { var row = new ActionRow(); UpdateRowFromItem(shortcut, ref row); row.SetActivatable(true); row.OnActivated += (sender, args) => { Console.WriteLine($"[DEBUG] Opening: {shortcut.Path}"); }; return row; } private void UpdateRowFromItem(PasswordStoreShortcut shortcut, ref ActionRow row) { row.SetTitle(shortcut.DisplayName); row.SetSubtitle(shortcut.Path); //Update icon var existingIcon = row.GetFirstChild() as Gtk.Image; if (existingIcon == null) { var icon = new Gtk.Image(); icon.SetFromIconName(shortcut.IconName); row.AddPrefix(icon); } else { existingIcon.SetFromIconName(shortcut.IconName); } } }