Newer
Older
AutoTypeSearch / AutoTypeSearch / Options.cs
using System;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Windows.Forms;
using AutoTypeSearch.Properties;
using KeePass.Forms;
using KeePass.Plugins;
using KeePassLib;
using KeePassLib.Native;

namespace AutoTypeSearch
{
	internal partial class Options : UserControl
	{
		private const string OptionsConfigRoot = "AutoTypeSearchExt.";

		private static int sRegisteredHotkeyId;

		// ReSharper disable once MemberCanBePrivate.Global - Public for forms designer
		public Options()
		{
			InitializeComponent();

			// Must mach order and values of Actions enum
			var actions = new object[] { Resources.PerformAutoType, Resources.EditEntry, Resources.ShowEntry, Resources.OpenEntryUrl, Resources.CopyPassword };
			mDefaultAction.Items.AddRange(actions);
			mAlternativeAction.Items.AddRange(actions);

			// Read options
			mShowOnFailedSearch.Checked = Settings.Default.ShowOnFailedAutoType;

			if (NativeLib.IsUnix())
			{
				mShowOnHotKey.Enabled = false;
				mShowOnHotKey.Checked = false;

				mShowHotKeyControl.Clear();
			}
			else
			{
				mShowOnHotKey.Checked = Settings.Default.ShowOnHotKey;
				ShowHotKey = Settings.Default.ShowHotKey;
			}
			mShowOnHotKey_CheckedChanged(null, EventArgs.Empty);

			mShowOnIPC.Checked = Settings.Default.ShowOnIPC;
			mSearchInTitle.Checked = Settings.Default.SearchTitle;
			mSearchInUserName.Checked = Settings.Default.SearchUserName;
			mSearchInUrl.Checked = Settings.Default.SearchUrl;
			mSearchInNotes.Checked = Settings.Default.SearchNotes;
			mSearchInTags.Checked = Settings.Default.SearchTags;
			mSearchInOtherFields.Checked = Settings.Default.SearchCustomFields;

			mCaseSensitive.Checked = Settings.Default.CaseSensitive;
			mExcludeExpired.Checked = Settings.Default.ExcludeExpired;
			mResolveReferences.Checked = Settings.Default.ResolveReferences;

			mDefaultAction.SelectedIndex = (int)Settings.Default.DefaultAction;
			mAlternativeAction.SelectedIndex = (int)Settings.Default.AlternativeAction;

			mAdditionalSequences.BeginUpdate();
			mAdditionalSequences.Items.Clear();
			
			if (Settings.Default.AdditionalCustomSequences != null)
			{
				foreach (string s in Settings.Default.AdditionalCustomSequences)
				{
					mAdditionalSequences.Items.Add(s);
				}
			}
			
			mAdditionalSequences.EndUpdate();
		}

		private Keys ShowHotKey
		{
			get { return mShowHotKeyControl.HotKey; }
			set { mShowHotKeyControl.HotKey = value; }
		}

		private void mShowOnHotKey_CheckedChanged(object sender, EventArgs e)
		{
			mShowHotKeyControl.Enabled = mShowOnHotKey.Checked;
		}

		private void ApplySettings()
		{
			// Apply settings
			Settings.Default.ShowOnFailedAutoType = mShowOnFailedSearch.Checked;
			Settings.Default.ShowOnHotKey = mShowOnHotKey.Checked;
			Settings.Default.ShowOnIPC = mShowOnIPC.Checked;
			Settings.Default.SearchTitle = mSearchInTitle.Checked;
			Settings.Default.SearchUserName = mSearchInUserName.Checked;
			Settings.Default.SearchUrl = mSearchInUrl.Checked;
			Settings.Default.SearchNotes = mSearchInNotes.Checked;
			Settings.Default.SearchTags = mSearchInTags.Checked;
			Settings.Default.SearchCustomFields = mSearchInOtherFields.Checked;
			Settings.Default.CaseSensitive = mCaseSensitive.Checked;
			Settings.Default.ExcludeExpired = mExcludeExpired.Checked;
			Settings.Default.ResolveReferences = mResolveReferences.Checked;
			Settings.Default.DefaultAction = (Actions)mDefaultAction.SelectedIndex;
			Settings.Default.AlternativeAction = (Actions)mAlternativeAction.SelectedIndex;
			Settings.Default.ShowHotKey = ShowHotKey;

			Settings.Default.AdditionalCustomSequences = new System.Collections.Specialized.StringCollection();
			for (int i = 0; i < mAdditionalSequences.Items.Count; i++)
			{
				if (i != mAdditionalSequences.NewEntryIndex)
				{
					Settings.Default.AdditionalCustomSequences.Add(mAdditionalSequences.Items[i].ToString());
				}
			}

			ApplyHotKey();
		}

		#region Settings persistence
		public static void SaveSettings(IPluginHost host)
		{
			if (host != null)
			{
				foreach (SettingsPropertyValue property in Settings.Default.PropertyValues)
				{
					if (property.IsDirty)
					{
						var value = property.SerializedValue as String;
						if (value != null)
						{
							host.CustomConfig.SetString(OptionsConfigRoot + property.Name, value);
						}
						else
						{
							Debug.Fail("Non-string serialized settings property");
						}
					}
				}
			}
		}

