context: /*
    KeePass Password Safe - The Open-Source Password Manager
    Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
  
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
  
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
  
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
  
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Windows.Forms;
  using System.Drawing;
  using System.Globalization;
  using System.Diagnostics;
  
  using KeePass.Resources;
  
  using KeePassLib;
  using KeePassLib.Serialization;
  using KeePassLib.Utility;
  
  namespace KeePass.UI
  {
  	/// <summary>
  	/// MRU handler interface. An MRU handler must support executing an MRU
  	/// item and clearing the MRU list.
  	/// </summary>
  	public interface IMruExecuteHandler
  	{
  		/// <summary>
  		/// Function that is called when an MRU item is executed (i.e. when
  		/// the user has clicked the menu item).
  		/// </summary>
  		void OnMruExecute(string strDisplayName, object oTag,
  			ToolStripMenuItem tsmiParent);
  
  		/// <summary>
  		/// Function to clear the MRU (for example all menu items must be
  		/// removed from the menu).
  		/// </summary>
  		void OnMruClear();
  	}
  
  	public sealed class MruList
  	{
  		private List<KeyValuePair<string, object>> m_vItems =
  			new List<KeyValuePair<string, object>>();
  
  		private IMruExecuteHandler m_handler = null;
  		private List<ToolStripMenuItem> m_lContainers =
  			new List<ToolStripMenuItem>();
  
  		private ToolStripMenuItem m_tsmiClear = null;
  		private List<ToolStripMenuItem> m_lMruMenuItems =
  			new List<ToolStripMenuItem>();
  
  		private enum MruMenuItemType
  		{
  			None = 0,
  			Item,
  			Clear
  		}
  
  		// private Font m_fItalic = null;
  
  		private uint m_uMaxItemCount = 0;
  		public uint MaxItemCount
  		{
  			get { return m_uMaxItemCount; }
  			set { m_uMaxItemCount = value; }
  		}
  
  		private bool m_bMarkOpened = false;
  		public bool MarkOpened
  		{
  			get { return m_bMarkOpened; }
  			set { m_bMarkOpened = value; }
  		}
  
  		public uint ItemCount
  		{
  			get { return (uint)m_vItems.Count; }
  		}
  
  		public bool IsValid
  		{
  			get { return (m_handler != null); }
  		}
  
  		public MruList()
  		{
  		}
  
  		public void Initialize(IMruExecuteHandler handler,
  			params ToolStripMenuItem[] vContainers)
  		{
  			Release();
  
  			Debug.Assert(handler != null); // No throw
  			m_handler = handler;
  
  			if(vContainers != null)
  			{
  				foreach(ToolStripMenuItem tsmi in vContainers)
  				{
  					if(tsmi != null)
  					{
  						m_lContainers.Add(tsmi);
  
  						tsmi.DropDownOpening += this.OnDropDownOpening;
  					}
  				}
  			}
  		}
  
  		public void Release()
  		{
  			ReleaseMenuItems();
  
  			foreach(ToolStripMenuItem tsmi in m_lContainers)
  			{
  				tsmi.DropDownOpening -= this.OnDropDownOpening;
  			}
  			m_lContainers.Clear();
  
  			m_handler = null;
  		}
  
  		private void ReleaseMenuItems()
  		{
  			if(m_tsmiClear != null)
  			{
  				m_tsmiClear.Click -= this.ClearHandler;
  				m_tsmiClear = null;
  			}
  
  			foreach(ToolStripMenuItem tsmi in m_lMruMenuItems)
  			{
  				tsmi.Click -= this.ClickHandler;
  			}
  			m_lMruMenuItems.Clear();
  		}
  
  		public void Clear()
  		{
  			m_vItems.Clear();
  		}
  
  		[Obsolete]
  		public void AddItem(string strDisplayName, object oTag, bool bUpdateMenu)
  		{
  			AddItem(strDisplayName, oTag);
  		}
  
  		public void AddItem(string strDisplayName, object oTag)
  		{
  			Debug.Assert(strDisplayName != null);
  			if(strDisplayName == null) throw new ArgumentNullException("strDisplayName");
  			// oTag may be null
  
  			bool bExists = false;
  			foreach(KeyValuePair<string, object> kvp in m_vItems)
  			{
  				Debug.Assert(kvp.Key != null);
  				if(kvp.Key.Equals(strDisplayName, StrUtil.CaseIgnoreCmp))
  				{
  					bExists = true;
  					break;
  				}
  			}
  
  			if(bExists) MoveItemToTop(strDisplayName, oTag);
  			else
  			{
  				m_vItems.Insert(0, new KeyValuePair<string, object>(
  					strDisplayName, oTag));
  
  				if(m_vItems.Count > m_uMaxItemCount)
  					m_vItems.RemoveAt(m_vItems.Count - 1);
  			}
  
  			// if(bUpdateMenu) UpdateMenu();
  		}
  
  		private void MoveItemToTop(string strName, object oNewTag)
  		{
  			for(int i = 0; i < m_vItems.Count; ++i)
  			{
  				if(m_vItems[i].Key.Equals(strName, StrUtil.CaseIgnoreCmp))
  				{
  					KeyValuePair<string, object> t =
  
gt: 						new KeyValuePair<string, object>(strName, oNewTag);