mirror of
https://github.com/SubtitleEdit/subtitleedit.git
synced 2024-10-27 22:42:38 +01:00
Move word up/down refactor to separate class + unit tests
Work on #3887
This commit is contained in:
parent
653287ff5a
commit
3dbadd68f6
242
libse/Forms/MoveWordUpDown.cs
Normal file
242
libse/Forms/MoveWordUpDown.cs
Normal file
@ -0,0 +1,242 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.Forms
|
||||
{
|
||||
public class MoveWordUpDown
|
||||
{
|
||||
public string S1 { get; private set; }
|
||||
public string S2 { get; private set; }
|
||||
|
||||
public MoveWordUpDown(string s1, string s2)
|
||||
{
|
||||
S1 = s1 ?? string.Empty;
|
||||
S2 = s2 ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Move first word in S2 to up as last word in S1
|
||||
/// </summary>
|
||||
public void MoveWordUp()
|
||||
{
|
||||
if (string.IsNullOrEmpty(S2))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var assTagOn = false;
|
||||
var htmlTagOn = false;
|
||||
var sbWord = new StringBuilder();
|
||||
var done = false;
|
||||
var sbS2 = new StringBuilder();
|
||||
for (int i = 0; i < S2.Length; i++)
|
||||
{
|
||||
var ch = S2[i];
|
||||
if (done)
|
||||
{
|
||||
sbS2.Append(ch);
|
||||
}
|
||||
else if (assTagOn)
|
||||
{
|
||||
if (ch == '}')
|
||||
{
|
||||
assTagOn = false;
|
||||
}
|
||||
sbS2.Append(ch);
|
||||
}
|
||||
else if (htmlTagOn)
|
||||
{
|
||||
if (ch == '>')
|
||||
{
|
||||
htmlTagOn = false;
|
||||
}
|
||||
sbS2.Append(ch);
|
||||
}
|
||||
else if (ch == '{' && S2.Substring(i).StartsWith("{\\", StringComparison.Ordinal))
|
||||
{
|
||||
assTagOn = true;
|
||||
sbS2.Append(ch);
|
||||
}
|
||||
else if (S2.Substring(i).StartsWith("<font", StringComparison.OrdinalIgnoreCase) ||
|
||||
S2.Substring(i).StartsWith("<i>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S2.Substring(i).StartsWith("<b>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S2.Substring(i).StartsWith("<u>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S2.Substring(i).StartsWith("</font", StringComparison.OrdinalIgnoreCase) ||
|
||||
S2.Substring(i).StartsWith("</i>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S2.Substring(i).StartsWith("</b>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S2.Substring(i).StartsWith("</u>", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
htmlTagOn = true;
|
||||
sbS2.Append(ch);
|
||||
}
|
||||
else if (sbWord.ToString().Trim().Length > 0 && (ch == ' ' || ch == '\r' || ch == '\n'))
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sbWord.Append(ch);
|
||||
}
|
||||
}
|
||||
S1 = AddWordAfter(sbWord.ToString().Trim(), S1);
|
||||
S1 = AutoBreakIfNeeded(S1);
|
||||
S2 = sbS2.ToString().Trim();
|
||||
S2 = RemoveEmptyTags(S2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Move last word from S1 down as first word in S2
|
||||
/// </summary>
|
||||
public void MoveWordDown()
|
||||
{
|
||||
if (string.IsNullOrEmpty(S1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var assTagOn = false;
|
||||
var htmlTagOn = false;
|
||||
var sbWord = new StringBuilder();
|
||||
var done = false;
|
||||
var sbS1 = new StringBuilder();
|
||||
for (int i = S1.Length - 1; i >= 0; i--)
|
||||
{
|
||||
var ch = S1[i];
|
||||
if (done)
|
||||
{
|
||||
sbS1.Append(ch);
|
||||
}
|
||||
else if (assTagOn)
|
||||
{
|
||||
if (ch == '{' && S2.Substring(i).StartsWith("{\\", StringComparison.Ordinal))
|
||||
{
|
||||
assTagOn = false;
|
||||
}
|
||||
sbS1.Append(ch);
|
||||
}
|
||||
else if (htmlTagOn)
|
||||
{
|
||||
if (S1.Substring(i).StartsWith("<font", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(i).StartsWith("<i>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(i).StartsWith("<b>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(i).StartsWith("<u>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(i).StartsWith("</font>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(i).StartsWith("</i>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(i).StartsWith("</b>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(i).StartsWith("</u>", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
htmlTagOn = false;
|
||||
}
|
||||
sbS1.Append(ch);
|
||||
}
|
||||
else if (ch == '}' && S1.StartsWith("{\\", StringComparison.Ordinal))
|
||||
{
|
||||
assTagOn = true;
|
||||
sbS1.Append(ch);
|
||||
}
|
||||
else if (ch == '>' && S1.Substring(0, i + 1).Contains("<font ", StringComparison.OrdinalIgnoreCase) && IsPartOfFontTag(S1, i) ||
|
||||
S1.Substring(0, i + 1).EndsWith("</font>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(0, i + 1).EndsWith("</i>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(0, i + 1).EndsWith("</b>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(0, i + 1).EndsWith("</u>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(0, i + 1).EndsWith("<i>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(0, i + 1).EndsWith("<b>", StringComparison.OrdinalIgnoreCase) ||
|
||||
S1.Substring(0, i + 1).EndsWith("<u>", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
htmlTagOn = true;
|
||||
sbS1.Append(ch);
|
||||
}
|
||||
else if (sbWord.ToString().Trim().Length > 0 && (ch == ' ' || ch == '\r' || ch == '\n'))
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sbWord.Append(ch);
|
||||
}
|
||||
}
|
||||
S1 = string.Join(string.Empty, sbS1.ToString().Trim().ToCharArray().Reverse());
|
||||
S1 = RemoveEmptyTags(S1);
|
||||
S2 = AddWordBefore(string.Join(string.Empty, sbWord.ToString().Trim().ToCharArray().Reverse()), S2);
|
||||
S2 = AutoBreakIfNeeded(S2);
|
||||
}
|
||||
|
||||
private static bool IsPartOfFontTag(string s, int i)
|
||||
{
|
||||
var indexOfFontTag = s.Substring(0, i).LastIndexOf("<font ", StringComparison.OrdinalIgnoreCase);
|
||||
if (indexOfFontTag < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var indexOfEndFontTag = s.IndexOf(">", indexOfFontTag, StringComparison.Ordinal);
|
||||
if (indexOfEndFontTag < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return i >= indexOfFontTag && i <= indexOfEndFontTag;
|
||||
}
|
||||
|
||||
private static string RemoveEmptyTags(string s)
|
||||
{
|
||||
var noTags = HtmlUtil.RemoveHtmlTags(s, true);
|
||||
if (noTags.Length == 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return s
|
||||
.Replace("<i></i>", string.Empty)
|
||||
.Replace("<u></u>", string.Empty)
|
||||
.Replace("<b></b>", string.Empty);
|
||||
}
|
||||
|
||||
private static string AddWordBefore(string word, string input)
|
||||
{
|
||||
var pre = string.Empty;
|
||||
var s = input;
|
||||
if (s.StartsWith("{\\") && s.Contains("}"))
|
||||
{
|
||||
var idx = s.IndexOf('}');
|
||||
pre = s.Substring(0, idx + 1);
|
||||
s = s.Remove(0, idx + 1);
|
||||
}
|
||||
var arr = s.SplitToLines();
|
||||
if (s.StartsWith("<i>", StringComparison.OrdinalIgnoreCase) && (s.EndsWith("</i>", StringComparison.OrdinalIgnoreCase) || arr[0].EndsWith("</i>", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return pre + s.Insert(3, word.Trim() + " ").Trim();
|
||||
}
|
||||
|
||||
return pre + (word.Trim() + " " + s.Trim()).Trim();
|
||||
}
|
||||
|
||||
private static string AddWordAfter(string word, string s)
|
||||
{
|
||||
var arr = s.SplitToLines();
|
||||
if (s.EndsWith("</i>", StringComparison.OrdinalIgnoreCase) && (s.StartsWith("<i>", StringComparison.OrdinalIgnoreCase) || arr[arr.Count - 1].StartsWith("<i>", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return s.Insert(s.Length - 4, " " + word.Trim()).Trim();
|
||||
}
|
||||
|
||||
return (s.Trim() + " " + word.Trim()).Trim();
|
||||
}
|
||||
|
||||
private static string AutoBreakIfNeeded(string s)
|
||||
{
|
||||
bool doBreak = false;
|
||||
foreach (var line in s.SplitToLines())
|
||||
{
|
||||
if (HtmlUtil.RemoveHtmlTags(line, true).Length > Configuration.Settings.General.SubtitleLineMaximumLength)
|
||||
{
|
||||
doBreak = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return doBreak ? Utilities.AutoBreakLine(s) : s;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -185,6 +185,7 @@
|
||||
<Compile Include="Forms\FixCommonErrors\FixUppercaseIInsideWords.cs" />
|
||||
<Compile Include="Forms\FixCommonErrors\Helper.cs" />
|
||||
<Compile Include="Forms\MergeLinesWithSameTimeCodes.cs" />
|
||||
<Compile Include="Forms\MoveWordUpDown.cs" />
|
||||
<Compile Include="Forms\RemoveInterjection.cs" />
|
||||
<Compile Include="Interfaces\IBinaryPersistableSubtitle.cs" />
|
||||
<Compile Include="Interfaces\IBinaryParagraph.cs" />
|
||||
|
@ -9175,133 +9175,17 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
var next = _subtitle.GetParagraphOrDefault(firstIndex + 1);
|
||||
if (p != null && next != null)
|
||||
{
|
||||
string s = next.Text.Trim();
|
||||
|
||||
// Find the first space.
|
||||
int startIndex = 0;
|
||||
if (s.StartsWith("{\\", StringComparison.Ordinal))
|
||||
var moveUpDown = new MoveWordUpDown(p.Text, next.Text);
|
||||
moveUpDown.MoveWordUp();
|
||||
if (moveUpDown.S1 != p.Text && moveUpDown.S2 != next.Text)
|
||||
{
|
||||
var endTagIndex = s.IndexOf('}');
|
||||
if (endTagIndex > 0)
|
||||
{
|
||||
startIndex = endTagIndex;
|
||||
}
|
||||
}
|
||||
int idx = s.IndexOf(' ', startIndex);
|
||||
// If the first space is after a "-", even if there is "{\an8}<i>" before, find the second space.
|
||||
if (idx > 0 && s.Substring(idx - 1, 2) == "- ")
|
||||
{
|
||||
idx = idx + 1 + s.Substring(idx + 1).IndexOf(' ');
|
||||
}
|
||||
|
||||
if (idx > 0 || s.Length > 0)
|
||||
// A first word was found or next subtitle is not empty (has one word).
|
||||
{
|
||||
// Undo
|
||||
MakeHistoryForUndo(_language.BeforeLineUpdatedInListView);
|
||||
|
||||
// Define firstWord. If idx > 0, there is a first word.
|
||||
// If not, firstWord is the whole text of the next subtitle.
|
||||
string firstWord = (idx > 0 ? s.Substring(0, idx).Trim() : next.Text);
|
||||
|
||||
// If firstWord contains a line break, it has two words.
|
||||
if (firstWord.Contains(Environment.NewLine))
|
||||
{
|
||||
// Redefine firstWord and idx.
|
||||
firstWord = firstWord.Remove(firstWord.IndexOf(Environment.NewLine, StringComparison.Ordinal));
|
||||
idx = s.IndexOf(Environment.NewLine, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
// Remove first word from the next subtitle.
|
||||
// If there is only one word, 'next' will be empty.
|
||||
next.Text = (idx > 0 ? s.Substring(idx + 1).Trim() : string.Empty);
|
||||
|
||||
// If the first subtitle ends with a tag (</i>):
|
||||
string endTag = string.Empty;
|
||||
if (p.Text.EndsWith('>') && p.Text.Contains('<'))
|
||||
{
|
||||
// Save the end tag.
|
||||
endTag = p.Text.Substring(p.Text.LastIndexOf('<'), p.Text.Length - p.Text.LastIndexOf('<'));
|
||||
// Remove the endTag from first subtitle.
|
||||
p.Text = p.Text.Remove(p.Text.LastIndexOf('<'));
|
||||
}
|
||||
|
||||
// If the first subtitle ends with "...":
|
||||
bool firstSubtitleEndsWithEllipsis = p.Text.EndsWith("...", StringComparison.Ordinal);
|
||||
if (firstSubtitleEndsWithEllipsis)
|
||||
{
|
||||
// Remove "..." from first subtitle.
|
||||
p.Text = p.Text.TrimEnd('.');
|
||||
}
|
||||
|
||||
// If the second subtitle (next) starts with a position tag, like {\an8}:
|
||||
string positionTag = string.Empty;
|
||||
if (firstWord.StartsWith('{') && firstWord.Contains('}'))
|
||||
{
|
||||
// Save the start tag.
|
||||
positionTag = firstWord.Substring(firstWord.IndexOf('{'), firstWord.IndexOf('}') + 1);
|
||||
// Remove the position tag from the first word.
|
||||
firstWord = firstWord.Remove(0, firstWord.IndexOf('}') + 1);
|
||||
}
|
||||
|
||||
// If the second subtitle (next) starts with a tag:
|
||||
string startTag = string.Empty;
|
||||
if (firstWord.StartsWith('<') && firstWord.Contains('>'))
|
||||
{
|
||||
// Save the start tag.
|
||||
startTag = firstWord.Substring(firstWord.IndexOf('<'), firstWord.IndexOf('>') + 1);
|
||||
// Remove the start tag from the first word.
|
||||
firstWord = firstWord.Remove(0, firstWord.IndexOf('>') + 1);
|
||||
}
|
||||
|
||||
// If the second subtitle ends with a tag and there's only one word in it:
|
||||
if (next.Text.EndsWith('>') && next.Text.Contains('<') && !next.Text.Contains(' '))
|
||||
{
|
||||
// Remove the end tag.
|
||||
next.Text = next.Text.Remove(next.Text.LastIndexOf('<'));
|
||||
}
|
||||
|
||||
// If the second subtitle (next) starts with a dialog ("-"):
|
||||
string dialogMarker = string.Empty;
|
||||
if (firstWord.StartsWith('-'))
|
||||
{
|
||||
// Save the dialog marker ("-" or "- ").
|
||||
dialogMarker = (firstWord.StartsWith("- ", StringComparison.Ordinal) ? "- " : "-");
|
||||
// Remove the dialog marker from the first word.
|
||||
firstWord = firstWord.Remove(0, dialogMarker.Length);
|
||||
}
|
||||
|
||||
// If the second subtitle starts with "...":
|
||||
bool nextSubtitleStartsWithEllipsis = firstWord.StartsWith("...", StringComparison.Ordinal);
|
||||
if (nextSubtitleStartsWithEllipsis)
|
||||
{
|
||||
// Remove "..." from the beginning of first word.
|
||||
firstWord = firstWord.TrimStart('.');
|
||||
}
|
||||
|
||||
// Add positionTag + startTag + dialogMarker + "..." + text to 'next'.
|
||||
if (idx > 0)
|
||||
{
|
||||
next.Text = positionTag + startTag + dialogMarker + (nextSubtitleStartsWithEllipsis ? "..." : string.Empty) + next.Text.Trim();
|
||||
}
|
||||
|
||||
// Add text + firstWord + "..." + endTag to First line.
|
||||
bool isEmpty = HtmlUtil.RemoveHtmlTags(p.Text, true).Length == 0;
|
||||
p.Text = (idx == 0 ? startTag : string.Empty) + p.Text.Trim() + (isEmpty ? string.Empty : " ") + firstWord.Trim() + (idx > 0 && firstSubtitleEndsWithEllipsis ? "..." : string.Empty) + endTag;
|
||||
|
||||
// Now, idx will hold the position of the last line break, if any.
|
||||
idx = p.Text.LastIndexOf(Environment.NewLine, StringComparison.Ordinal);
|
||||
|
||||
// Check if the last line of the subtitle (the one that now contains the moved word) is longer than SubtitleLineMaximumLength.
|
||||
if (HtmlUtil.RemoveHtmlTags(p.Text.Substring((idx > 0 ? idx + Environment.NewLine.Length : 0))).Length > Configuration.Settings.General.SubtitleLineMaximumLength)
|
||||
{
|
||||
p.Text = Utilities.AutoBreakLine(p.Text);
|
||||
}
|
||||
p.Text = moveUpDown.S1;
|
||||
next.Text = moveUpDown.S2;
|
||||
SubtitleListview1.SetText(firstIndex, p.Text);
|
||||
SubtitleListview1.SetText(firstIndex + 1, next.Text);
|
||||
textBoxListViewText.Text = p.Text;
|
||||
}
|
||||
|
||||
SubtitleListview1.SetText(firstIndex, p.Text);
|
||||
SubtitleListview1.SetText(firstIndex + 1, next.Text);
|
||||
textBoxListViewText.Text = p.Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9315,123 +9199,17 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
var next = _subtitle.GetParagraphOrDefault(firstIndex + 1);
|
||||
if (p != null && next != null)
|
||||
{
|
||||
string s = p.Text.Trim();
|
||||
int idx = s.LastIndexOf(' ');
|
||||
if (s.StartsWith("{\\", StringComparison.Ordinal))
|
||||
var moveUpDown = new MoveWordUpDown(p.Text, next.Text);
|
||||
moveUpDown.MoveWordDown();
|
||||
if (moveUpDown.S1 != p.Text && moveUpDown.S2 != next.Text)
|
||||
{
|
||||
var endTagIndex = s.IndexOf('}');
|
||||
if (endTagIndex > 0 && idx < endTagIndex)
|
||||
{
|
||||
idx = endTagIndex+1;
|
||||
}
|
||||
|
||||
if (idx >= s.Length - 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (idx > 0 || s.Length > 0)
|
||||
// A last word was found or the first subtitle is not empty (has one word).
|
||||
{
|
||||
// Undo
|
||||
MakeHistoryForUndo(_language.BeforeLineUpdatedInListView);
|
||||
|
||||
// Define lastWord. If idx > 0, there is a last word.
|
||||
// If not, lastWord is the whole text of the first subtitle.
|
||||
string lastWord = idx > 0 ? s.Substring(idx).Trim() : p.Text;
|
||||
|
||||
// If lastWord contains a line break, it has two words.
|
||||
if (lastWord.Contains(Environment.NewLine))
|
||||
{
|
||||
// Redefine lastWord and idx.
|
||||
lastWord = lastWord.Substring(lastWord.LastIndexOf(Environment.NewLine, StringComparison.Ordinal));
|
||||
idx = s.LastIndexOf(Environment.NewLine, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
// Remove last word from the first subtitle.
|
||||
p.Text = idx > 0 ? s.Substring(0, idx).Trim() : string.Empty;
|
||||
|
||||
// If the first subtitle ends with a tag (</i>):
|
||||
string endTag = string.Empty;
|
||||
if (lastWord.EndsWith('>') && lastWord.Contains('<'))
|
||||
{
|
||||
// Save the end tag.
|
||||
endTag = lastWord.Substring(lastWord.LastIndexOf('<'), lastWord.Length - lastWord.LastIndexOf('<'));
|
||||
// Remove the end tag from the last word.
|
||||
lastWord = lastWord.Remove(lastWord.LastIndexOf('<'));
|
||||
}
|
||||
|
||||
// If the first subtitle ends with "...":
|
||||
bool firstSubtitleEndsWithEllipsis = lastWord.EndsWith("...", StringComparison.Ordinal);
|
||||
if (firstSubtitleEndsWithEllipsis)
|
||||
{
|
||||
// Remove "..." from the last word.
|
||||
lastWord = lastWord.TrimEnd('.');
|
||||
}
|
||||
|
||||
// If the second subtitle (next) starts with a position tag, like {\an8}:
|
||||
string positionTag = string.Empty;
|
||||
if (next.Text.StartsWith('{') && next.Text.Contains('}'))
|
||||
{
|
||||
// Save the start tag.
|
||||
positionTag = next.Text.Substring(next.Text.IndexOf('{'), next.Text.IndexOf('}') + 1);
|
||||
// Remove the position tag from next subtitle.
|
||||
next.Text = next.Text.Remove(0, next.Text.IndexOf('}') + 1);
|
||||
}
|
||||
|
||||
// If the second subtitle (next) starts with a tag:
|
||||
string startTag = string.Empty;
|
||||
if (next.Text.StartsWith('<') && next.Text.Contains('>'))
|
||||
{
|
||||
// Save the start tag.
|
||||
startTag = next.Text.Substring(next.Text.IndexOf('<'), next.Text.IndexOf('>') + 1);
|
||||
// Remove the start tag from next subtitle.
|
||||
next.Text = next.Text.Remove(0, next.Text.IndexOf('>') + 1);
|
||||
}
|
||||
|
||||
// If the second subtitle (next) starts with a dialog ("-"):
|
||||
string dialogMarker = string.Empty;
|
||||
if (next.Text.StartsWith('-'))
|
||||
{
|
||||
// Save the dialog marker ("-" or "- ").
|
||||
dialogMarker = (next.Text.StartsWith("- ", StringComparison.Ordinal) ? "- " : "-");
|
||||
// Remove the dialog marker from the next subtitle.
|
||||
next.Text = next.Text.Remove(0, dialogMarker.Length);
|
||||
}
|
||||
|
||||
// If the second subtitle starts with "...":
|
||||
bool nextSubtitleStartsWithEllipsis = next.Text.StartsWith("...", StringComparison.Ordinal);
|
||||
if (nextSubtitleStartsWithEllipsis)
|
||||
{
|
||||
// Remove "..." from the beginning of 'next'.
|
||||
next.Text = next.Text.TrimStart('.');
|
||||
}
|
||||
|
||||
// Add text + "..." + endTag to first subtitle.
|
||||
if (idx > 0)
|
||||
{
|
||||
p.Text = p.Text + (firstSubtitleEndsWithEllipsis ? "..." : string.Empty) + endTag;
|
||||
}
|
||||
|
||||
// Add positionTag + startTag + dialogMarker + "..." + lastWord to 'next'.
|
||||
next.Text = (idx > 0 ? positionTag : string.Empty) +
|
||||
(idx > 0 ? startTag : string.Empty) + dialogMarker +
|
||||
(nextSubtitleStartsWithEllipsis && idx > 0 ? "..." : string.Empty) +
|
||||
lastWord.Trim() + " " + next.Text.Trim();
|
||||
|
||||
// Now, idx will hold the position of the first line break, if any.
|
||||
idx = next.Text.IndexOf(Environment.NewLine, StringComparison.Ordinal);
|
||||
|
||||
// Check if the first line of the next subtitle (the one that now contains the moved word) is longer than SubtitleLineMaximumLength.
|
||||
if (HtmlUtil.RemoveHtmlTags(next.Text.Substring(0, (idx > 0 ? idx : next.Text.Length))).Length > Configuration.Settings.General.SubtitleLineMaximumLength)
|
||||
{
|
||||
next.Text = Utilities.AutoBreakLine(next.Text);
|
||||
}
|
||||
p.Text = moveUpDown.S1;
|
||||
next.Text = moveUpDown.S2;
|
||||
SubtitleListview1.SetText(firstIndex, p.Text);
|
||||
SubtitleListview1.SetText(firstIndex + 1, next.Text);
|
||||
textBoxListViewText.Text = p.Text;
|
||||
}
|
||||
|
||||
SubtitleListview1.SetText(firstIndex, p.Text);
|
||||
SubtitleListview1.SetText(firstIndex + 1, next.Text);
|
||||
textBoxListViewText.Text = p.Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
225
src/Test/Logic/Forms/MoveWordUpDownTest.cs
Normal file
225
src/Test/Logic/Forms/MoveWordUpDownTest.cs
Normal file
@ -0,0 +1,225 @@
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Nikse.SubtitleEdit.Core.Forms;
|
||||
|
||||
namespace Test.Logic.Forms
|
||||
{
|
||||
[TestClass]
|
||||
public class MoveWordUpDownTest
|
||||
{
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordDownSimple()
|
||||
{
|
||||
var x = new MoveWordUpDown("Hallo my", "dear friend!");
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual("Hallo", x.S1);
|
||||
Assert.AreEqual("my dear friend!", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual(string.Empty, x.S1);
|
||||
Assert.AreEqual("Hallo my dear friend!", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual(string.Empty, x.S1);
|
||||
Assert.AreEqual("Hallo my dear friend!", x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordUpSimple()
|
||||
{
|
||||
var x = new MoveWordUpDown("Hallo my", "dear friend!");
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("Hallo my dear", x.S1);
|
||||
Assert.AreEqual("friend!", x.S2);
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("Hallo my dear friend!", x.S1);
|
||||
Assert.AreEqual(string.Empty, x.S2);
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("Hallo my dear friend!", x.S1);
|
||||
Assert.AreEqual(string.Empty, x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordDownSimpleAssTag()
|
||||
{
|
||||
var x = new MoveWordUpDown("{\\an8}Hallo my", "dear friend!");
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual("{\\an8}Hallo", x.S1);
|
||||
Assert.AreEqual("my dear friend!", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual(string.Empty, x.S1);
|
||||
Assert.AreEqual("Hallo my dear friend!", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual(string.Empty, x.S1);
|
||||
Assert.AreEqual("Hallo my dear friend!", x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordUpSimpleAssTag()
|
||||
{
|
||||
var x = new MoveWordUpDown("{\\an8}Hallo my", "dear friend!");
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("{\\an8}Hallo my dear", x.S1);
|
||||
Assert.AreEqual("friend!", x.S2);
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("{\\an8}Hallo my dear friend!", x.S1);
|
||||
Assert.AreEqual(string.Empty, x.S2);
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("{\\an8}Hallo my dear friend!", x.S1);
|
||||
Assert.AreEqual(string.Empty, x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordDownSimpleHtmlTag()
|
||||
{
|
||||
var x = new MoveWordUpDown("<i>Hallo my</i>", "<i>dear friend!</i>");
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual("<i>Hallo</i>", x.S1);
|
||||
Assert.AreEqual("<i>my dear friend!</i>", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual(string.Empty, x.S1);
|
||||
Assert.AreEqual("<i>Hallo my dear friend!</i>", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual(string.Empty, x.S1);
|
||||
Assert.AreEqual("<i>Hallo my dear friend!</i>", x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordUpSimpleHtmlTag()
|
||||
{
|
||||
var x = new MoveWordUpDown("<i>Hallo my</i>", "<i>dear friend!</i>");
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("<i>Hallo my dear</i>", x.S1);
|
||||
Assert.AreEqual("<i>friend!</i>", x.S2);
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("<i>Hallo my dear friend!</i>", x.S1);
|
||||
Assert.AreEqual(string.Empty, x.S2);
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("<i>Hallo my dear friend!</i>", x.S1);
|
||||
Assert.AreEqual(string.Empty, x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordDownHtmlFontTag()
|
||||
{
|
||||
var x = new MoveWordUpDown("<font color=\"red\">Hallo my</font>", "dear friend!");
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual("<font color=\"red\">Hallo</font>", x.S1);
|
||||
Assert.AreEqual("my dear friend!", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual(string.Empty, x.S1);
|
||||
Assert.AreEqual("Hallo my dear friend!", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual(string.Empty, x.S1);
|
||||
Assert.AreEqual("Hallo my dear friend!", x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordUpHtmlFontTag()
|
||||
{
|
||||
var x = new MoveWordUpDown("Hallo my", "<font color=\"red\">dear friend!</font>");
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("Hallo my dear", x.S1);
|
||||
Assert.AreEqual("<font color=\"red\">friend!</font>", x.S2);
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("Hallo my dear friend!", x.S1);
|
||||
Assert.AreEqual(string.Empty, x.S2);
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("Hallo my dear friend!", x.S1);
|
||||
Assert.AreEqual(string.Empty, x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordDownAssFontTag()
|
||||
{
|
||||
var x = new MoveWordUpDown("{\\fnArabic Typesetting\\fs34}AAA BBB CCC", "DDD");
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual("{\\fnArabic Typesetting\\fs34}AAA BBB", x.S1);
|
||||
Assert.AreEqual("CCC DDD", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual("{\\fnArabic Typesetting\\fs34}AAA", x.S1);
|
||||
Assert.AreEqual("BBB CCC DDD", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual(string.Empty, x.S1);
|
||||
Assert.AreEqual("AAA BBB CCC DDD", x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordDownAssFontTag2()
|
||||
{
|
||||
var x = new MoveWordUpDown("AAA BBB CCC", "{\\fnArabic Typesetting\\fs34}DDD");
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual("AAA BBB", x.S1);
|
||||
Assert.AreEqual("{\\fnArabic Typesetting\\fs34}CCC DDD", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual("AAA", x.S1);
|
||||
Assert.AreEqual("{\\fnArabic Typesetting\\fs34}BBB CCC DDD", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual(string.Empty, x.S1);
|
||||
Assert.AreEqual("{\\fnArabic Typesetting\\fs34}AAA BBB CCC DDD", x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordUpAssFontTag()
|
||||
{
|
||||
var x = new MoveWordUpDown("AAA BBB", "{\\fnArabic Typesetting\\fs34}CCC DDD");
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("AAA BBB CCC", x.S1);
|
||||
Assert.AreEqual("{\\fnArabic Typesetting\\fs34}DDD", x.S2);
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("AAA BBB CCC DDD", x.S1);
|
||||
Assert.AreEqual(string.Empty, x.S2);
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("AAA BBB CCC DDD", x.S1);
|
||||
Assert.AreEqual(string.Empty, x.S2);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordDownSimpleHtmlTagInline()
|
||||
{
|
||||
var x = new MoveWordUpDown("Hallo <i>my</i> dear", "friend!");
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual("Hallo <i>my</i>", x.S1);
|
||||
Assert.AreEqual("dear friend!", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual("Hallo", x.S1);
|
||||
Assert.AreEqual("my dear friend!", x.S2);
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual(string.Empty, x.S1);
|
||||
Assert.AreEqual("Hallo my dear friend!", x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordUpSimpleHtmlTagInline()
|
||||
{
|
||||
var x = new MoveWordUpDown("Hallo", "my <i>dear</i> friend!");
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("Hallo my", x.S1);
|
||||
Assert.AreEqual("<i>dear</i> friend!", x.S2);
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("Hallo my dear", x.S1);
|
||||
Assert.AreEqual("friend!", x.S2);
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("Hallo my dear friend!", x.S1);
|
||||
Assert.AreEqual(string.Empty, x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordUpAutoBr()
|
||||
{
|
||||
var x = new MoveWordUpDown("0123456789A 0123456789A 0123456789A", "0123456789A 0123456789A 0123456789A");
|
||||
x.MoveWordUp();
|
||||
Assert.AreEqual("0123456789A 0123456789A" + Environment.NewLine + "0123456789A 0123456789A", x.S1);
|
||||
Assert.AreEqual("0123456789A 0123456789A", x.S2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoveWordDownAutoBr()
|
||||
{
|
||||
var x = new MoveWordUpDown("0123456789A 0123456789A 0123456789A", "0123456789A 0123456789A 0123456789A");
|
||||
x.MoveWordDown();
|
||||
Assert.AreEqual("0123456789A 0123456789A", x.S1);
|
||||
Assert.AreEqual("0123456789A 0123456789A" + Environment.NewLine + "0123456789A 0123456789A", x.S2);
|
||||
}
|
||||
}
|
||||
}
|
@ -55,6 +55,7 @@
|
||||
<Compile Include="Core\SubtitleTest.cs" />
|
||||
<Compile Include="Core\RichTextToPlainTextTest.cs" />
|
||||
<Compile Include="Logic\BridgeGapsTest.cs" />
|
||||
<Compile Include="Logic\Forms\MoveWordUpDownTest.cs" />
|
||||
<Compile Include="Logic\NetflixQualityCheckTest.cs" />
|
||||
<Compile Include="Logic\Ocr\BinaryOcrTest.cs" />
|
||||
<Compile Include="Core\HtmlUtilTest.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user