John 91da0b995f Added supporting logic to SaveText and SaveContents for Editorial Spell Checker
Added supporting logic to SpellCheckNext for Editorial Spell Checker
Save text changes before starting up the spell checker
Added supporting logic to UpdateEditor for Editorial Spell Checker
2016-10-25 18:48:14 +00:00

294 lines
7.7 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);
// show first error (after firing load event)
ErrorIndex = 0;
}
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)
{
_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("");
}
}
}