Working on spell check via word (late bound)

git-svn-id: https://subtitleedit.googlecode.com/svn/trunk@245 99eadd0c-20b8-1223-b5c4-2a2b2df33de2
This commit is contained in:
niksedk 2011-01-13 20:35:52 +00:00
parent 23b7f890bc
commit 6ea4ab4d77
6 changed files with 169 additions and 4 deletions

View File

@ -2766,8 +2766,56 @@ namespace Nikse.SubtitleEdit.Forms
SpellCheck(true); SpellCheck(true);
} }
private void SpellCheckViaWord()
{
WordSpellChecker wordSpellChecker = null;
int totalCorrections = 0;
try
{
wordSpellChecker = new WordSpellChecker();
}
catch
{
MessageBox.Show(_language.UnableToStartWord);
//Configuration.Settings.General.SpellChecker = "hunspell"; ???
return;
}
string version = wordSpellChecker.Version;
int index = 1;
foreach (Paragraph p in _subtitle.Paragraphs)
{
int errorsBefore;
int errorsAfter;
wordSpellChecker.NewDocument();
ShowStatus(string.Format(_language.SpellChekingViaWordXLineYOfX, version, index, _subtitle.Paragraphs.Count.ToString()));
SubtitleListview1.SelectIndexAndEnsureVisible(index - 1);
string newText = wordSpellChecker.CheckSpelling(p.Text, out errorsBefore, out errorsAfter);
wordSpellChecker.CloseDocument();
if (errorsAfter > 0)
{
wordSpellChecker.Quit();
ShowStatus(string.Format(_language.SpellCheckAbortedXCorrections, totalCorrections));
return;
}
else if (errorsBefore != errorsAfter)
{
textBoxListViewText.Text = newText;
}
totalCorrections += (errorsBefore - errorsAfter);
index++;
}
wordSpellChecker.Quit();
ShowStatus(string.Format(_language.SpellCheckCompletedXCorrections, totalCorrections));
}
private void SpellCheck(bool autoDetect) private void SpellCheck(bool autoDetect)
{ {
if (Configuration.Settings.General.SpellChecker.ToLower().Contains("word"))
{
SpellCheckViaWord();
return;
}
try try
{ {
string dictionaryFolder = Utilities.DictionaryFolder; string dictionaryFolder = Utilities.DictionaryFolder;

View File

@ -662,6 +662,10 @@ namespace Nikse.SubtitleEdit.Logic
NetworkMode = "Networking mode", NetworkMode = "Networking mode",
UserAndAction = "User/action", UserAndAction = "User/action",
XStartedSessionYAtZ = "{0}: Started session {1} at {2}", XStartedSessionYAtZ = "{0}: Started session {1} at {2}",
SpellChekingViaWordXLineYOfX = "Spell checking using Word {0} - line {1} / {2}",
UnableToStartWord = "Unable to start Microsoft Word",
SpellCheckAbortedXCorrections = "Spell check aborted. {0} corrections was made.",
SpellCheckCompletedXCorrections = "Spell check completed. {0} corrections was made.",
Menu = new LanguageStructure.Main.MainMenu Menu = new LanguageStructure.Main.MainMenu
{ {

View File

@ -590,7 +590,11 @@
public string UserAndAction { get; set; } public string UserAndAction { get; set; }
public string NetworkMode { get; set; } public string NetworkMode { get; set; }
public string XStartedSessionYAtZ { get; set; } public string XStartedSessionYAtZ { get; set; }
public string SpellChekingViaWordXLineYOfX { get; set; }
public string UnableToStartWord { get; set; }
public string SpellCheckAbortedXCorrections { get; set; }
public string SpellCheckCompletedXCorrections { get; set; }
public class MainMenu public class MainMenu
{ {
public class FileMenu public class FileMenu

View File

@ -237,6 +237,7 @@ namespace Nikse.SubtitleEdit.Logic
public bool AutoContinueOn { get; set; } public bool AutoContinueOn { get; set; }
public bool SyncListViewWithVideoWhilePlaying { get; set; } public bool SyncListViewWithVideoWhilePlaying { get; set; }
public int AutoBackupSeconds { get; set; } public int AutoBackupSeconds { get; set; }
public string SpellChecker { get; set; }
public GeneralSettings() public GeneralSettings()
{ {
@ -283,6 +284,7 @@ namespace Nikse.SubtitleEdit.Logic
AutoContinueOn = false; AutoContinueOn = false;
SyncListViewWithVideoWhilePlaying = false; SyncListViewWithVideoWhilePlaying = false;
AutoBackupSeconds = 0; AutoBackupSeconds = 0;
SpellChecker = "hunspell";
} }
} }
@ -626,7 +628,10 @@ namespace Nikse.SubtitleEdit.Logic
settings.General.AutoContinueOn = Convert.ToBoolean(subNode.InnerText); settings.General.AutoContinueOn = Convert.ToBoolean(subNode.InnerText);
subNode = node.SelectSingleNode("AutoBackupSeconds"); subNode = node.SelectSingleNode("AutoBackupSeconds");
if (subNode != null) if (subNode != null)
settings.General.AutoBackupSeconds = Convert.ToInt32(subNode.InnerText); settings.General.AutoBackupSeconds = Convert.ToInt32(subNode.InnerText);
subNode = node.SelectSingleNode("SpellChecker");
if (subNode != null)
settings.General.SpellChecker = subNode.InnerText;
settings.Tools = new Nikse.SubtitleEdit.Logic.ToolsSettings(); settings.Tools = new Nikse.SubtitleEdit.Logic.ToolsSettings();
node = doc.DocumentElement.SelectSingleNode("Tools"); node = doc.DocumentElement.SelectSingleNode("Tools");
@ -929,8 +934,9 @@ namespace Nikse.SubtitleEdit.Logic
textWriter.WriteElementString("DefaultAdjustMilliseconds", settings.General.DefaultAdjustMilliseconds.ToString()); textWriter.WriteElementString("DefaultAdjustMilliseconds", settings.General.DefaultAdjustMilliseconds.ToString());
textWriter.WriteElementString("AutoRepeatOn", settings.General.AutoRepeatOn.ToString()); textWriter.WriteElementString("AutoRepeatOn", settings.General.AutoRepeatOn.ToString());
textWriter.WriteElementString("AutoContinueOn", settings.General.AutoContinueOn.ToString()); textWriter.WriteElementString("AutoContinueOn", settings.General.AutoContinueOn.ToString());
textWriter.WriteElementString("SyncListViewWithVideoWhilePlaying", settings.General.SyncListViewWithVideoWhilePlaying.ToString()); textWriter.WriteElementString("SyncListViewWithVideoWhilePlaying", settings.General.SyncListViewWithVideoWhilePlaying.ToString());
textWriter.WriteElementString("AutoBackupSeconds", settings.General.AutoBackupSeconds.ToString()); textWriter.WriteElementString("AutoBackupSeconds", settings.General.AutoBackupSeconds.ToString());
textWriter.WriteElementString("SpellChecker", settings.General.SpellChecker);
textWriter.WriteEndElement(); textWriter.WriteEndElement();
textWriter.WriteStartElement("Tools", ""); textWriter.WriteStartElement("Tools", "");

102
src/Logic/WordLateBound.cs Normal file
View File

@ -0,0 +1,102 @@
using System;
using System.Reflection;
namespace Nikse.SubtitleEdit.Logic
{
/// <summary>
/// MS Word methods (late bound) for spell checking by Nikse
/// Mostly a bunch of hacks...
/// </summary>
internal class WordSpellChecker
{
private object _wordApplication;
private object _wordDocument;
private Type _wordApplicationType;
private Type _wordDocumentType;
public WordSpellChecker()
{
_wordApplicationType = System.Type.GetTypeFromProgID("Word.Application");
_wordApplication = Activator.CreateInstance(_wordApplicationType);
_wordApplicationType.InvokeMember("Top", BindingFlags.SetProperty, null, _wordApplication, new object[] { -1000 }); // hide window - it's a hack
_wordApplicationType.InvokeMember("Visible", BindingFlags.SetProperty, null, _wordApplication, new object[] { true }); // set visible to true - otherwise it will appear in the background
}
public void NewDocument()
{
_wordDocumentType = System.Type.GetTypeFromProgID("Word.Document");
_wordDocument = Activator.CreateInstance(_wordDocumentType);
}
public void CloseDocument()
{
object saveChanges = false;
object p = Missing.Value;
_wordDocumentType.InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, _wordDocument, new object[] { saveChanges, p, p });
}
public string Version
{
get
{
object wordVersion = _wordApplicationType.InvokeMember("Version", BindingFlags.GetProperty, null, _wordApplication, null);
return wordVersion.ToString();
}
}
public void Quit()
{
object saveChanges = false;
object originalFormat = Missing.Value;
object routeDocument = Missing.Value;
_wordApplicationType.InvokeMember("Quit", System.Reflection.BindingFlags.InvokeMethod, null, _wordApplication, new object[] { saveChanges, originalFormat, routeDocument });
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(_wordDocument);
System.Runtime.InteropServices.Marshal.ReleaseComObject(_wordApplication);
}
finally
{
_wordDocument = null;
_wordApplication = null;
}
}
public string CheckSpelling(string text, out int errorsBefore, out int errorsAfter)
{
// insert text
object words = _wordDocumentType.InvokeMember("Words", BindingFlags.GetProperty, null, _wordDocument, null);
object range = words.GetType().InvokeMember("First", BindingFlags.GetProperty, null, words, null);
range.GetType().InvokeMember("InsertBefore", BindingFlags.InvokeMethod, null, range, new Object[] { text });
// spell check error count
object spellingErrors = _wordDocumentType.InvokeMember("SpellingErrors", BindingFlags.GetProperty, null, _wordDocument, null);
object spellingErrorsCount = spellingErrors.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, spellingErrors, null);
errorsBefore = int.Parse(spellingErrorsCount.ToString());
System.Runtime.InteropServices.Marshal.ReleaseComObject(spellingErrors);
// perform spell check
object p = Missing.Value;
_wordApplicationType.InvokeMember("Visible", BindingFlags.SetProperty, null, _wordApplication, new object[] { true }); // set visible to true - otherwise it will appear in the background
_wordDocumentType.InvokeMember("CheckSpelling", BindingFlags.InvokeMethod, null, _wordDocument, new Object[] { p, p, p, p, p, p, p, p, p, p, p, p }); // 12 parameters
// _wordApplicationType.InvokeMember("Top", BindingFlags.SetProperty, null, _wordApplication, new object[] { -1000 }); // hide window - it's a hack
// spell check error count
spellingErrors = _wordDocumentType.InvokeMember("SpellingErrors", BindingFlags.GetProperty, null, _wordDocument, null);
spellingErrorsCount = spellingErrors.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, spellingErrors, null);
errorsAfter = int.Parse(spellingErrorsCount.ToString());
System.Runtime.InteropServices.Marshal.ReleaseComObject(spellingErrors);
// Get spellcheck text
object first = 0;
object characters = _wordDocumentType.InvokeMember("Characters", BindingFlags.GetProperty, null, _wordDocument, null);
object charactersCount = characters.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, characters, null);
object last = int.Parse(charactersCount.ToString()) - 1;
System.Runtime.InteropServices.Marshal.ReleaseComObject(characters);
object resultText = range.GetType().InvokeMember("Text", BindingFlags.GetProperty, null, range, null);
return resultText.ToString().TrimEnd(); // result needs a trimming at the end
}
}
}

View File

@ -561,6 +561,7 @@
<Compile Include="Logic\VobSub\VobSubParser.cs" /> <Compile Include="Logic\VobSub\VobSubParser.cs" />
<Compile Include="Logic\VobSub\VobSubMergedPack.cs" /> <Compile Include="Logic\VobSub\VobSubMergedPack.cs" />
<Compile Include="Logic\VobSub\VobSubPack.cs" /> <Compile Include="Logic\VobSub\VobSubPack.cs" />
<Compile Include="Logic\WordLateBound.cs" />
<Compile Include="Logic\zlib\Adler32.cs" /> <Compile Include="Logic\zlib\Adler32.cs" />
<Compile Include="Logic\zlib\Deflate.cs" /> <Compile Include="Logic\zlib\Deflate.cs" />
<Compile Include="Logic\zlib\InfBlocks.cs" /> <Compile Include="Logic\zlib\InfBlocks.cs" />