307 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			307 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.ComponentModel;
 | 
						|
using System.Data;
 | 
						|
using System.Drawing;
 | 
						|
using System.Text;
 | 
						|
using System.Windows.Forms;
 | 
						|
using DevComponents.DotNetBar;
 | 
						|
using C1.Win.C1SpellChecker;
 | 
						|
 | 
						|
namespace Volian.Controls.Library
 | 
						|
{
 | 
						|
	// Our custom Spell Checker dialog
 | 
						|
	public partial class VlnSpellCheckDlg : DevComponents.DotNetBar.Office2007Form, ISpellDialog
 | 
						|
	{
 | 
						|
		private C1SpellChecker _Spell;
 | 
						|
		private ISpellCheckableEditor _Editor;
 | 
						|
		private CharRangeList _Errors;
 | 
						|
		private int _ErrorCount;
 | 
						|
		private int _ErrorIndex = -1;       // current error index
 | 
						|
		private bool _AutoSuggest = true;
 | 
						|
		private string _NoSuggestionsText = "(no suggestions)";
 | 
						|
 | 
						|
		Dictionary<string, string> _changeAll = new Dictionary<string, string>();
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Gets the <see cref="CharRange"/> object that represents the error currently 
 | 
						|
		/// displayed in the dialog.
 | 
						|
		/// </summary>
 | 
						|
		public CharRange CurrentError
 | 
						|
		{
 | 
						|
			get { return _Errors[_ErrorIndex]; }
 | 
						|
		}
 | 
						|
		public bool DidCorrectSpelling = false;  // B2015-024  have Spell Checker text changes be in editorial mode (not assign a change bar but keep existing change bar)
 | 
						|
 | 
						|
		public VlnSpellCheckDlg()
 | 
						|
		{
 | 
						|
			InitializeComponent();
 | 
						|
		}
 | 
						|
		/// <summary>
 | 
						|
		/// Initializes the dialog to use the given parameters.
 | 
						|
		/// </summary>
 | 
						|
		/// <param name="spell"><see cref="C1SpellChecker"/> to use for spelling.</param>
 | 
						|
		/// <param name="editor"><see cref="ISpellCheckableEditor"/> that contains the text to spell-check.</param>
 | 
						|
		/// <param name="errors"><see cref="CharRangeList"/> that contains the initial error list.</param>
 | 
						|
		public void Initialize(C1SpellChecker spell, ISpellCheckableEditor editor, CharRangeList errors)
 | 
						|
		{
 | 
						|
			_Spell = spell;
 | 
						|
			_Editor = editor;
 | 
						|
			_Errors = errors;
 | 
						|
			if (_Errors == null)
 | 
						|
			{
 | 
						|
				_Errors = _Spell.CheckText(_Editor.Text);
 | 
						|
			}
 | 
						|
			_ErrorCount += _Errors.Count;
 | 
						|
			btnAddToDictionary.Visible = _Spell.UserDictionary.Enabled;
 | 
						|
		}
 | 
						|
		/// <summary>
 | 
						|
		/// Gets the total number of errors detected in the control.
 | 
						|
		/// </summary>
 | 
						|
		public int ErrorCount
 | 
						|
		{
 | 
						|
			get { return _ErrorCount; }
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Gets or sets the index of the current error into the <see cref="Errors"/> list.
 | 
						|
		/// </summary>
 | 
						|
		public int ErrorIndex
 | 
						|
		{
 | 
						|
			get { return _ErrorIndex; }
 | 
						|
			set
 | 
						|
			{
 | 
						|
				_ErrorIndex = value;
 | 
						|
				UpdateCurrentError();
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		private void UpdateEditor(string replacement)
 | 
						|
		{
 | 
						|
			DidCorrectSpelling = true;
 | 
						|
			// save starting point to continue checking from here
 | 
						|
			int start = CurrentError.Start;
 | 
						|
 | 
						|
			if (replacement.Length == 0)
 | 
						|
			{
 | 
						|
				// if replacement is empty, expand over spaces and commas
 | 
						|
				CharRange delete = CharRange.ExpandOverWhitespace(_Editor.Text, CurrentError);
 | 
						|
				_Editor.Select(delete.Start, delete.Text.Length);
 | 
						|
			}
 | 
						|
 | 
						|
			// replace word in text and re-check
 | 
						|
			_Editor.SelectedText = replacement;
 | 
						|
			_Errors = _Spell.CheckText(_Editor.Text, start);
 | 
						|
 | 
						|
			// update index
 | 
						|
			ErrorIndex = ErrorIndex; // originally 0;
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Raises the <see cref="Form.Load"/> event.
 | 
						|
		/// </summary>
 | 
						|
		/// <param name="e"><see cref="EventArgs"/> that contains the event data.</param>
 | 
						|
		protected override void OnLoad(EventArgs e)
 | 
						|
		{
 | 
						|
			// fire load event
 | 
						|
			base.OnLoad(e);
 | 
						|
			//AddHandle();
 | 
						|
			// show first error (after firing load event)
 | 
						|
			ErrorIndex = 0;
 | 
						|
		}
 | 
						|
		// added for debugging - comment out when not using
 | 
						|
		//public void AddHandle()
 | 
						|
		//{
 | 
						|
		//	if (!Handles.Contains(this.Handle))
 | 
						|
		//	{
 | 
						|
		//		GC.Collect();
 | 
						|
		//		Handles.Add(this.Handle);
 | 
						|
		//		Console.WriteLine("Handles {0}, RTB Count Created {1}, RTB Count Not Disposed = {2} ", Handles.Count,StepRTB.CountCreated,StepRTB.CountNotDisposed);
 | 
						|
				
 | 
						|
		//	}
 | 
						|
		//}
 | 
						|
		//private static List<IntPtr> Handles = new List<IntPtr>();
 | 
						|
 | 
						|
		private bool _Initializing = false;
 | 
						|
		private string _OrgWord;
 | 
						|
 | 
						|
		// update dialog to show current error
 | 
						|
		private void UpdateCurrentError()
 | 
						|
		{
 | 
						|
			// design time
 | 
						|
			if (DesignMode || _Errors == null)
 | 
						|
			{
 | 
						|
				return;
 | 
						|
			}
 | 
						|
			// finished with this batch of errors
 | 
						|
			if (ErrorIndex >= _Errors.Count)
 | 
						|
			{
 | 
						|
				// check whether the editor has more text to check
 | 
						|
				while (_Editor.HasMoreText())
 | 
						|
				{
 | 
						|
					_Errors = _Spell.CheckText(_Editor.Text);
 | 
						|
					if (_Errors.Count > 0)
 | 
						|
					{
 | 
						|
						_ErrorCount += _Errors.Count;
 | 
						|
						ErrorIndex = 0;
 | 
						|
						return;
 | 
						|
					}
 | 
						|
				}
 | 
						|
 | 
						|
				// editor has no more text...
 | 
						|
				DialogResult = DialogResult.OK;
 | 
						|
				return;
 | 
						|
			}
 | 
						|
 | 
						|
			// update current error
 | 
						|
			CharRange err = CurrentError;
 | 
						|
 | 
						|
			// select word in editor
 | 
						|
			_Editor.Select(err.Start, err.Text.Length);
 | 
						|
 | 
						|
			// honor 'change all' list
 | 
						|
			if (_changeAll.ContainsKey(err.Text))
 | 
						|
			{
 | 
						|
				txbBadWord.Text = _changeAll[err.Text];
 | 
						|
				btnChange_Click(this, EventArgs.Empty);
 | 
						|
				return;
 | 
						|
			}
 | 
						|
 | 
						|
			_Initializing = true;
 | 
						|
			// show bad word, new text
 | 
						|
			txbBadWord.Text = _OrgWord = err.Text;
 | 
						|
 | 
						|
			// repeated word?
 | 
						|
			if (err.Duplicate)
 | 
						|
			{
 | 
						|
				// adjust dialog
 | 
						|
				lblNotInDictionary.Text = "Duplicate Word";
 | 
						|
				btnIgnoreAll.Enabled = false;
 | 
						|
				btnAddToDictionary.Enabled = false;
 | 
						|
				btnRemove.Enabled = true;
 | 
						|
 | 
						|
				// no suggestions
 | 
						|
				lbSuggestList.Items.Clear();
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				// adjust dialog
 | 
						|
				lblNotInDictionary.Text = "Not In Dictionary";
 | 
						|
				btnIgnoreAll.Enabled = true;
 | 
						|
				btnAddToDictionary.Enabled = true;
 | 
						|
				btnRemove.Enabled = false;
 | 
						|
 | 
						|
				SetupSuggestions(err.Text);
 | 
						|
			}
 | 
						|
 | 
						|
			// focus to new word
 | 
						|
			_AutoSuggest = false;
 | 
						|
			txbBadWord.SelectAll();
 | 
						|
			txbBadWord.Focus();
 | 
						|
			_AutoSuggest = true;
 | 
						|
			AcceptButton = btnIgnore;
 | 
						|
			
 | 
						|
			// show 'Add' button only if user dictionary is enabled
 | 
						|
			btnAddToDictionary.Visible = _Spell.UserDictionary.Enabled;
 | 
						|
 | 
						|
			// all ready, fire ErrorDisplayed event
 | 
						|
			//OnErrorDisplayed(EventArgs.Empty);
 | 
						|
		}
 | 
						|
 | 
						|
		private void SetupSuggestions(string badWord)
 | 
						|
		{
 | 
						|
			// show suggestions
 | 
						|
			_Initializing = true;
 | 
						|
			string[] suggestions = _Spell.GetSuggestions(badWord);
 | 
						|
			lbSuggestList.Items.Clear();
 | 
						|
			if (suggestions.Length > 0)
 | 
						|
			{
 | 
						|
				lbSuggestList.Items.AddRange(suggestions);
 | 
						|
				lbSuggestList.SelectedIndex = -1;
 | 
						|
				lbSuggestList.Enabled = true;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				lbSuggestList.Items.Add(_NoSuggestionsText);
 | 
						|
				lbSuggestList.SelectedIndex = -1;
 | 
						|
				lbSuggestList.Enabled = false;
 | 
						|
			}
 | 
						|
			_Initializing = false;
 | 
						|
		}
 | 
						|
 | 
						|
		private void txbBadWord_TextChanged(object sender, EventArgs e)
 | 
						|
		{
 | 
						|
			btnChange.Enabled = (_OrgWord != txbBadWord.Text);
 | 
						|
			btnChangeAll.Enabled = btnChange.Enabled && lblNotInDictionary.Text == "Not In Dictionary";
 | 
						|
			btnAddToDictionary.Enabled = _Spell.UserDictionary.Enabled && !InDictionary(txbBadWord.Text);
 | 
						|
			if (_AutoSuggest && !_Initializing)
 | 
						|
			{
 | 
						|
				SetupSuggestions(txbBadWord.Text);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		private bool InDictionary(string word)
 | 
						|
		{
 | 
						|
			if (_Spell.MainDictionary.Contains(word))
 | 
						|
				return true;
 | 
						|
			if (_Spell.CustomDictionary != null && _Spell.CustomDictionary.Contains(word))
 | 
						|
				return true;
 | 
						|
			if (_Spell.UserDictionary != null && _Spell.UserDictionary.Contains(word))
 | 
						|
				return true;
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		private void btnChange_Click(object sender, EventArgs e)
 | 
						|
		{
 | 
						|
			UpdateEditor(txbBadWord.Text);
 | 
						|
		}
 | 
						|
 | 
						|
		private void btnChangeAll_Click(object sender, EventArgs e)
 | 
						|
		{
 | 
						|
			_changeAll[CurrentError.Text] = txbBadWord.Text;
 | 
						|
			UpdateEditor(txbBadWord.Text);
 | 
						|
		}
 | 
						|
 | 
						|
		private void btnIgnore_Click(object sender, EventArgs e)
 | 
						|
		{
 | 
						|
			ErrorIndex++;
 | 
						|
		}
 | 
						|
 | 
						|
		private void btnIgnoreAll_Click(object sender, EventArgs e)
 | 
						|
		{
 | 
						|
			//Console.WriteLine("handle: {0}", this.Handle);
 | 
						|
			_Spell.IgnoreList.Add(CurrentError.Text);
 | 
						|
			_Errors = _Spell.CheckText(_Editor.Text, CurrentError.Start);
 | 
						|
			UpdateCurrentError();
 | 
						|
		}
 | 
						|
 | 
						|
		private void btnAddToDictionary_Click(object sender, EventArgs e)
 | 
						|
		{
 | 
						|
			_Spell.UserDictionary.AddWord(CurrentError.Text);
 | 
						|
			_Errors = _Spell.CheckText(_Editor.Text, CurrentError.Start);
 | 
						|
			ErrorIndex = 0;
 | 
						|
		}
 | 
						|
 | 
						|
		private void lbSuggestList_SelectedIndexChanged(object sender, EventArgs e)
 | 
						|
		{
 | 
						|
			_AutoSuggest = false;
 | 
						|
			if (!_Initializing && lbSuggestList.Text != _NoSuggestionsText)
 | 
						|
				txbBadWord.Text =  lbSuggestList.Text;
 | 
						|
			_AutoSuggest = true;
 | 
						|
		}
 | 
						|
 | 
						|
		// double-click selects word for suggestion list and changes mis-spelled word
 | 
						|
		private void lbSuggestList_DoubleClick(object sender, EventArgs e)
 | 
						|
		{
 | 
						|
			if (txbBadWord.Text == lbSuggestList.Text)
 | 
						|
			{
 | 
						|
				UpdateEditor(txbBadWord.Text);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		private void btnRemove_Click(object sender, EventArgs e)
 | 
						|
		{
 | 
						|
			UpdateEditor("");
 | 
						|
		}
 | 
						|
	}
 | 
						|
} |