1 /* 2 KeePass Password Safe - The Open-Source Password Manager 3 Copyright (C) 2003-2021 Dominik Reichl <dominik.reichl@t-online.de> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 using System; 21 using System.Collections.Generic; 22 using System.Diagnostics; 23 using System.Drawing; 24 using System.Text; 25 using System.Windows.Forms; 26 27 using KeePassLib.Delegates; 28 using KeePassLib.Utility; 29 30 namespace KeePass.UI 31 { 32 internal sealed class MenuItemLinks 33 { 34 private readonly Dictionary<ToolStripItem, ToolStripItem> m_dCopies = 35 new Dictionary<ToolStripItem, ToolStripItem>(); 36 CreateCopy(ToolStripItemCollection tsicTarget, ToolStripItem tsiPosRef, bool bAfter, ToolStripMenuItem tsmiBase)37 public void CreateCopy(ToolStripItemCollection tsicTarget, 38 ToolStripItem tsiPosRef, bool bAfter, ToolStripMenuItem tsmiBase) 39 { 40 if(tsicTarget == null) { Debug.Assert(false); return; } 41 if(tsmiBase == null) { Debug.Assert(false); return; } 42 43 ToolStripMenuItem tsmi = new ToolStripMenuItem(); 44 45 string strName = tsmiBase.Name, strNameNew = null; 46 if(!string.IsNullOrEmpty(strName)) 47 { 48 if(strName.StartsWith("m_menu", StrUtil.CaseIgnoreCmp)) 49 strNameNew = "m_ctx" + strName.Substring(6); 50 } 51 if(!string.IsNullOrEmpty(strNameNew)) 52 { 53 ToolStripItem[] v = tsicTarget.Find(strNameNew, true); 54 if((v == null) || (v.Length == 0)) 55 tsmi.Name = strNameNew; 56 else { Debug.Assert(false); } 57 } 58 else { Debug.Assert(false); } 59 60 CreateLink(tsmi, tsmiBase, (tsmiBase.DropDownItems.Count == 0)); 61 62 int i, n = tsicTarget.Count; 63 if(tsiPosRef == null) i = (bAfter ? n : 0); 64 else 65 { 66 i = tsicTarget.IndexOf(tsiPosRef); 67 if(i < 0) { Debug.Assert(false); i = n; } 68 else if(bAfter) ++i; 69 } 70 71 tsicTarget.Insert(i, tsmi); 72 73 foreach(ToolStripItem tsiSub in tsmiBase.DropDownItems) 74 { 75 ToolStripMenuItem tsmiSub = (tsiSub as ToolStripMenuItem); 76 if(tsmiSub != null) 77 CreateCopy(tsmi.DropDownItems, null, true, tsmiSub); 78 else if(tsiSub is ToolStripSeparator) 79 tsmi.DropDownItems.Add(new ToolStripSeparator()); 80 else { Debug.Assert(false); } 81 } 82 } 83 CreateLink(ToolStripMenuItem tsmi, ToolStripMenuItem tsmiBase, bool bHandleClick)84 public void CreateLink(ToolStripMenuItem tsmi, ToolStripMenuItem tsmiBase, 85 bool bHandleClick) 86 { 87 if(tsmi == null) { Debug.Assert(false); return; } 88 if(tsmiBase == null) { Debug.Assert(false); return; } 89 90 tsmi.Text = tsmiBase.Text; 91 tsmiBase.TextChanged += delegate(object sender, EventArgs e) 92 { 93 Debug.Assert(sender == tsmiBase); 94 Debug.Assert(tsmi.Text != tsmiBase.Text); 95 try { tsmi.Text = tsmiBase.Text; } 96 catch(Exception) { Debug.Assert(false); } 97 }; 98 99 tsmi.Image = tsmiBase.Image; 100 Debug.Assert(object.ReferenceEquals(tsmi.Image, tsmiBase.Image)); 101 Debug.Assert(tsmiBase.ImageTransparentColor == Color.Empty); 102 103 tsmi.Size = tsmiBase.Size; 104 105 // Getting 'Visible' also checks parent 106 tsmi.Available = tsmiBase.Available; 107 tsmiBase.AvailableChanged += delegate(object sender, EventArgs e) 108 { 109 Debug.Assert(sender == tsmiBase); 110 Debug.Assert(tsmi.Available != tsmiBase.Available); 111 try { tsmi.Available = tsmiBase.Available; } 112 catch(Exception) { Debug.Assert(false); } 113 }; 114 115 VoidDelegate fCopyEnabled = delegate() 116 { 117 // Check (direct) owner state; see ToolStripItem.Enabled 118 ToolStrip tsOwner = tsmiBase.Owner; 119 if((tsOwner != null) && !tsOwner.Enabled) 120 { 121 Debug.Assert(false); // tsmiBase.Enabled unusable 122 return; 123 } 124 tsmi.Enabled = tsmiBase.Enabled; 125 }; 126 127 fCopyEnabled(); 128 tsmiBase.EnabledChanged += delegate(object sender, EventArgs e) 129 { 130 Debug.Assert(sender == tsmiBase); 131 Debug.Assert(tsmi.Enabled != tsmiBase.Enabled); 132 try { fCopyEnabled(); } 133 catch(Exception) { Debug.Assert(false); } 134 }; 135 136 string strSh = tsmiBase.ShortcutKeyDisplayString; 137 if(!string.IsNullOrEmpty(strSh)) tsmi.ShortcutKeyDisplayString = strSh; 138 139 if(bHandleClick) 140 { 141 Debug.Assert(tsmiBase.DropDownItems.Count == 0); 142 tsmi.Click += delegate(object sender, EventArgs e) 143 { 144 Debug.Assert(sender == tsmi); 145 try { tsmiBase.PerformClick(); } 146 catch(Exception) { Debug.Assert(false); } 147 }; 148 } 149 150 Debug.Assert(!m_dCopies.ContainsKey(tsmiBase)); // One copy only 151 m_dCopies[tsmiBase] = tsmi; 152 } 153 SetCopyAvailable(ToolStripMenuItem tsmiBase, bool bAvailable)154 public void SetCopyAvailable(ToolStripMenuItem tsmiBase, bool bAvailable) 155 { 156 if(tsmiBase == null) { Debug.Assert(false); return; } 157 158 ToolStripItem tsi; 159 if(!m_dCopies.TryGetValue(tsmiBase, out tsi)) { Debug.Assert(false); return; } 160 tsi.Available = bAvailable; 161 } 162 SetImage(ToolStripMenuItem tsmiBase, Image img)163 public void SetImage(ToolStripMenuItem tsmiBase, Image img) 164 { 165 if(tsmiBase == null) { Debug.Assert(false); return; } 166 167 tsmiBase.Image = img; 168 169 ToolStripItem tsi; 170 if(!m_dCopies.TryGetValue(tsmiBase, out tsi)) { Debug.Assert(false); return; } 171 tsi.Image = img; 172 } 173 } 174 } 175