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
294 lines
7.7 KiB
C#
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("");
|
|
}
|
|
}
|
|
} |