		public static void LoadSettings(IPluginHost host)
		{
			if (host != null)
			{
				// ReSharper disable once UnusedVariable
				var ignored = Settings.Default.ShowOnFailedAutoType; //Access any property just to make it load settings.

				foreach (SettingsPropertyValue property in Settings.Default.PropertyValues)
				{
					var value = host.CustomConfig.GetString(OptionsConfigRoot + property.Name);
					if (value != null)
					{
						property.SerializedValue = value;
						property.Deserialized = false;
						property.IsDirty = false;
					}
				}

				ApplyHotKey();
			}
		}
		#endregion

		#region Hotkey
		private static void ApplyHotKey()
		{
			UnregisterHotKey();

			if (Settings.Default.ShowOnHotKey && Settings.Default.ShowHotKey != Keys.None)
			{
				sRegisteredHotkeyId = HotKeyManager.RegisterHotKey(Settings.Default.ShowHotKey);
			}
		}

		public static void UnregisterHotKey()
		{
			if (sRegisteredHotkeyId != 0)
			{
				var result = HotKeyManager.UnregisterHotKey(sRegisteredHotkeyId);
				Debug.Assert(result);
				sRegisteredHotkeyId = 0;
			}
		}
		#endregion

		private static OptionsForm sOptionsForm;
		public static void AddToWindow(OptionsForm optionsForm)
		{
			Options.sOptionsForm = optionsForm;
			var tabControl = optionsForm.Controls.Find("m_tabMain", false).FirstOrDefault() as TabControl;
			var okButton = optionsForm.Controls.Find("m_btnOK", false).FirstOrDefault() as Button;

			if (tabControl == null || okButton == null)
			{
				Debug.Fail("Could not integrate with options form");
			}

			var tabPage = new TabPage(Resources.AutoTypeSearch)
			{
				UseVisualStyleBackColor = true,
				AutoScroll = true,
				ImageIndex = (int)PwIcon.EMailSearch
			};
			var options = new Options { Dock = DockStyle.Fill };
			tabPage.Controls.Add(options);

			tabControl.TabPages.Add(tabPage);

			okButton.Click += delegate
			{
				options.ApplySettings();
			};
		}

		private void Options_Paint(object sender, PaintEventArgs e)
		{
			Rectangle r = new Rectangle(mPanel.Location, mPanel.ClientSize);
			//r.Offset(mPanel.Location);
			r.X -= 1;
			r.Y -= 1;
			r.Width += 2 + SystemInformation.VerticalScrollBarWidth;
			r.Height += 2;
			ControlPaint.DrawBorder(e.Graphics, r, SystemColors.GrayText, ButtonBorderStyle.Solid);
		}

		#region Prevent closing when editing
		private IButtonControl mOldOptionsAcceptButton;
		private IButtonControl mOldOptionsCancelButton;
		private int mSavedOldOptionsAcceptButton = 0;
		private int mSavedOldOptionsCancelButton = 0;

		private void SaveFormAcceptButton()
		{
			mSavedOldOptionsAcceptButton++;
			if (sOptionsForm != null && mSavedOldOptionsAcceptButton == 1)
			{
				mOldOptionsAcceptButton = sOptionsForm.AcceptButton;
				sOptionsForm.AcceptButton = null;
			}
		}

		private void RestoreFormAcceptButton()
		{
			if (mSavedOldOptionsAcceptButton > 0)
			{
				mSavedOldOptionsAcceptButton--;
				if (sOptionsForm != null && mSavedOldOptionsAcceptButton == 0)
				{
					sOptionsForm.AcceptButton = mOldOptionsAcceptButton;
				}
			}
		}

		private void SaveFormCancelButton()
		{
			mSavedOldOptionsCancelButton++;
			if (sOptionsForm != null && mSavedOldOptionsCancelButton == 1)
			{
				mOldOptionsCancelButton = sOptionsForm.CancelButton;
				sOptionsForm.CancelButton = null;
			}
		}

		private void RestoreFormCancelButton()
		{
			if (mSavedOldOptionsCancelButton > 0)
			{
				mSavedOldOptionsCancelButton--;
				if (sOptionsForm != null && mSavedOldOptionsCancelButton == 0)
				{
					sOptionsForm.CancelButton = mOldOptionsCancelButton;
				}
			}
		}
		private void mAdditionalSequences_StartEdit(object sender, EventArgs e)
		{
			SaveFormAcceptButton();
			SaveFormCancelButton();

			mPanel.ScrollControlIntoView(mAdditionalSequences);
		}

		private void mAdditionalSequences_FinishEdit(object sender, EventArgs e)
		{
			RestoreFormAcceptButton();
			RestoreFormCancelButton();
		}

		private void mAdditionalSequences_SelectedIndexChanged(object sender, EventArgs e)
		{
			mPanel.ScrollControlIntoView(mAdditionalSequences);
		}

		#endregion

		#region Additional sequence list focusing
		private bool mAdditionalSequencesFocused = false;
		private void mAdditionalSequences_Enter(object sender, EventArgs e)
		{
			if (mAdditionalSequencesFocused) return;
			mAdditionalSequencesFocused = true;

			SaveFormAcceptButton();
		}

		private void mAdditionalSequences_Leave(object sender, EventArgs e)
		{
			if (!mAdditionalSequencesFocused) return;
			mAdditionalSequencesFocused = false;

			RestoreFormAcceptButton();
		}
		#endregion

		private void mAdditionalSequences_FinishEdit(object sender, FinishEditEventArgs e)
		{

		}
	}
}