Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit bddea4f

Browse files
committed
working on spell check
1 parent d777583 commit bddea4f

File tree

12 files changed

+654
-80
lines changed

12 files changed

+654
-80
lines changed

SubtitleEdit/SubtitleEdit.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@
290290
<DependentUpon>SpellCheckController.cs</DependentUpon>
291291
</Compile>
292292
<Compile Include="UILogic\SpellCheck\SpellChecker.cs" />
293+
<Compile Include="UILogic\ISubtitleParagraphShow.cs" />
293294
</ItemGroup>
294295
<ItemGroup>
295296
<InterfaceDefinition Include="Windows\MainMenu.xib" />
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System;
2+
3+
namespace UILogic
4+
{
5+
public interface ISubtitleParagraphShow
6+
{
7+
void SubtitleParagraphShow(int index);
8+
}
9+
}
10+

SubtitleEdit/UILogic/SpellCheck/SpellChecker.cs

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22
using System.Collections.Generic;
33
using AppKit;
44
using Nikse.SubtitleEdit.Core;
5+
using Nikse.SubtitleEdit.Core.SpellCheck;
6+
using Nikse.SubtitleEdit.Core.Interfaces;
57
using System.Linq;
68
using System.Text;
79
using Foundation;
810

911
namespace SpellCheck
1012
{
1113

12-
public class SpellChecker : IDisposable
14+
public class SpellChecker : IDisposable, IDoSpell
1315
{
1416
NSSpellChecker _nativeSpellChecker;
1517

@@ -18,7 +20,7 @@ public SpellChecker(string language)
1820
_nativeSpellChecker = new NSSpellChecker();
1921
}
2022

21-
public bool Spell(string word)
23+
public bool DoSpell(string word)
2224
{
2325
nint wordCount = 0;
2426
var res = _nativeSpellChecker.CheckSpelling(word, 0, "en",true, 0, out wordCount);
@@ -45,7 +47,7 @@ protected void AddIShouldBeLowercaseLSuggestion(List<string> suggestions, string
4547
}
4648

4749
// "I" can often be an ocr bug - should really be "l"
48-
if (word.Length > 1 && word.StartsWith('I') && !suggestions.Contains("l" + word.Substring(1)) && Spell("l" + word.Substring(1)))
50+
if (word.Length > 1 && word.StartsWith('I') && !suggestions.Contains("l" + word.Substring(1)) && DoSpell("l" + word.Substring(1)))
4951
{
5052
suggestions.Add("l" + word.Substring(1));
5153
}
@@ -71,6 +73,8 @@ public string CurrentLanguage
7173

7274
public const string WordSplitChars = " -.,?!:;\"“”()[]{}|<>/+\r\n¿¡…—–♪♫„“";
7375

76+
77+
7478
public static List<SpellCheckWord> Split(string s)
7579
{
7680
var list = new List<SpellCheckWord>();
@@ -94,6 +98,86 @@ public static List<SpellCheckWord> Split(string s)
9498
}
9599

96100

101+
private int GetPositionFromWordIndex(string text, int wordIndex)
102+
{
103+
var sb = new StringBuilder();
104+
int index = -1;
105+
for (int i = 0; i < text.Length; i++)
106+
{
107+
if (SpellCheckWordLists.SplitChars.Contains(text[i]))
108+
{
109+
if (sb.Length > 0)
110+
{
111+
index++;
112+
if (index == wordIndex)
113+
{
114+
int pos = i - sb.Length;
115+
if (pos > 0)
116+
pos--;
117+
if (pos >= 0)
118+
return pos;
119+
}
120+
}
121+
sb.Clear();
122+
}
123+
else
124+
{
125+
sb.Append(text[i]);
126+
}
127+
}
128+
if (sb.Length > 0)
129+
{
130+
index++;
131+
if (index == wordIndex)
132+
{
133+
int pos = text.Length - 1 - sb.Length;
134+
if (pos >= 0)
135+
return pos;
136+
}
137+
}
138+
return 0;
139+
}
140+
141+
public void CorrectWord(string changeWord, Paragraph p, string oldWord, int wordIndex)
142+
{
143+
if (oldWord != changeWord)
144+
{
145+
int startIndex = p.Text.IndexOf(oldWord, StringComparison.Ordinal);
146+
if (wordIndex >= 0)
147+
{
148+
startIndex = p.Text.IndexOf(oldWord, GetPositionFromWordIndex(p.Text, wordIndex), StringComparison.Ordinal);
149+
}
150+
while (startIndex >= 0 && startIndex < p.Text.Length && p.Text.Substring(startIndex).Contains(oldWord))
151+
{
152+
bool startOk = startIndex == 0 ||
153+
p.Text[startIndex - 1] == ' ' ||
154+
p.Text[startIndex - 1] == '>' ||
155+
p.Text[startIndex - 1] == '"' ||
156+
p.Text[startIndex - 1] == '\'' ||
157+
startIndex == p.Text.Length - oldWord.Length ||
158+
Environment.NewLine.EndsWith(p.Text[startIndex - 1]);
159+
if (startOk)
160+
{
161+
int end = startIndex + oldWord.Length;
162+
if (end <= p.Text.Length)
163+
{
164+
if (end == p.Text.Length || (" ,.!?:;')<\"-]}%&$£" + Environment.NewLine).Contains(p.Text[end]))
165+
p.Text = p.Text.Remove(startIndex, oldWord.Length).Insert(startIndex, changeWord);
166+
}
167+
}
168+
if (startIndex + 2 >= p.Text.Length)
169+
startIndex = -1;
170+
else
171+
startIndex = p.Text.IndexOf(oldWord, startIndex + 2, StringComparison.Ordinal);
172+
173+
// stop if using index
174+
if (wordIndex >= 0)
175+
startIndex = -1;
176+
}
177+
}
178+
}
179+
180+
97181
}
98182

99183
}

