using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.IO; using System.Linq; using Vanara.Collections; using Vanara.Extensions; using static Vanara.PInvoke.Shell32; namespace Vanara.Windows.Shell { /// The navigation log is a history of the locations visited by a shell view object. public class ShellNavigationHistory : IHistory { private readonly History pidls = new(); /// Initializes a new instance of the class. public ShellNavigationHistory() { pidls.CollectionChanged += (s, e) => CollectionChanged?.Invoke(this, e); pidls.PropertyChanged += (s, e) => PropertyChanged?.Invoke(this, e); } /// Occurs when an item is added, removed, changed, moved, or the entire list is refreshed. public event NotifyCollectionChangedEventHandler CollectionChanged; /// Occurs when a property value changes. public event PropertyChangedEventHandler PropertyChanged; /// Indicates the presence of items in the history that can be reached by calling . /// if this instance can seek backward; otherwise, . public bool CanSeekBackward => pidls.CanSeekBackward; /// Indicates the presence of items in the history that can be reached by calling . /// if this instance can seek forward; otherwise, . public bool CanSeekForward => pidls.CanSeekForward; /// Gets the items in the history. /// The number of items. public int Count => pidls.Count; /// Gets the shell object in the Locations collection pointed to by CurrentLocationIndex. public ShellItem Current => new(pidls.Current); /// /// Adds the specified item as the last history entry and sets the property to /// it's value. /// /// The item to add to the history. public void Add(ShellItem item) => pidls.Add(item.PIDL, true); /// Clears the history of all items. public void Clear() => pidls.Clear(); /// Returns an enumerator that iterates through the collection. /// A that can be used to iterate through the collection. public IEnumerator GetEnumerator() => pidls.Select(p => new ShellItem(p)).GetEnumerator(); /// Gets a specified number of items starting at a location within the history. /// The maximum number of items to retrieve. The actual number of items returned may be less if not avaialable. /// The reference point within the history at which to start fetching items. /// A read-only list of items. public IReadOnlyList GetItems(int count, SeekOrigin origin) => (IReadOnlyList)new List(pidls.GetItems(count, origin).Select(ShIFromPIDL)); /// /// Seeks through the history a given number of items starting at a known location within the history. This updates the property. /// /// The number of items to move. This value can be negative to search backwards or positive to search forwards. /// The reference point within the history at which to start seeking. /// The value at the new current pointer position. public ShellItem Seek(int count, SeekOrigin origin) => ShIFromPIDL(pidls.Seek(count, origin)); /// Seeks one position backwards. /// The value at the new current pointer position. public ShellItem SeekBackward() => ShIFromPIDL(pidls.SeekBackward()); /// Seeks one position forwards. /// The value at the new current pointer position. public ShellItem SeekForward() => ShIFromPIDL(pidls.SeekForward()); /// /// Adds the specified item as the last history entry and sets the property to /// it's value. /// /// The item to add to the history. /// /// indicates to remove all items forward of the current pointer; leaves the history intact. /// void IHistory.Add(ShellItem item, bool removeForwardItems) => pidls.Add(item?.PIDL, removeForwardItems); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); internal void Add(PIDL pidl) => pidls.Add(pidl, true); private static ShellItem ShIFromPIDL(PIDL pidl) => pidl is null ? null : new ShellItem(pidl); } }