mirror of https://github.com/dahall/Vanara.git
151 lines
6.5 KiB
C#
151 lines
6.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using Vanara.Configuration;
|
|
using Vanara.Extensions;
|
|
|
|
namespace Vanara.Windows.Forms;
|
|
|
|
/// <summary>
|
|
/// A class that manages a Most Recently Used file listing and interacts with a MenuStrip to display a menu list of the files. By
|
|
/// default, the application settings are used to store the history. Optionally a constructor can be used to provide an alternate class
|
|
/// to handle that work.
|
|
/// </summary>
|
|
[DefaultProperty("RecentFileMenuItem")]
|
|
public class MenuStripMRUManager : MRUManager
|
|
{
|
|
/// <summary>Initializes a new instance of the <see cref="MenuStripMRUManager"/> class.</summary>
|
|
public MenuStripMRUManager() : base(new AppSettingsFileListStorage(), new MenuStripMenuBuilder())
|
|
{
|
|
}
|
|
|
|
/// <summary>Initializes a new instance of the <see cref="MRUManager"/> class.</summary>
|
|
/// <param name="extensions">The extensions of files to find in system MRU list.</param>
|
|
/// <param name="parentMenuItem">The parent "Recent Files" menu item.</param>
|
|
/// <param name="onRecentFileClick">Action to run when The on recent file click.</param>
|
|
/// <param name="onClearRecentFilesClick">Optional. The on clear recent files click.</param>
|
|
/// <param name="storageHandler">Optional. The storage handler.</param>
|
|
public MenuStripMRUManager(string extensions, ToolStripMenuItem parentMenuItem, Action<string> onRecentFileClick,
|
|
Action<StringCollection> onClearRecentFilesClick = null, IFileListStorage storageHandler = null)
|
|
: base(storageHandler ?? new AppSettingsFileListStorage(), new MenuStripMenuBuilder())
|
|
{
|
|
FileExtensions = extensions;
|
|
((MenuStripMenuBuilder)MenuBuilderHandler).RecentFileMenuItem = parentMenuItem;
|
|
if (onRecentFileClick != null)
|
|
RecentFileMenuItemClick += onRecentFileClick;
|
|
if (onClearRecentFilesClick != null)
|
|
ClearListMenuItemClick += onClearRecentFilesClick;
|
|
|
|
RefreshRecentFilesMenu();
|
|
}
|
|
|
|
/// <summary>Gets or sets the clear list menu item image.</summary>
|
|
/// <value>The clear list menu item image.</value>
|
|
[Category("Appearance"), DefaultValue(null), Description("The clear list menu item icon."), Localizable(true)]
|
|
public Image ClearListMenuItemImage
|
|
{
|
|
get => clearListMenuItemImage as Image;
|
|
set
|
|
{
|
|
if (value is null)
|
|
throw new ArgumentException("Must be of type Image.");
|
|
clearListMenuItemImage = value;
|
|
RefreshRecentFilesMenu();
|
|
}
|
|
}
|
|
|
|
/// <summary>Gets or sets the recent file menu item.</summary>
|
|
/// <value>The recent file menu item.</value>
|
|
[DefaultValue(null), Category("Behavior"), Description("The recent file menu item.")]
|
|
public ToolStripMenuItem RecentFileMenuItem
|
|
{
|
|
get => ((MenuStripMenuBuilder)MenuBuilderHandler).RecentFileMenuItem;
|
|
set { ((MenuStripMenuBuilder)MenuBuilderHandler).RecentFileMenuItem = value; RefreshRecentFilesMenu(); }
|
|
}
|
|
|
|
/// <summary>Builds a menu within a MenuStrip.</summary>
|
|
private class MenuStripMenuBuilder : IMenuBuilder
|
|
{
|
|
private Action<string> fileMenuItemClickAction;
|
|
|
|
/// <summary>Gets or sets the recent file menu item.</summary>
|
|
/// <value>The recent file menu item.</value>
|
|
public ToolStripMenuItem RecentFileMenuItem { get; set; }
|
|
|
|
/// <summary>Clears the recent files.</summary>
|
|
public void ClearRecentFiles()
|
|
{
|
|
if (RecentFileMenuItem == null) return;
|
|
RecentFileMenuItem.DropDownItems.Clear();
|
|
RecentFileMenuItem.Enabled = false;
|
|
}
|
|
|
|
/// <summary>Rebuilds the menus.</summary>
|
|
/// <param name="files">The file listing.</param>
|
|
/// <param name="fileMenuItemClick">The handler for when one of the automatically added recent file menu items is clicked..</param>
|
|
/// <param name="clearListMenuItemText">
|
|
/// The clear list menu item text. A <c>null</c> value indicates that this menu item should not be shown.
|
|
/// </param>
|
|
/// <param name="clearListMenuItemClick">The handler for when the clear recent files menu item is clicked.</param>
|
|
/// <param name="clearListMenuItemImage">
|
|
/// The clear list menu item image. A <c>null</c> value indicates that this menu item's image should not be shown.
|
|
/// </param>
|
|
/// <param name="clearListMenuItemOnTop">if set to <see langword="true"/>, the clear list menu item precedes the files.</param>
|
|
/// <param name="menuImageCallback">The menu image callback delegate.</param>
|
|
public void RebuildMenus(IEnumerable<string> files, Action<string> fileMenuItemClick, string clearListMenuItemText = null, Action clearListMenuItemClick = null, object clearListMenuItemImage = null, bool clearListMenuItemOnTop = false, Func<string, object> menuImageCallback = null)
|
|
{
|
|
if (RecentFileMenuItem == null) return;
|
|
|
|
RecentFileMenuItem.DropDownItems.Clear();
|
|
|
|
if (files is null || !files.Any())
|
|
{
|
|
RecentFileMenuItem.Enabled = false;
|
|
return;
|
|
}
|
|
|
|
if (clearListMenuItemOnTop && !string.IsNullOrEmpty(clearListMenuItemText))
|
|
{
|
|
RecentFileMenuItem.DropDownItems.Add(clearListMenuItemText, clearListMenuItemImage as Image, (o, e) => clearListMenuItemClick?.Invoke());
|
|
RecentFileMenuItem.DropDownItems.Add("-");
|
|
}
|
|
|
|
fileMenuItemClickAction = fileMenuItemClick;
|
|
foreach (var f in files)
|
|
{
|
|
RecentFileMenuItem.DropDownItems.Add(new ToolStripMenuItem(CompactPath(RecentFileMenuItem.GetCurrentParent().CreateGraphics(), f, RecentFileMenuItem.Font, RecentFileMenuItem.Width), menuImageCallback?.Invoke(f) as Image, OnFileMenuItemClick) { Tag = f });
|
|
}
|
|
|
|
if (!clearListMenuItemOnTop && !string.IsNullOrEmpty(clearListMenuItemText))
|
|
{
|
|
RecentFileMenuItem.DropDownItems.Add("-");
|
|
RecentFileMenuItem.DropDownItems.Add(clearListMenuItemText, clearListMenuItemImage as Image, (o, e) => clearListMenuItemClick?.Invoke());
|
|
}
|
|
RecentFileMenuItem.Enabled = true;
|
|
}
|
|
|
|
/// <summary>Compacts the path.</summary>
|
|
/// <param name="g">The Graphics instance to use.</param>
|
|
/// <param name="stringToCompact">The string to compact.</param>
|
|
/// <param name="font">The font.</param>
|
|
/// <param name="maxWidthInPts">The maximum width in PTS.</param>
|
|
/// <returns>The compacted string.</returns>
|
|
private static string CompactPath(Graphics g, string stringToCompact, Font font, int maxWidthInPts)
|
|
{
|
|
var sb = new StringBuilder(stringToCompact);
|
|
g.MeasureText(sb, font, new Size(maxWidthInPts, 0), TextFormatFlags.PathEllipsis | TextFormatFlags.ModifyString);
|
|
return sb.ToString(); // string.Concat(stringToCompact.TakeWhile(c => c != '\0'));
|
|
}
|
|
|
|
private void OnFileMenuItemClick(object sender, EventArgs e)
|
|
{
|
|
if (sender is ToolStripMenuItem item)
|
|
fileMenuItemClickAction(item.Tag.ToString());
|
|
}
|
|
}
|
|
} |