SubtitleEdit/Windows/Edit/SpellCheck.cs

Lines changed: 122 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@
44
using AppKit;
55
using Nikse.SubtitleEdit.Core;
66
using System.Collections.Generic;
7+
using Nikse.SubtitleEdit.Core.SpellCheck;
8+
using System.Text;
9+
using Nikse.SubtitleEdit.UILogic;
10+
using System.Linq;
711

812
namespace Edit
913
{
1014
public partial class SpellCheck : NSWindow
1115
{
16+
17+
private List<string> _suggestions = new List<string>();
18+
1219
public SpellCheck(IntPtr handle)
1320
: base(handle)
1421
{
@@ -20,6 +27,15 @@ public SpellCheck(NSCoder coder)
2027
{
2128
}
2229

30+
private void InitializeTable(NSTableView table)
31+
{
32+
var columns = table.TableColumns();
33+
columns[0].SetIdentifier(StringListTableDelegate.CellIdentifiers[0]);
34+
columns[0].MinWidth = 50;
35+
columns[0].MaxWidth = 20000;
36+
columns[0].Width = 2060;
37+
}
38+
2339
public override void AwakeFromNib()
2440
{
2541
base.AwakeFromNib();
@@ -34,33 +50,125 @@ public override void AwakeFromNib()
3450

3551
(WindowController as SpellCheckController).InitializeSpellCheck();
3652

37-
_buttonAbort.Activated += (object sender, EventArgs e) =>
38-
{
39-
(WindowController as SpellCheckController).Abort();
40-
Close();
41-
};
53+
_buttonAbort.Activated += (object sender, EventArgs e) =>
54+
{
55+
(WindowController as SpellCheckController).Abort();
56+
Close();
57+
};
58+
59+
_buttonSkipAll.Activated += (object sender, EventArgs e) =>
60+
{
61+
(WindowController as SpellCheckController).SkipAll();
62+
};
63+
64+
_buttonSkipOne.Activated += (object sender, EventArgs e) =>
65+
{
66+
(WindowController as SpellCheckController).SkipOne();
67+
};
68+
69+
_buttonChange.Activated += (object sender, EventArgs e) =>
70+
{
71+
(WindowController as SpellCheckController).ChangeWord(_textWordNotFound.StringValue);
72+
};
73+
74+
_buttonChangeAll.Activated += (object sender, EventArgs e) =>
75+
{
76+
(WindowController as SpellCheckController).ChangeWordAll(_textWordNotFound.StringValue);
77+
};
4278

43-
_buttonSkipAll.Activated += (object sender, EventArgs e) =>
79+
_buttonAddToNames.Activated += (object sender, EventArgs e) =>
80+
{
81+
(WindowController as SpellCheckController).AddToNames(_textWordNotFound.StringValue);
82+
};
83+
84+
_buttonAddToUserDictionary.Activated += (object sender, EventArgs e) =>
85+
{
86+
(WindowController as SpellCheckController).AddToUserDictionary(_textWordNotFound.StringValue);
87+
};
88+
89+
_buttonGoogleIt.Activated += (object sender, EventArgs e) =>
90+
{
91+
System.Diagnostics.Process.Start("https://www.google.com/search?q=" + Utilities.UrlEncode(_textWordNotFound.StringValue));
92+
};
93+
94+
_buttonUseSuggestion.Activated += (object sender, EventArgs e) =>
95+
{
96+
int idx = (int)_tableSuggestions.SelectedRow;
97+
if (_suggestions.Count > 0 && idx >= 0)
4498
{
45-
(WindowController as SpellCheckController).SkipAll();
46-
};
99+
(WindowController as SpellCheckController).ChangeWord(_suggestions[idx]);
100+
}
101+
};
47102

48-
_buttonSkipOne.Activated += (object sender, EventArgs e) =>
103+
_buttonUseSuggestionAlways.Activated += (object sender, EventArgs e) =>
104+
{
105+
int idx = (int)_tableSuggestions.SelectedRow;
106+
if (_suggestions.Count > 0 && idx >= 0)
49107
{
50-
(WindowController as SpellCheckController).SkipOne();
51-
_textWordNotFound.StringValue = string.Empty;
52-
};
108+
(WindowController as SpellCheckController).ChangeWordAll(_suggestions[idx]);
109+
}
110+
};
53111

112+
_popUpLanguages.Activated += (object sender, EventArgs e) =>
113+
{
114+
(WindowController as SpellCheckController).LoadDictionaries(_popUpLanguages.SelectedItem.Title);
115+
};
116+
117+
_checkAutoFixNames.Activated += (object sender, EventArgs e) =>
118+
{
119+
(WindowController as SpellCheckController).SetAutoFixState(_checkAutoFixNames.State == NSCellStateValue.On);
120+
};
54121

122+
InitializeTable(_tableSuggestions);
55123
}
56124

57125
public void InitializeLanguages(List<string> list)
58126
{
59-
127+
_popUpLanguages.RemoveAllItems();
128+
foreach (var language in list)
129+
{
130+
_popUpLanguages.AddItem(language);
131+
}
132+
}
133+
134+
public void ShowSuggestions(List<string> suggestions)
135+
{
136+
_suggestions = suggestions;
137+
var ds = new StringListTableDataSource(suggestions);
138+
_tableSuggestions.DataSource = ds;
139+
_tableSuggestions.Delegate = new StringListTableDelegate(ds, null);
140+
if (suggestions.Count > 0)
141+
{
142+
_tableSuggestions.SelectRow(0, false);
143+
}
60144
}
61145

62146
public void ShowUnknownWord(SpellCheckWord currentSpellCheckWord, Paragraph currentParagraph)
63147
{
148+
string text = HtmlUtil.RemoveHtmlTags(currentParagraph.Text, true);
149+
_textViewFullText.Editable = true;
150+
_textViewFullText.TextStorage.SetString(new NSAttributedString(""));
151+
_textViewFullText.InsertText(new NSString(text));
152+
int idx = text.IndexOf(currentSpellCheckWord.Text);
153+
while (idx >= 0)
154+
{
155+
bool startOk = idx == 0 || text.Substring(idx - 1, 1).ToLower() == text.Substring(idx - 1, 1).ToUpper();
156+
if (startOk)
157+
{
158+
int endIdx = idx + currentSpellCheckWord.Text.Length;
159+
bool endOk = endIdx >= text.Length || text.Substring(endIdx, 1).ToLower() == text.Substring(endIdx, 1).ToUpper();
160+
if (endOk)
161+
{
162+
_textViewFullText.SetTextColor(NSColor.Red, new NSRange(idx, currentSpellCheckWord.Text.Length));
163+
}
164+
}
165+
if (idx < text.Length - 1)
166+
{
167+
idx = text.IndexOf(currentSpellCheckWord.Text, idx + 1);
168+
}
169+
}
170+
_textViewFullText.Editable = false;
171+
64172
_textWordNotFound.StringValue = currentSpellCheckWord.Text;
65173
}
66174

@@ -70,5 +178,6 @@ public void ShowProgress(int currentParagraphIndex, Subtitle _subtitle)
70178
_progressBar.DoubleValue = currentParagraphIndex;
71179
Title = Configuration.Settings.Language.SpellCheck.Title + " - " + (currentParagraphIndex + 1) + " / " + _subtitle.Paragraphs.Count;
72180
}
181+
73182
}
74183
}

0 commit comments

Comments
 (0)