mirror of
https://github.com/SubtitleEdit/subtitleedit.git
synced 2024-11-22 03:02:35 +01:00
Work on translate
This commit is contained in:
parent
0ecef2a641
commit
f98c0a1eda
@ -30,6 +30,7 @@
|
||||
* Fix for unwanted "<br />" in MS translator - thx Miguel
|
||||
* Only add recent file if saved - thx F5System
|
||||
* Fix for mouse wheel scroll direction in video player - thx Peter
|
||||
* Fix for ASSA border width in export to image based format - thx Christian
|
||||
|
||||
|
||||
4.0.2 (19th November 2023)
|
||||
|
@ -24,7 +24,7 @@ namespace Nikse.SubtitleEdit.Core.AutoTranslate
|
||||
public void Initialize()
|
||||
{
|
||||
_httpClient?.Dispose();
|
||||
_httpClient = new HttpClient(); //DownloaderFactory.MakeHttpClient();
|
||||
_httpClient = new HttpClient();
|
||||
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");
|
||||
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("accept", "application/json");
|
||||
_httpClient.BaseAddress = new Uri(Configuration.Settings.Tools.AutoTranslateLibreUrl);
|
||||
|
@ -2632,6 +2632,7 @@ $HorzAlign = Center
|
||||
public string MainAdjustViaEndAutoStart { get; set; }
|
||||
public string MainAdjustViaEndAutoStartAndGoToNext { get; set; }
|
||||
public string MainAdjustSetEndMinusGapAndStartNextHere { get; set; }
|
||||
public string MainAdjustSetEndAndStartOfNextPlusGap { get; set; }
|
||||
public string MainAdjustSetStartAutoDurationAndGoToNext { get; set; }
|
||||
public string MainAdjustSetEndNextStartAndGoToNext { get; set; }
|
||||
public string MainAdjustStartDownEndUpAndGoToNext { get; set; }
|
||||
@ -10686,6 +10687,12 @@ $HorzAlign = Center
|
||||
shortcuts.MainAdjustSetEndMinusGapAndStartNextHere = subNode.InnerText;
|
||||
}
|
||||
|
||||
subNode = node.SelectSingleNode("MainAdjustSetEndAndStartOfNextPlusGap");
|
||||
if (subNode != null)
|
||||
{
|
||||
shortcuts.MainAdjustSetEndAndStartOfNextPlusGap = subNode.InnerText;
|
||||
}
|
||||
|
||||
subNode = node.SelectSingleNode("MainAdjustSetStartAutoDurationAndGoToNext");
|
||||
if (subNode != null)
|
||||
{
|
||||
@ -12701,6 +12708,7 @@ $HorzAlign = Center
|
||||
textWriter.WriteElementString("MainAdjustViaEndAutoStart", shortcuts.MainAdjustViaEndAutoStart);
|
||||
textWriter.WriteElementString("MainAdjustViaEndAutoStartAndGoToNext", shortcuts.MainAdjustViaEndAutoStartAndGoToNext);
|
||||
textWriter.WriteElementString("MainAdjustSetEndMinusGapAndStartNextHere", shortcuts.MainAdjustSetEndMinusGapAndStartNextHere);
|
||||
textWriter.WriteElementString("MainAdjustSetEndAndStartOfNextPlusGap", shortcuts.MainAdjustSetEndAndStartOfNextPlusGap);
|
||||
textWriter.WriteElementString("MainAdjustSetStartAutoDurationAndGoToNext", shortcuts.MainAdjustSetStartAutoDurationAndGoToNext);
|
||||
textWriter.WriteElementString("MainAdjustSetEndNextStartAndGoToNext", shortcuts.MainAdjustSetEndNextStartAndGoToNext);
|
||||
textWriter.WriteElementString("MainAdjustStartDownEndUpAndGoToNext", shortcuts.MainAdjustStartDownEndUpAndGoToNext);
|
||||
|
@ -49,7 +49,7 @@ namespace Nikse.SubtitleEdit.Core.Translate
|
||||
|
||||
public string SetTagsAndReturnTrimmed(string input, string sourceLanguage)
|
||||
{
|
||||
if (string.IsNullOrEmpty(HtmlUtil.RemoveHtmlTags(input, true)))
|
||||
if (string.IsNullOrWhiteSpace(HtmlUtil.RemoveHtmlTags(input, true).Replace("♪", string.Empty).Replace("♫", string.Empty)))
|
||||
{
|
||||
ReplaceAllText = input;
|
||||
return "...";
|
||||
|
@ -2484,12 +2484,12 @@ $DROP=[DROPVALUE]" + Environment.NewLine + Environment.NewLine +
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (float.TryParse(comboBoxBorderWidth.SelectedItem.ToString(), out var f))
|
||||
if (float.TryParse(comboBoxBorderWidth.SelectedItem.ToString().Replace(',', '.'), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var f))
|
||||
{
|
||||
return f;
|
||||
}
|
||||
|
||||
if (float.TryParse(Utilities.RemoveNonNumbers(comboBoxBorderWidth.SelectedItem.ToString()), out f))
|
||||
if (float.TryParse(Utilities.RemoveNonNumbers(comboBoxBorderWidth.SelectedItem.ToString()).Replace(',', '.'), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out f))
|
||||
{
|
||||
return f;
|
||||
}
|
||||
|
@ -18803,6 +18803,11 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
SetEndMinusGapAndStartNextHere(FirstSelectedIndex);
|
||||
e.SuppressKeyPress = true;
|
||||
}
|
||||
else if (mediaPlayer.VideoPlayer != null && _shortcuts.MainAdjustSetEndAndStartOfNextPlusGap == e.KeyData)
|
||||
{
|
||||
MainAdjustSetEndAndStartOfNextPlusGap(FirstSelectedIndex);
|
||||
e.SuppressKeyPress = true;
|
||||
}
|
||||
else if (mediaPlayer.VideoPlayer != null && _shortcuts.MainAdjustSetStartAutoDurationAndGoToNext == e.KeyData)
|
||||
{
|
||||
SetCurrentStartAutoDurationAndGotoNext(FirstSelectedIndex);
|
||||
@ -29763,6 +29768,76 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
UpdateSourceView();
|
||||
}
|
||||
|
||||
public void MainAdjustSetEndAndStartOfNextPlusGap(int index)
|
||||
{
|
||||
var p = _subtitle.GetParagraphOrDefault(index);
|
||||
if (p == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mediaPlayer.VideoPlayer == null || string.IsNullOrEmpty(_videoFileName))
|
||||
{
|
||||
MessageBox.Show(_languageGeneral.NoVideoLoaded);
|
||||
return;
|
||||
}
|
||||
|
||||
double totalMillisecondsEnd = mediaPlayer.CurrentPosition * TimeCode.BaseUnit;
|
||||
var oldParagraph = new Paragraph(p, false);
|
||||
var newDurationMs = totalMillisecondsEnd - p.StartTime.TotalMilliseconds;
|
||||
if (!p.StartTime.IsMaxTime &&
|
||||
newDurationMs < Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds &&
|
||||
newDurationMs > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var tc = new TimeCode(totalMillisecondsEnd);
|
||||
MakeHistoryForUndo(_language.BeforeSetEndAndVideoPosition + " " + tc);
|
||||
_makeHistoryPaused = true;
|
||||
|
||||
if (p.StartTime.IsMaxTime)
|
||||
{
|
||||
p.EndTime.TotalMilliseconds = totalMillisecondsEnd;
|
||||
p.StartTime.TotalMilliseconds = p.EndTime.TotalMilliseconds - Utilities.GetOptimalDisplayMilliseconds(p.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.EndTime.TotalMilliseconds = totalMillisecondsEnd;
|
||||
}
|
||||
|
||||
timeUpDownStartTime.TimeCode = p.StartTime;
|
||||
var durationInSeconds = (decimal)p.DurationTotalSeconds;
|
||||
if (durationInSeconds >= numericUpDownDuration.Minimum && durationInSeconds <= numericUpDownDuration.Maximum)
|
||||
{
|
||||
SetDurationInSeconds((double)durationInSeconds);
|
||||
}
|
||||
|
||||
var next = _subtitle.GetParagraphOrDefault(index + 1);
|
||||
Paragraph oldNextParagraph = null;
|
||||
if (next != null && (next.StartTime.IsMaxTime || next.StartTime.TotalMilliseconds - totalMillisecondsEnd < 5_000))
|
||||
{
|
||||
oldNextParagraph = new Paragraph(next, false);
|
||||
next.StartTime.TotalMilliseconds = totalMillisecondsEnd + MinGapBetweenLines;
|
||||
|
||||
if (next.StartTime.IsMaxTime)
|
||||
{
|
||||
next.EndTime.TotalMilliseconds = totalMillisecondsEnd + MinGapBetweenLines + Configuration.Settings.General.NewEmptyDefaultMs;
|
||||
}
|
||||
}
|
||||
|
||||
RestartHistory();
|
||||
|
||||
UpdateOriginalTimeCodes(oldParagraph, oldNextParagraph);
|
||||
SubtitleListview1.SetStartTimeAndDuration(index - 1, _subtitle.GetParagraphOrDefault(index - 1), _subtitle.GetParagraphOrDefault(index), _subtitle.GetParagraphOrDefault(index - 2));
|
||||
SubtitleListview1.SetStartTimeAndDuration(index, _subtitle.GetParagraphOrDefault(index), _subtitle.GetParagraphOrDefault(index + 1), _subtitle.GetParagraphOrDefault(index - 1));
|
||||
SubtitleListview1.SetStartTimeAndDuration(index + 1, _subtitle.GetParagraphOrDefault(index + 1), _subtitle.GetParagraphOrDefault(index + 2), _subtitle.GetParagraphOrDefault(index));
|
||||
RefreshSelectedParagraph();
|
||||
ShowStatus(string.Format(_language.VideoControls.AdjustedViaEndTime, p.StartTime.ToShortString()));
|
||||
audioVisualizer.Invalidate();
|
||||
UpdateSourceView();
|
||||
}
|
||||
|
||||
public void SetCurrentViaEndPositionAndGotoNext(int index, bool goToNext)
|
||||
{
|
||||
var p = _subtitle.GetParagraphOrDefault(index);
|
||||
|
@ -1844,6 +1844,7 @@ namespace Nikse.SubtitleEdit.Forms.Options
|
||||
AddNode(createAndAdjustNode, language.AdjustSetEndAndOffsetTheRestAndGoToNext, nameof(Configuration.Settings.Shortcuts.MainAdjustSetEndAndOffsetTheRestAndGoToNext));
|
||||
AddNode(createAndAdjustNode, language.AdjustSetEndNextStartAndGoToNext, nameof(Configuration.Settings.Shortcuts.MainAdjustSetEndNextStartAndGoToNext));
|
||||
AddNode(createAndAdjustNode, language.AdjustSetEndMinusGapAndStartNextHere, nameof(Configuration.Settings.Shortcuts.MainAdjustSetEndMinusGapAndStartNextHere));
|
||||
AddNode(createAndAdjustNode, "Set end and start of next after gap", nameof(Configuration.Settings.Shortcuts.MainAdjustSetEndAndStartOfNextPlusGap));
|
||||
AddNode(createAndAdjustNode, language.AdjustViaEndAutoStart, nameof(Configuration.Settings.Shortcuts.MainAdjustViaEndAutoStart));
|
||||
AddNode(createAndAdjustNode, language.AdjustViaEndAutoStartAndGoToNext, nameof(Configuration.Settings.Shortcuts.MainAdjustViaEndAutoStartAndGoToNext));
|
||||
AddNode(createAndAdjustNode, language.AdjustSelected100MsBack, nameof(Configuration.Settings.Shortcuts.MainAdjustSelected100MsBack));
|
||||
|
82
src/ui/Forms/Translate/AutoTranslate.Designer.cs
generated
82
src/ui/Forms/Translate/AutoTranslate.Designer.cs
generated
@ -42,10 +42,15 @@
|
||||
this.toolStripMenuItemStartLibre = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItemStartNLLBServe = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItemStartNLLBApi = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.translateSingleLinesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.startLibreTranslateServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.startNLLBServeServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.startNLLBAPIServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.translateSingleLinesToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.labelApiKey = new System.Windows.Forms.Label();
|
||||
this.nikseTextBoxApiKey = new Nikse.SubtitleEdit.Controls.NikseTextBox();
|
||||
this.nikseComboBoxEngine = new Nikse.SubtitleEdit.Controls.NikseComboBox();
|
||||
this.nikseComboBoxUrl = new Nikse.SubtitleEdit.Controls.NikseComboBox();
|
||||
@ -53,11 +58,6 @@
|
||||
this.comboBoxTarget = new Nikse.SubtitleEdit.Controls.NikseComboBox();
|
||||
this.subtitleListViewTarget = new Nikse.SubtitleEdit.Controls.SubtitleListView();
|
||||
this.subtitleListViewSource = new Nikse.SubtitleEdit.Controls.SubtitleListView();
|
||||
this.labelApiKey = new System.Windows.Forms.Label();
|
||||
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.translateSingleLinesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.translateSingleLinesToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.contextMenuStrip2.SuspendLayout();
|
||||
this.contextMenuStrip1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
@ -159,7 +159,7 @@
|
||||
this.toolStripSeparator1,
|
||||
this.translateSingleLinesToolStripMenuItem});
|
||||
this.contextMenuStrip2.Name = "contextMenuStrip1";
|
||||
this.contextMenuStrip2.Size = new System.Drawing.Size(197, 120);
|
||||
this.contextMenuStrip2.Size = new System.Drawing.Size(197, 98);
|
||||
this.contextMenuStrip2.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStrip2_Opening);
|
||||
//
|
||||
// toolStripMenuItemStartLibre
|
||||
@ -182,6 +182,18 @@
|
||||
this.toolStripMenuItemStartNLLBApi.Size = new System.Drawing.Size(196, 22);
|
||||
this.toolStripMenuItemStartNLLBApi.Text = "Start NLLB API server";
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
this.toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
this.toolStripSeparator1.Size = new System.Drawing.Size(193, 6);
|
||||
//
|
||||
// translateSingleLinesToolStripMenuItem
|
||||
//
|
||||
this.translateSingleLinesToolStripMenuItem.Name = "translateSingleLinesToolStripMenuItem";
|
||||
this.translateSingleLinesToolStripMenuItem.Size = new System.Drawing.Size(196, 22);
|
||||
this.translateSingleLinesToolStripMenuItem.Text = "Translate single lines";
|
||||
this.translateSingleLinesToolStripMenuItem.Click += new System.EventHandler(this.translateSingleLinesToolStripMenuItem_Click);
|
||||
//
|
||||
// contextMenuStrip1
|
||||
//
|
||||
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
@ -214,6 +226,28 @@
|
||||
this.startNLLBAPIServerToolStripMenuItem.Size = new System.Drawing.Size(196, 22);
|
||||
this.startNLLBAPIServerToolStripMenuItem.Text = "Start NLLB API server";
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
this.toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
this.toolStripSeparator2.Size = new System.Drawing.Size(193, 6);
|
||||
//
|
||||
// translateSingleLinesToolStripMenuItem1
|
||||
//
|
||||
this.translateSingleLinesToolStripMenuItem1.Name = "translateSingleLinesToolStripMenuItem1";
|
||||
this.translateSingleLinesToolStripMenuItem1.Size = new System.Drawing.Size(196, 22);
|
||||
this.translateSingleLinesToolStripMenuItem1.Text = "Translate single lines";
|
||||
this.translateSingleLinesToolStripMenuItem1.Click += new System.EventHandler(this.translateSingleLinesToolStripMenuItem1_Click);
|
||||
//
|
||||
// labelApiKey
|
||||
//
|
||||
this.labelApiKey.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.labelApiKey.AutoSize = true;
|
||||
this.labelApiKey.Location = new System.Drawing.Point(360, 533);
|
||||
this.labelApiKey.Name = "labelApiKey";
|
||||
this.labelApiKey.Size = new System.Drawing.Size(47, 13);
|
||||
this.labelApiKey.TabIndex = 111;
|
||||
this.labelApiKey.Text = "API key:";
|
||||
//
|
||||
// nikseTextBoxApiKey
|
||||
//
|
||||
this.nikseTextBoxApiKey.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
@ -363,40 +397,8 @@
|
||||
this.subtitleListViewSource.UseCompatibleStateImageBehavior = false;
|
||||
this.subtitleListViewSource.UseSyntaxColoring = true;
|
||||
this.subtitleListViewSource.View = System.Windows.Forms.View.Details;
|
||||
//
|
||||
// labelApiKey
|
||||
//
|
||||
this.labelApiKey.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.labelApiKey.AutoSize = true;
|
||||
this.labelApiKey.Location = new System.Drawing.Point(360, 533);
|
||||
this.labelApiKey.Name = "labelApiKey";
|
||||
this.labelApiKey.Size = new System.Drawing.Size(47, 13);
|
||||
this.labelApiKey.TabIndex = 111;
|
||||
this.labelApiKey.Text = "API key:";
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
this.toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
this.toolStripSeparator1.Size = new System.Drawing.Size(193, 6);
|
||||
//
|
||||
// translateSingleLinesToolStripMenuItem
|
||||
//
|
||||
this.translateSingleLinesToolStripMenuItem.Name = "translateSingleLinesToolStripMenuItem";
|
||||
this.translateSingleLinesToolStripMenuItem.Size = new System.Drawing.Size(196, 22);
|
||||
this.translateSingleLinesToolStripMenuItem.Text = "Translate single lines";
|
||||
this.translateSingleLinesToolStripMenuItem.Click += new System.EventHandler(this.translateSingleLinesToolStripMenuItem_Click);
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
this.toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
this.toolStripSeparator2.Size = new System.Drawing.Size(193, 6);
|
||||
//
|
||||
// translateSingleLinesToolStripMenuItem1
|
||||
//
|
||||
this.translateSingleLinesToolStripMenuItem1.Name = "translateSingleLinesToolStripMenuItem1";
|
||||
this.translateSingleLinesToolStripMenuItem1.Size = new System.Drawing.Size(196, 22);
|
||||
this.translateSingleLinesToolStripMenuItem1.Text = "Translate single lines";
|
||||
this.translateSingleLinesToolStripMenuItem1.Click += new System.EventHandler(this.translateSingleLinesToolStripMenuItem1_Click);
|
||||
this.subtitleListViewSource.Click += new System.EventHandler(this.subtitleListViewSource_Click);
|
||||
this.subtitleListViewSource.DoubleClick += new System.EventHandler(this.subtitleListViewSource_DoubleClick);
|
||||
//
|
||||
// AutoTranslate
|
||||
//
|
||||
|
@ -99,6 +99,7 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
subtitleListViewSource.Fill(_subtitle);
|
||||
AutoTranslate_Resize(null, null);
|
||||
UpdateTranslation();
|
||||
MergeAndSplitHelper.MergeSplitProblems = false;
|
||||
}
|
||||
|
||||
private void InitializeAutoTranslatorEngines()
|
||||
@ -151,6 +152,7 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
labelApiKey.Visible = false;
|
||||
nikseComboBoxUrl.Visible = false;
|
||||
nikseTextBoxApiKey.Top = nikseComboBoxUrl.Top;
|
||||
labelApiKey.Text = LanguageSettings.Current.Settings.GoogleTranslateApiKey;
|
||||
var engineType = _autoTranslator.GetType();
|
||||
|
||||
if (engineType == typeof(GoogleTranslateV1))
|
||||
@ -228,16 +230,17 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
|
||||
if (engineType == typeof(PapagoTranslate))
|
||||
{
|
||||
|
||||
|
||||
nikseComboBoxUrl.Items.Clear();
|
||||
nikseComboBoxUrl.Items.Add(Configuration.Settings.Tools.AutoTranslatePapagoApiKeyId);
|
||||
nikseComboBoxUrl.SelectedIndex = 0;
|
||||
nikseComboBoxUrl.Visible = true;
|
||||
labelUrl.Visible = true;
|
||||
labelUrl.Text = "API Key ID";
|
||||
labelUrl.Text = "Client ID";
|
||||
nikseComboBoxUrl.Left = labelUrl.Right + 3;
|
||||
|
||||
labelApiKey.Left = nikseComboBoxUrl.Right + 12;
|
||||
labelApiKey.Text = "Client secret";
|
||||
nikseTextBoxApiKey.Text = Configuration.Settings.Tools.AutoTranslatePapagoApiKey;
|
||||
nikseTextBoxApiKey.Left = labelApiKey.Right + 3;
|
||||
labelApiKey.Visible = true;
|
||||
@ -557,7 +560,7 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
timerUpdate.Tick += TimerUpdate_Tick;
|
||||
timerUpdate.Start();
|
||||
var linesTranslated = 0;
|
||||
var forceSingleLineMode = translateSingleLinesToolStripMenuItem.Checked;
|
||||
var forceSingleLineMode = translateSingleLinesToolStripMenuItem.Checked || _autoTranslator.Name == NoLanguageLeftBehindApi.StaticName;
|
||||
var delaySeconds = 0;
|
||||
if (_autoTranslator.Name == ChatGptTranslate.StaticName)
|
||||
{
|
||||
@ -566,6 +569,8 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
|
||||
if (comboBoxSource.SelectedItem is TranslationPair source && comboBoxTarget.SelectedItem is TranslationPair target)
|
||||
{
|
||||
var mergeErrorCount = 0;
|
||||
|
||||
Configuration.Settings.Tools.GoogleTranslateLastTargetLanguage = target.TwoLetterIsoLanguageName ?? target.Code;
|
||||
try
|
||||
{
|
||||
@ -573,23 +578,7 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
var index = start;
|
||||
while (index < _subtitle.Paragraphs.Count)
|
||||
{
|
||||
if (index > start && delaySeconds > 0)
|
||||
{
|
||||
for (var i = delaySeconds; i > 0; i--)
|
||||
{
|
||||
labelPleaseWait.Text = LanguageSettings.Current.GoogleTranslate.PleaseWait + $" ({i})";
|
||||
labelPleaseWait.Refresh();
|
||||
Application.DoEvents();
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
if (_breakTranslation)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
labelPleaseWait.Text = LanguageSettings.Current.GoogleTranslate.PleaseWait;
|
||||
Application.DoEvents();
|
||||
}
|
||||
Delay(delaySeconds, start, index);
|
||||
|
||||
if (_breakTranslation)
|
||||
{
|
||||
@ -605,6 +594,12 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
continue;
|
||||
}
|
||||
|
||||
mergeErrorCount++;
|
||||
if (mergeErrorCount > 20)
|
||||
{
|
||||
forceSingleLineMode = true;
|
||||
}
|
||||
|
||||
var p = _subtitle.Paragraphs[index];
|
||||
var f = new Formatting();
|
||||
var unformattedText = f.SetTagsAndReturnTrimmed(p.Text, source.Code);
|
||||
@ -657,6 +652,27 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
buttonOK.Focus();
|
||||
}
|
||||
|
||||
private void Delay(int delaySeconds, int start, int index)
|
||||
{
|
||||
if (index > start && delaySeconds > 0)
|
||||
{
|
||||
for (var i = delaySeconds; i > 0; i--)
|
||||
{
|
||||
labelPleaseWait.Text = LanguageSettings.Current.GoogleTranslate.PleaseWait + $" ({i})";
|
||||
labelPleaseWait.Refresh();
|
||||
Application.DoEvents();
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
if (_breakTranslation)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
labelPleaseWait.Text = LanguageSettings.Current.GoogleTranslate.PleaseWait;
|
||||
Application.DoEvents();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleError(Exception exception, int linesTranslate, Type engineType)
|
||||
{
|
||||
SeLogger.Error(exception);
|
||||
@ -684,7 +700,7 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
Environment.NewLine +
|
||||
LanguageSettings.Current.GoogleTranslate.ReadMore + Environment.NewLine +
|
||||
Environment.NewLine +
|
||||
"AutoTranslatePapagoApiKeyId and AutoTranslatePapagoApiKey needs to be filled out in Settings.xml" + Environment.NewLine +
|
||||
"Client ID and Client secrect are required" + Environment.NewLine +
|
||||
Environment.NewLine +
|
||||
_autoTranslator.Error,
|
||||
Text,
|
||||
@ -962,5 +978,15 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
{
|
||||
ToggleTranslateSingleLines();
|
||||
}
|
||||
|
||||
private void subtitleListViewSource_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
SyncListViews(subtitleListViewSource, subtitleListViewTarget);
|
||||
}
|
||||
|
||||
private void subtitleListViewSource_Click(object sender, EventArgs e)
|
||||
{
|
||||
SyncListViews(subtitleListViewSource, subtitleListViewTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,84 +9,66 @@ using Nikse.SubtitleEdit.Core.Translate;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
{
|
||||
public static class MergeAndSplitHelper
|
||||
public static partial class MergeAndSplitHelper
|
||||
{
|
||||
public static bool MergeSplitProblems { get; set; }
|
||||
|
||||
public static async Task<int> MergeAndTranslateIfPossible(Subtitle sourceSubtitle, Subtitle targetSubtitle, TranslationPair source, TranslationPair target, int index, IAutoTranslator autoTranslator, bool forceSingleLineMode)
|
||||
{
|
||||
var noSentenceEndingSource = IsNonMergeLanguage(source.Code);
|
||||
var noSentenceEndingTarget = IsNonMergeLanguage(target.Code);
|
||||
|
||||
if (forceSingleLineMode)
|
||||
{
|
||||
noSentenceEndingSource = true; // will add separator between lines
|
||||
return 0;
|
||||
}
|
||||
|
||||
var p = sourceSubtitle.Paragraphs[index];
|
||||
char? splitAtChar = null;
|
||||
var mergeCount = 0;
|
||||
var allItalic = false;
|
||||
var allBold = false;
|
||||
var text = string.Empty;
|
||||
var linesTranslate = 0;
|
||||
|
||||
MergeResult mergeResult = null;
|
||||
List<Formatting> formattings = null;
|
||||
|
||||
var noSentenceEndingSource = IsNonMergeLanguage(source);
|
||||
var noSentenceEndingTarget = IsNonMergeLanguage(target);
|
||||
|
||||
// Try to handle (remove and save info for later restore) italics, bold, alignment, and more where possible
|
||||
var tempSubtitle = new Subtitle(sourceSubtitle);
|
||||
formattings = HandleFormatting(tempSubtitle, index, target.Code);
|
||||
List<Formatting> formattings = HandleFormatting(tempSubtitle, index, target.Code);
|
||||
|
||||
// Merge text for better translation and save info enough to split again later
|
||||
mergeResult = MergeMultipleLines(tempSubtitle, index, autoTranslator.MaxCharacters, noSentenceEndingSource, noSentenceEndingTarget);
|
||||
mergeCount = mergeResult.ParagraphCount;
|
||||
text = mergeResult.Text;
|
||||
|
||||
//TODO: handle mergeResult.Error !!!
|
||||
|
||||
|
||||
if (mergeCount == 0)
|
||||
var maxChars = autoTranslator.MaxCharacters;
|
||||
if (MergeSplitProblems)
|
||||
{
|
||||
if (MergeWithThreeNext(sourceSubtitle, index, source.Code))
|
||||
MergeSplitProblems = false;
|
||||
if (maxChars > 500)
|
||||
{
|
||||
mergeCount = 3;
|
||||
allItalic = HasAllLinesTag(sourceSubtitle, index, mergeCount, "i");
|
||||
allBold = HasAllLinesTag(sourceSubtitle, index, mergeCount, "b");
|
||||
text = MergeLines(sourceSubtitle, index, mergeCount, allItalic, allBold);
|
||||
}
|
||||
else if (MergeWithTwoNext(sourceSubtitle, index, source.Code))
|
||||
{
|
||||
mergeCount = 2;
|
||||
allItalic = HasAllLinesTag(sourceSubtitle, index, mergeCount, "i");
|
||||
allBold = HasAllLinesTag(sourceSubtitle, index, mergeCount, "b");
|
||||
text = MergeLines(sourceSubtitle, index, mergeCount, allItalic, allBold);
|
||||
}
|
||||
else if (MergeWithNext(sourceSubtitle, index, source.Code))
|
||||
{
|
||||
mergeCount = 1;
|
||||
allItalic = HasAllLinesTag(sourceSubtitle, index, mergeCount, "i");
|
||||
allBold = HasAllLinesTag(sourceSubtitle, index, mergeCount, "b");
|
||||
text = MergeLines(sourceSubtitle, index, mergeCount, allItalic, allBold);
|
||||
maxChars = maxChars / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// just take next sentence too
|
||||
var next = sourceSubtitle.GetParagraphOrDefault(index + 1);
|
||||
if (mergeCount == 0 && MergeWithNextOneLineEnding(sourceSubtitle, index, source.Code, out char splitChar))
|
||||
MergeResult mergeResult = MergeMultipleLines(tempSubtitle, index, maxChars, noSentenceEndingSource, noSentenceEndingTarget);
|
||||
var mergeCount = mergeResult.ParagraphCount;
|
||||
var text = mergeResult.Text;
|
||||
|
||||
if (mergeResult.HasError)
|
||||
{
|
||||
splitAtChar = splitChar;
|
||||
mergeCount = 1;
|
||||
allItalic = HasAllLinesTag(sourceSubtitle, index, mergeCount, "i");
|
||||
allBold = HasAllLinesTag(sourceSubtitle, index, mergeCount, "b");
|
||||
text = Utilities.UnbreakLine(p.Text) + Environment.NewLine + Utilities.UnbreakLine(next.Text);
|
||||
MergeSplitProblems = true;
|
||||
|
||||
if (!noSentenceEndingSource)
|
||||
{
|
||||
noSentenceEndingSource = true;
|
||||
mergeResult = MergeMultipleLines(tempSubtitle, index, maxChars, noSentenceEndingSource, noSentenceEndingTarget);
|
||||
mergeCount = mergeResult.ParagraphCount;
|
||||
text = mergeResult.Text;
|
||||
}
|
||||
|
||||
if (mergeResult.HasError)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
var linesTranslate = 0;
|
||||
if (mergeResult != null)
|
||||
{
|
||||
var mergedTranslation = await autoTranslator.Translate(text, source.Code, target.Code);
|
||||
var splitResult = SplitMultipleLines(mergeResult, mergedTranslation, target.Code);
|
||||
if (splitResult.Count == mergeCount)
|
||||
if (splitResult.Count == mergeCount && HasSameEmptyLines(splitResult, tempSubtitle, index))
|
||||
{
|
||||
// Split by line ending chars
|
||||
|
||||
var idx = 0;
|
||||
foreach (var line in splitResult)
|
||||
{
|
||||
@ -99,55 +81,93 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
|
||||
return linesTranslate;
|
||||
}
|
||||
|
||||
var translatedLines = mergedTranslation.SplitToLines();
|
||||
if (translatedLines.Count == mergeResult.Text.SplitToLines().Count)
|
||||
{
|
||||
// Split per number of lines
|
||||
|
||||
var newSub = new Subtitle();
|
||||
for (var i = 0; i < mergeResult.ParagraphCount; i++)
|
||||
{
|
||||
newSub.Paragraphs.Add(new Paragraph());
|
||||
}
|
||||
|
||||
var translatedLinesIdx = 0;
|
||||
var paragraphIdx = 0;
|
||||
foreach (var mergeItem in mergeResult.MergeResultItems)
|
||||
{
|
||||
var numberOfParagraphs = mergeItem.EndIndex - mergeItem.StartIndex + 1;
|
||||
var numberOfLines = mergeItem.Text.SplitToLines().Count;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
for (var j = 0; j < numberOfLines && translatedLinesIdx < translatedLines.Count; j++)
|
||||
{
|
||||
sb.AppendLine(translatedLines[translatedLinesIdx]);
|
||||
translatedLinesIdx++;
|
||||
}
|
||||
var translatedText = sb.ToString().Trim();
|
||||
|
||||
var arr = TextSplit.SplitMulti(translatedText, numberOfParagraphs, target.TwoLetterIsoLanguageName);
|
||||
for (var i = 0; i < arr.Count && paragraphIdx < newSub.Paragraphs.Count; i++)
|
||||
{
|
||||
newSub.Paragraphs[paragraphIdx].Text = Utilities.AutoBreakLine(arr[i], Configuration.Settings.General.SubtitleLineMaximumLength * 2, 0, target.TwoLetterIsoLanguageName);
|
||||
paragraphIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
if (paragraphIdx == mergeCount && HasSameEmptyLines(newSub, sourceSubtitle, index))
|
||||
{
|
||||
var idx = 0;
|
||||
foreach (var p in newSub.Paragraphs)
|
||||
{
|
||||
var reformattedText = formattings[idx].ReAddFormatting(p.Text);
|
||||
targetSubtitle.Paragraphs[index].Text = reformattedText;
|
||||
index++;
|
||||
linesTranslate++;
|
||||
idx++;
|
||||
}
|
||||
|
||||
return linesTranslate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mergeCount > 0)
|
||||
{
|
||||
var mergedTranslation = await autoTranslator.Translate(text, source.Code, target.Code);
|
||||
|
||||
List<string> result;
|
||||
|
||||
if (splitAtChar != null && mergeCount == 1)
|
||||
{
|
||||
result = SplitResultAtSplitChar(mergedTranslation, splitAtChar.Value, target.Code);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = SplitResult(mergedTranslation.SplitToLines(), mergeCount, source.Code);
|
||||
}
|
||||
|
||||
if (allItalic)
|
||||
{
|
||||
for (var k = 0; k < result.Count; k++)
|
||||
{
|
||||
result[k] = "<i>" + result[k] + "</i>";
|
||||
}
|
||||
}
|
||||
|
||||
if (allBold)
|
||||
{
|
||||
for (var k = 0; k < result.Count; k++)
|
||||
{
|
||||
result[k] = "<b>" + result[k] + "</b>";
|
||||
}
|
||||
}
|
||||
|
||||
if (result.Count == mergeCount + 1 && result.All(t => !string.IsNullOrEmpty(t)))
|
||||
{
|
||||
foreach (var line in result)
|
||||
{
|
||||
targetSubtitle.Paragraphs[index].Text = line;
|
||||
index++;
|
||||
linesTranslate++;
|
||||
}
|
||||
|
||||
return linesTranslate;
|
||||
}
|
||||
}
|
||||
MergeSplitProblems = true;
|
||||
|
||||
return linesTranslate;
|
||||
}
|
||||
|
||||
private static bool HasSameEmptyLines(Subtitle newSub, Subtitle sourceSubtitle, int index)
|
||||
{
|
||||
for (var i = 0; i < newSub.Paragraphs.Count; i++)
|
||||
{
|
||||
var inputBlank = string.IsNullOrWhiteSpace(sourceSubtitle.Paragraphs[i + index].Text);
|
||||
var outputBlank = string.IsNullOrWhiteSpace(newSub.Paragraphs[i].Text);
|
||||
if (inputBlank || outputBlank && (inputBlank != outputBlank))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool HasSameEmptyLines(List<string> splitResult, Subtitle tempSubtitle, int index)
|
||||
{
|
||||
for (var i = 0; i < splitResult.Count; i++)
|
||||
{
|
||||
var inputBlank = string.IsNullOrWhiteSpace(tempSubtitle.Paragraphs[i + index].Text);
|
||||
var outputBlank = string.IsNullOrWhiteSpace(splitResult[i]);
|
||||
if (inputBlank || outputBlank && (inputBlank != outputBlank))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static List<Formatting> HandleFormatting(Subtitle sourceSubtitle, int index, string sourceLanguage)
|
||||
{
|
||||
var formattings = new List<Formatting>();
|
||||
@ -164,31 +184,6 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
return formattings;
|
||||
}
|
||||
|
||||
public class MergeResultItem
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public int StartIndex { get; set; }
|
||||
public int EndIndex { get; set; }
|
||||
public bool AllItalic { get; set; }
|
||||
public bool AllBold { get; set; }
|
||||
public bool Continious { get; set; }
|
||||
public char EndChar { get; set; }
|
||||
public int EndCharOccurences { get; set; }
|
||||
public bool IsEmpty { get; set; }
|
||||
public bool HasError { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class MergeResult
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public int ParagraphCount { get; set; }
|
||||
public List<MergeResultItem> MergeResultItems { get; set; }
|
||||
public bool HasError { get; set; }
|
||||
public bool NoSentenceEndingSource { get; set; }
|
||||
public bool NoSentenceEndingTarget { get; set; }
|
||||
}
|
||||
|
||||
public static MergeResult MergeMultipleLines(Subtitle sourceSubtitle, int index, int maxTextSize, bool noSentenceEndingSource, bool noSentenceEndingTarget)
|
||||
{
|
||||
var result = new MergeResult
|
||||
@ -201,11 +196,14 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
var item = new MergeResultItem();
|
||||
item.StartIndex = index;
|
||||
item.EndIndex = index;
|
||||
item.Text = string.Empty;
|
||||
|
||||
result.Text = sourceSubtitle.Paragraphs[index].Text;
|
||||
item.Text = sourceSubtitle.Paragraphs[index].Text;
|
||||
if (string.IsNullOrWhiteSpace(result.Text))
|
||||
{
|
||||
item.IsEmpty = true;
|
||||
item.Text = string.Empty;
|
||||
result.MergeResultItems.Add(item);
|
||||
item = null;
|
||||
result.Text = string.Empty;
|
||||
@ -225,15 +223,24 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
|
||||
if (noSentenceEndingSource)
|
||||
{
|
||||
result.Text += Environment.NewLine + "." + Environment.NewLine + p.Text;
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
item.TextIndexEnd = result.Text.Length;
|
||||
}
|
||||
|
||||
result.Text += Environment.NewLine + "." + Environment.NewLine + p.Text;
|
||||
item.Text += Environment.NewLine + "." + Environment.NewLine + p.Text;
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
item.TextIndexStart = result.Text.Length;
|
||||
item.StartIndex = i - 1;
|
||||
item.EndIndex = i - 1;
|
||||
result.MergeResultItems.Add(item);
|
||||
|
||||
textBuild = new StringBuilder();
|
||||
item = new MergeResultItem { StartIndex = i };
|
||||
item = new MergeResultItem { StartIndex = i, Text = string.Empty };
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(p.Text))
|
||||
@ -241,6 +248,8 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
var endChar = result.Text[result.Text.Length - 1];
|
||||
if (item != null)
|
||||
{
|
||||
item.TextIndexStart = result.Text.Length;
|
||||
item.TextIndexEnd = result.Text.Length;
|
||||
item.EndChar = endChar;
|
||||
var endCharOccurences = Utilities.CountTagInText(textBuild.ToString(), endChar);
|
||||
item.EndCharOccurences = endCharOccurences;
|
||||
@ -252,7 +261,10 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
{
|
||||
StartIndex = index,
|
||||
EndIndex = index,
|
||||
IsEmpty = true
|
||||
IsEmpty = true,
|
||||
TextIndexStart = result.Text.Length,
|
||||
TextIndexEnd = result.Text.Length,
|
||||
Text = string.Empty,
|
||||
});
|
||||
|
||||
item = null;
|
||||
@ -266,6 +278,7 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
item.TextIndexEnd = result.Text.Length;
|
||||
result.MergeResultItems.Add(item);
|
||||
textBuild = new StringBuilder();
|
||||
}
|
||||
@ -279,6 +292,7 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
item.EndChar = endChar;
|
||||
var endCharOccurences = Utilities.CountTagInText(textBuild.ToString(), endChar);
|
||||
item.EndCharOccurences = endCharOccurences;
|
||||
item.TextIndexEnd = result.Text.Length;
|
||||
result.MergeResultItems.Add(item);
|
||||
textBuild = new StringBuilder();
|
||||
}
|
||||
@ -288,13 +302,14 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
|
||||
result.Text += Environment.NewLine + p.Text;
|
||||
|
||||
item = new MergeResultItem { StartIndex = i };
|
||||
item = new MergeResultItem { StartIndex = i, TextIndexStart = result.Text.Length, Text = p.Text };
|
||||
}
|
||||
else if (item != null && (item.Continious || item.StartIndex == item.EndIndex) && p.StartTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds < 1000)
|
||||
{
|
||||
textBuild.Append(" ");
|
||||
textBuild.Append(p.Text);
|
||||
result.Text += " " + p.Text;
|
||||
item.Text += " " + p.Text;
|
||||
item.Continious = true;
|
||||
}
|
||||
else
|
||||
@ -306,6 +321,7 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
if (item != null)
|
||||
{
|
||||
item.EndIndex = i;
|
||||
item.TextIndexEnd = result.Text.Length;
|
||||
}
|
||||
|
||||
prev = p;
|
||||
@ -328,13 +344,18 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
result.Text = result.Text.Trim();
|
||||
result.ParagraphCount = result.MergeResultItems.Sum(p => p.EndIndex - p.StartIndex + 1);
|
||||
|
||||
foreach (var i in result.MergeResultItems)
|
||||
{
|
||||
i.Text = i.Text.Trim();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<string> SplitMultipleLines(MergeResult mergeResult, string input, string language)
|
||||
public static List<string> SplitMultipleLines(MergeResult mergeResult, string translatedText, string language)
|
||||
{
|
||||
var lines = new List<string>();
|
||||
var text = input;
|
||||
var text = translatedText;
|
||||
|
||||
if (mergeResult.NoSentenceEndingSource)
|
||||
{
|
||||
@ -371,8 +392,8 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
{
|
||||
var part = GetPartFromItem(text, item);
|
||||
text = text.Remove(0, part.Length).Trim();
|
||||
var lineRAnge = SplitContontinous(part, item, language);
|
||||
lines.AddRange(lineRAnge);
|
||||
var lineRange = SplitContontinous(part, item, language);
|
||||
lines.AddRange(lineRange);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -429,294 +450,18 @@ namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
return TextSplit.SplitMulti(text, count, language);
|
||||
}
|
||||
|
||||
private static bool HasAllLinesTag(Subtitle subtitle, int i, int mergeCount, string tag)
|
||||
private static bool IsNonMergeLanguage(TranslationPair language)
|
||||
{
|
||||
for (var j = i; j < subtitle.Paragraphs.Count && j <= i + mergeCount; j++)
|
||||
{
|
||||
var text = subtitle.Paragraphs[j].Text.Trim();
|
||||
if (!text.StartsWith("<" + tag + ">") && !text.EndsWith("</" + tag + ">"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var code = language.TwoLetterIsoLanguageName ?? language.Code;
|
||||
|
||||
return true;
|
||||
return code.ToLowerInvariant() == "zh" ||
|
||||
code.ToLowerInvariant() == "zh-CN" ||
|
||||
code.ToLowerInvariant() == "zh-TW" ||
|
||||
code.ToLowerInvariant() == "yue_Hant" ||
|
||||
code.ToLowerInvariant() == "zho_Hans" ||
|
||||
code.ToLowerInvariant() == "zho_Hant" ||
|
||||
code.ToLowerInvariant() == "jpn_Jpan" ||
|
||||
code.ToLowerInvariant() == "ja";
|
||||
}
|
||||
|
||||
private static bool MergeWithTwoNext(Subtitle subtitle, int i, string source)
|
||||
{
|
||||
if (i + 2 >= subtitle.Paragraphs.Count || IsNonMergeLanguage(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return MergeWithNext(subtitle, i, source) && MergeWithNext(subtitle, i + 1, source);
|
||||
}
|
||||
|
||||
private static bool MergeWithThreeNext(Subtitle subtitle, int i, string source)
|
||||
{
|
||||
if (i + 3 >= subtitle.Paragraphs.Count || IsNonMergeLanguage(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return MergeWithNext(subtitle, i, source) && MergeWithNext(subtitle, i + 1, source) && MergeWithNext(subtitle, i + 2, source);
|
||||
}
|
||||
|
||||
private static string MergeLines(Subtitle subtitle, int i, int mergeCount, bool italic, bool bold)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for (var j = i; j < subtitle.Paragraphs.Count && j <= i + mergeCount; j++)
|
||||
{
|
||||
var text = subtitle.Paragraphs[j].Text.Trim();
|
||||
sb.AppendLine(RemoveAllLinesTag(text, italic, bold));
|
||||
}
|
||||
|
||||
return Utilities.RemoveLineBreaks(sb.ToString());
|
||||
}
|
||||
|
||||
private static List<string> SplitResultAtSplitChar(string translation, char splitAtChar, string languageCode)
|
||||
{
|
||||
var idx = translation.IndexOf(splitAtChar);
|
||||
if (idx < 0 && idx < translation.Length - 1)
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
var line1 = Utilities.AutoBreakLine(translation.Substring(0, idx + 1).Trim(),
|
||||
Configuration.Settings.General.SubtitleLineMaximumLength,
|
||||
Configuration.Settings.General.MergeLinesShorterThan,
|
||||
languageCode);
|
||||
var line2 = Utilities.AutoBreakLine(translation.Remove(0, idx + 1).Trim(),
|
||||
Configuration.Settings.General.SubtitleLineMaximumLength,
|
||||
Configuration.Settings.General.MergeLinesShorterThan,
|
||||
languageCode);
|
||||
return new List<string> { line1, line2 };
|
||||
}
|
||||
|
||||
private static bool MergeWithNextOneLineEnding(Subtitle subtitle, int index, string sourceCode, out char c)
|
||||
{
|
||||
c = '-';
|
||||
|
||||
if (index + 1 >= subtitle.Paragraphs.Count || IsNonMergeLanguage(sourceCode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MergeWithNext(subtitle, index, sourceCode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var next = subtitle.GetParagraphOrDefault(index + 1);
|
||||
if (next == null || !next.Text.HasSentenceEnding("en"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (subtitle.Paragraphs[index].Text.EndsWith(".") && Utilities.CountTagInText(subtitle.Paragraphs[index].Text, '.') == 1)
|
||||
{
|
||||
c = '.';
|
||||
return true;
|
||||
}
|
||||
|
||||
if (subtitle.Paragraphs[index].Text.EndsWith("?") && Utilities.CountTagInText(subtitle.Paragraphs[index].Text, '?') == 1)
|
||||
{
|
||||
c = '?';
|
||||
return true;
|
||||
}
|
||||
|
||||
if (subtitle.Paragraphs[index].Text.EndsWith("!") && Utilities.CountTagInText(subtitle.Paragraphs[index].Text, '!') == 1)
|
||||
{
|
||||
c = '!';
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool MergeWithNext(Subtitle subtitle, int i, string source)
|
||||
{
|
||||
if (i + 1 >= subtitle.Paragraphs.Count || IsNonMergeLanguage(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var p = subtitle.Paragraphs[i];
|
||||
var text = HtmlUtil.RemoveHtmlTags(p.Text, true).TrimEnd('"');
|
||||
if (text.EndsWith(".", StringComparison.Ordinal) ||
|
||||
text.EndsWith("!", StringComparison.Ordinal) ||
|
||||
text.EndsWith("?", StringComparison.Ordinal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var next = subtitle.Paragraphs[i + 1];
|
||||
return next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds < 500;
|
||||
}
|
||||
|
||||
private static bool IsNonMergeLanguage(string source)
|
||||
{
|
||||
return source.ToLowerInvariant() == "zh" ||
|
||||
source.ToLowerInvariant() == "zh-CN" ||
|
||||
source.ToLowerInvariant() == "zh-TW" ||
|
||||
source.ToLowerInvariant() == "yue_Hant" ||
|
||||
source.ToLowerInvariant() == "zho_Hans" ||
|
||||
source.ToLowerInvariant() == "zho_Hant" ||
|
||||
source.ToLowerInvariant() == "jpn_Jpan" ||
|
||||
source.ToLowerInvariant() == "ja";
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static string RemoveAllLinesTag(string text, bool allItalic, bool allBold)
|
||||
{
|
||||
if (allItalic)
|
||||
{
|
||||
text = text.Replace("<i>", string.Empty);
|
||||
text = text.Replace("</i>", string.Empty);
|
||||
}
|
||||
|
||||
if (allBold)
|
||||
{
|
||||
text = text.Replace("<b>", string.Empty);
|
||||
text = text.Replace("</b>", string.Empty);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
private static List<string> SplitResult(List<string> result, int mergeCount, string language)
|
||||
{
|
||||
if (result.Count != 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (mergeCount == 1)
|
||||
{
|
||||
var arr = Utilities.AutoBreakLine(result[0], 84, 1, language).SplitToLines();
|
||||
if (arr.Count == 1)
|
||||
{
|
||||
arr = Utilities.AutoBreakLine(result[0], 42, 1, language).SplitToLines();
|
||||
}
|
||||
|
||||
if (arr.Count == 1)
|
||||
{
|
||||
arr = Utilities.AutoBreakLine(result[0], 22, 1, language).SplitToLines();
|
||||
}
|
||||
|
||||
if (arr.Count == 2)
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
Utilities.AutoBreakLine(arr[0], 42, language == "zh" ? 0 : 25, language),
|
||||
Utilities.AutoBreakLine(arr[1], 42, language == "zh" ? 0 : 25, language),
|
||||
};
|
||||
}
|
||||
|
||||
if (arr.Count == 1)
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
Utilities.AutoBreakLine(arr[0], 42, language == "zh" ? 0 : 25, language),
|
||||
string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (mergeCount == 2)
|
||||
{
|
||||
var arr = SplitHelper.SplitToXLines(3, result[0], 84).ToArray();
|
||||
|
||||
if (arr.Length == 3)
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
Utilities.AutoBreakLine(arr[0], 42, language == "zh" ? 0 : 25, language),
|
||||
Utilities.AutoBreakLine(arr[1], 42, language == "zh" ? 0 : 25, language),
|
||||
Utilities.AutoBreakLine(arr[2], 42, language == "zh" ? 0 : 25, language),
|
||||
};
|
||||
}
|
||||
|
||||
if (arr.Length == 2)
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
Utilities.AutoBreakLine(arr[0], 42, language == "zh" ? 0 : 25, language),
|
||||
Utilities.AutoBreakLine(arr[1], 42, language == "zh" ? 0 : 25, language),
|
||||
string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
if (arr.Length == 1)
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
Utilities.AutoBreakLine(arr[0], 42, language == "zh" ? 0 : 25, language),
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (mergeCount == 3)
|
||||
{
|
||||
var arr = SplitHelper.SplitToXLines(4, result[0], 84).ToArray();
|
||||
|
||||
if (arr.Length == 4)
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
Utilities.AutoBreakLine(arr[0], 42, language == "zh" ? 0 : 25, language),
|
||||
Utilities.AutoBreakLine(arr[1], 42, language == "zh" ? 0 : 25, language),
|
||||
Utilities.AutoBreakLine(arr[2], 42, language == "zh" ? 0 : 25, language),
|
||||
Utilities.AutoBreakLine(arr[3], 42, language == "zh" ? 0 : 25, language),
|
||||
};
|
||||
}
|
||||
|
||||
if (arr.Length == 3)
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
Utilities.AutoBreakLine(arr[0], 42, language == "zh" ? 0 : 25, language),
|
||||
Utilities.AutoBreakLine(arr[1], 42, language == "zh" ? 0 : 25, language),
|
||||
Utilities.AutoBreakLine(arr[2], 42, language == "zh" ? 0 : 25, language),
|
||||
string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
if (arr.Length == 2)
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
Utilities.AutoBreakLine(arr[0], 42, language == "zh" ? 0 : 25, language),
|
||||
Utilities.AutoBreakLine(arr[1], 42, language == "zh" ? 0 : 25, language),
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
if (arr.Length == 1)
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
Utilities.AutoBreakLine(arr[0], 42, language == "zh" ? 0 : 25, language),
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
17
src/ui/Forms/Translate/MergeResult.cs
Normal file
17
src/ui/Forms/Translate/MergeResult.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
{
|
||||
public static partial class MergeAndSplitHelper
|
||||
{
|
||||
public class MergeResult
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public int ParagraphCount { get; set; }
|
||||
public List<MergeResultItem> MergeResultItems { get; set; }
|
||||
public bool HasError { get; set; }
|
||||
public bool NoSentenceEndingSource { get; set; }
|
||||
public bool NoSentenceEndingTarget { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
21
src/ui/Forms/Translate/MergeResultItem.cs
Normal file
21
src/ui/Forms/Translate/MergeResultItem.cs
Normal file
@ -0,0 +1,21 @@
|
||||
namespace Nikse.SubtitleEdit.Forms.Translate
|
||||
{
|
||||
public static partial class MergeAndSplitHelper
|
||||
{
|
||||
public class MergeResultItem
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public int StartIndex { get; set; }
|
||||
public int EndIndex { get; set; }
|
||||
public bool AllItalic { get; set; }
|
||||
public bool AllBold { get; set; }
|
||||
public bool Continious { get; set; }
|
||||
public char EndChar { get; set; }
|
||||
public int EndCharOccurences { get; set; }
|
||||
public bool IsEmpty { get; set; }
|
||||
public bool HasError { get; set; }
|
||||
public int TextIndexStart { get; set; }
|
||||
public int TextIndexEnd { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
@ -153,6 +153,7 @@ namespace Nikse.SubtitleEdit.Logic
|
||||
public Keys MainAdjustInsertViaEndAutoStart { get; set; }
|
||||
public Keys MainAdjustInsertViaEndAutoStartAndGoToNext { get; set; }
|
||||
public Keys MainAdjustSetEndMinusGapAndStartNextHere { get; set; }
|
||||
public Keys MainAdjustSetEndAndStartOfNextPlusGap { get; set; }
|
||||
public Keys MainAdjustSetStartAutoDurationAndGoToNext { get; set; }
|
||||
public Keys MainAdjustSetEndNextStartAndGoToNext { get; set; }
|
||||
public Keys MainAdjustStartDownEndUpAndGoToNext { get; set; }
|
||||
@ -469,6 +470,7 @@ namespace Nikse.SubtitleEdit.Logic
|
||||
MainAdjustInsertViaEndAutoStart = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainAdjustViaEndAutoStart);
|
||||
MainAdjustInsertViaEndAutoStartAndGoToNext = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainAdjustViaEndAutoStartAndGoToNext);
|
||||
MainAdjustSetEndMinusGapAndStartNextHere = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainAdjustSetEndMinusGapAndStartNextHere);
|
||||
MainAdjustSetEndAndStartOfNextPlusGap = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainAdjustSetEndAndStartOfNextPlusGap);
|
||||
MainAdjustSetStartAutoDurationAndGoToNext = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainAdjustSetStartAutoDurationAndGoToNext);
|
||||
MainAdjustSetEndNextStartAndGoToNext = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainAdjustSetEndNextStartAndGoToNext);
|
||||
MainAdjustStartDownEndUpAndGoToNext = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainAdjustStartDownEndUpAndGoToNext);
|
||||
|
@ -1338,6 +1338,8 @@
|
||||
<DependentUpon>TimedTextStyles.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\Translate\MergeAndSplitHelper.cs" />
|
||||
<Compile Include="Forms\Translate\MergeResult.cs" />
|
||||
<Compile Include="Forms\Translate\MergeResultItem.cs" />
|
||||
<Compile Include="Forms\Translate\SplitHelper.cs" />
|
||||
<Compile Include="Forms\Translate\TranslateBlock.cs">
|
||||
<SubType>Form</SubType>
|
||||
|
Loading…
Reference in New Issue
Block a user