using PaintDotNet.Data.Param; using PaintDotNet.Base.SettingModel; using PaintDotNet.SystemLayer; using System; using System.ComponentModel; using System.Drawing; using System.IO; using System.Reflection; using System.Windows.Forms; namespace PaintDotNet { internal class PdnMenuItem : ToolStripMenuItem, IFormAssociate { /// /// 是否可以用在脚本功能里,默认true /// private bool canUseInScript = true; /// /// true可以自动执行 false只能手动执行,默认true /// private bool automaticScript = true; /// /// true自动执行下一步 false手动点击下一步执行,默认false /// private bool autoNextScript = false; /// /// 脚本是否必须打开窗口,并等待执行完成后才能继续的处理(针对通用分析和专用分析) /// private bool needOpenDialog = false; /// /// 脚本是否需要加等待执行完成后才能继续的处理 /// private bool needWaitKey = false; /// /// 是否可以选中 /// public bool canChecked = false; /// /// AppWorkspace的引用 /// private AppWorkspace appWorkspace; private string textResourceName = null; private const char noMnemonicChar = (char)0; private const char mnemonicPrefix = '&'; /// /// icon loaded的标记 /// private bool iconsLoaded = false; /// /// 标题 loaded的标记 /// private bool namesLoaded = false; /// /// 快捷键 /// private Keys registeredHotKey = Keys.None; /// /// 当前菜单的唯一id /// private int menuId; public int MenuId { get { return this.menuId; } set { this.menuId = value; } } public bool CanUseInSenseShield { get { System.Collections.Generic.List menuIdlists = new System.Collections.Generic.List(); menuIdlists.Add(this.menuId); PdnMenuItem menuItem = this; while (menuItem.OwnerItem != null && menuItem.OwnerItem is PdnMenuItem) { menuIdlists.Insert(0, ((PdnMenuItem)menuItem.OwnerItem).menuId); menuItem = (PdnMenuItem)menuItem.OwnerItem; } return Startup.getMenuIdUsable(menuIdlists, true); } } /// /// 是否授权显示该菜单 /// public bool CanShowInSenseShield { get { return Startup.getMenuIdVisible(this.menuId); } } /// /// 是否可以用在脚本功能里,默认true /// public bool CanUseInScript { get { return this.canUseInScript; } set { this.canUseInScript = value; } } /// /// true可以自动执行 false只能手动执行,默认true /// public bool AutomaticScript { get { return this.automaticScript; } set { this.automaticScript = value; } } /// /// true自动执行下一步 false手动点击下一步执行,默认false /// public bool AutoNextScript { get { return this.autoNextScript; } set { this.autoNextScript = value; } } /// /// 脚本是否必须打开窗口,并等待执行完成后才能继续的处理(针对通用分析和专用分析) /// public bool NeedOpenDialog { get { return this.needOpenDialog; } set { this.needOpenDialog = value; } } /// /// 脚本是否需要加等待执行完成后才能继续的处理 /// public bool NeedWaitKey { get { return this.needWaitKey; } set { this.needWaitKey = value; } } [Browsable(false)] public AppWorkspace AppWorkspace { get { return this.appWorkspace; } set { if (value != this.appWorkspace) { OnAppWorkspaceChanging(); this.appWorkspace = value; OnAppWorkspaceChanged(); } } } public Form AssociatedForm { get { if (this.appWorkspace == null) { return null; } else { return this.appWorkspace.FindForm(); } } } public new Keys ShortcutKeys { get { return base.ShortcutKeys; } set { if (ShortcutKeys != Keys.None) { PdnBaseForm.UnregisterFormHotKey(ShortcutKeys, OnShortcutKeyPressed); } PdnBaseForm.RegisterFormHotKey(value, OnShortcutKeyPressed); base.ShortcutKeys = value; } } public void resetShortcutKeys(string itemHotKeys) { if (itemHotKeys != null && !itemHotKeys.Equals("")) { string[] keys = itemHotKeys.Trim().Split('+'); Keys Key = Keys.None; foreach (string key in keys) { if (Key == Keys.None) { Key = (Keys)(Enum.Parse(typeof(Keys), key.Trim())); } else { Key = (Keys)(Enum.Parse(typeof(Keys), key.Trim())) | Key; } } this.ShortcutKeys = Key; } else { this.ShortcutKeys = Keys.None; } } public bool HasMnemonic { get { return (Mnemonic != noMnemonicChar); } } public char Mnemonic { get { if (string.IsNullOrEmpty(this.Text)) { return noMnemonicChar; } int mnemonicPrefixIndex = this.Text.IndexOf(mnemonicPrefix); if (mnemonicPrefixIndex >= 0 && mnemonicPrefixIndex < this.Text.Length - 1) { return this.Text[mnemonicPrefixIndex + 1]; } else { return noMnemonicChar; } } } public void PerformClickAsync() { this.Owner.BeginInvoke(new Procedure(this.PerformClick)); } protected virtual void OnAppWorkspaceChanging() { foreach (ToolStripItem item in this.DropDownItems) { PdnMenuItem asPMI = item as PdnMenuItem; if (asPMI != null) { asPMI.AppWorkspace = null; } } } protected virtual void OnAppWorkspaceChanged() { foreach (ToolStripItem item in this.DropDownItems) { PdnMenuItem asPMI = item as PdnMenuItem; if (asPMI != null) { asPMI.AppWorkspace = AppWorkspace; } } } public PdnMenuItem(string name, Image image, EventHandler eventHandler) : base(name, image, eventHandler) { Constructor(); } /// /// 目前用的构造方法 /// /// public PdnMenuItem(ActionType type) { Constructor(); //设置快捷键,如果配置了 SetHotKeyFromConfig((int)type); //设置名称 this.Name = GetDescription(type); //设置id this.MenuId = (int)type; } public PdnMenuItem(ActionType type, bool canChecked) { Constructor(); //设置快捷键,如果配置了 SetHotKeyFromConfig((int)type); //设置名称 this.Name = GetDescription(type); //设置id this.MenuId = (int)type; //设置可以被选中 this.canChecked = canChecked; } public PdnMenuItem() { Constructor(); } private void Constructor() { InitializeComponent(); } private void InitializeComponent() { this.DropDownOpening += new EventHandler(PdnMenuItem_DropDownOpening); } private bool OnShortcutKeyPressed(Keys keys) { //PerformClick(); return true; } private bool OnAccessHotKeyPressed(Keys keys) { ShowDropDown(); return true; } protected override void OnTextChanged(EventArgs e) { if (this.registeredHotKey != Keys.None) { PdnBaseForm.UnregisterFormHotKey(this.registeredHotKey, OnAccessHotKeyPressed); } char mnemonic = this.Mnemonic; if (mnemonic != noMnemonicChar && !IsOnDropDown) { Keys hotKey = Utility.LetterOrDigitCharToKeys(mnemonic);//快捷键,通过alt+key打开一级菜单 PdnBaseForm.RegisterFormHotKey(Keys.Alt | hotKey, OnAccessHotKeyPressed);//快捷键,通过alt+key打开一级菜单 } base.OnTextChanged(e); } private void PdnMenuItem_DropDownOpening(object sender, EventArgs e) { OnDropDownOpening(e); } protected virtual void OnDropDownOpening(EventArgs e) { if (!this.namesLoaded) { LoadNames(this.Name); } if (!this.iconsLoaded) { LoadIcons(); } } /// /// 递归查找菜单,如果脚本正在执行,则菜单不可手动点击 /// /// /// protected void RecursiveData(ToolStripItemCollection collection) { if (!AppWorkspace.ScriptRunning) return; Boolean enabled = false; for (int i = 0; i < collection.Count; i++) { if (collection[i] is PdnMenuItem) { ((PdnMenuItem)collection[i]).Enabled = enabled; //RecursiveData(((PdnMenuItem)collection[i]).DropDownItems); } //if (!collection[i].Name.Equals("OpenRecent") && !collection[i].Name.Equals("CameraSelection")) //{ //} } } public void LoadNames(string baseName) { foreach (ToolStripItem item in this.DropDownItems) { if(!string.IsNullOrWhiteSpace(item.Name)) { string itemNameBase = baseName + "." + item.Name; string itemNameText = itemNameBase + ".Text"; string text = PdnResources.GetString(itemNameText); if (text != null) { item.Text = text; } PdnMenuItem pmi = item as PdnMenuItem; if (pmi != null) { pmi.textResourceName = itemNameText; pmi.LoadNames(itemNameBase); } } } this.namesLoaded = true; } public void SetIcon(string imageName) { this.ImageTransparentColor = Utility.TransparentKey; this.Image = PdnResources.GetImageResource(imageName).Reference; } public void SetIcon(ImageResource image) { this.ImageTransparentColor = Utility.TransparentKey; this.Image = image.Reference; } public void LoadIcons() { Type ourType = this.GetType(); FieldInfo[] fields = ourType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach (FieldInfo fi in fields) { if (fi.FieldType.IsSubclassOf(typeof(PdnMenuItem)) || fi.FieldType == typeof(PdnMenuItem)) { string iconFileName = "Icons." + fi.Name[0].ToString().ToUpper() + fi.Name.Substring(1) + "Icon.png"; PdnMenuItem mi = (PdnMenuItem)fi.GetValue(this); Stream iconStream = PdnResources.GetResourceStream(iconFileName); if (iconStream != null) { iconStream.Dispose(); mi.SetIcon(iconFileName); } else { Tracing.Ping(iconFileName + " not found"); } } } this.iconsLoaded = true; } protected override void OnDropDownClosed(EventArgs e) { foreach (ToolStripItem item in this.DropDownItems) { item.Enabled = true; } base.OnDropDownClosed(e); } protected override void OnClick(EventArgs e) { if ((this.DropDownItems == null || this.DropDownItems.Count == 0) && !this.CanUseInSenseShield) { string featureNameNotShield = this.Name ?? this.Text; Tracing.LogFeature(featureNameNotShield + "not shield"); return; } var form = Form.ActiveForm; if (form != null) { form.BeginInvoke(new Procedure(PdnBaseForm.UpdateAllForms)); } string featureName = this.Name ?? this.Text; Tracing.LogFeature(featureName); base.OnClick(e); } private void SetHotKeyFromConfig(int menuId) { if (Startup.instance.hotkeyModel != null && Startup.instance.hotkeyModel.items != null && Startup.instance.hotkeyModel.items.Count > 0) { HotkeyModel.Item item = Startup.instance.hotkeyModel.items.Find(m => m.MenuId == menuId); if (item!=null) { if (item.HotKeys != null && !item.HotKeys.Equals("")) { string[] keys = item.HotKeys.Trim().Split('+'); Keys Key = Keys.None; foreach (string key in keys) { if (Key == Keys.None) { Key = (Keys)(Enum.Parse(typeof(Keys), key.Trim())); } else { Key = (Keys)(Enum.Parse(typeof(Keys), key.Trim())) | Key; } } this.ShortcutKeys = Key; } } } } /// /// 获取枚举的描述 /// /// 枚举 /// 返回枚举的描述 public static string GetDescription(Enum en) { Type type = en.GetType(); //获取类型 MemberInfo[] memberInfos = type.GetMember(en.ToString()); //获取成员 if (memberInfos != null && memberInfos.Length > 0) { DescriptionAttribute[] attrs = memberInfos[0].GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[]; //获取描述特性 if (attrs != null && attrs.Length > 0) { return attrs[0].Description; //返回当前描述 } } return en.ToString(); } } }