From df4d52ee849ad051ff3ed098ae8e372d547a3b55 Mon Sep 17 00:00:00 2001 From: niksedk Date: Fri, 29 Sep 2023 21:25:46 +0200 Subject: [PATCH] Testing NLLB api Related to #7457 --- src/libse/AutoTranslate/AutoTranslator.cs | 275 ++++++++++++++++ src/libse/AutoTranslate/IAutoTranslator.cs | 15 + src/libse/Http/DownloaderFactory.cs | 1 - src/ui/Forms/Main.Designer.cs | 22 +- src/ui/Forms/Main.cs | 91 +++++ src/ui/Forms/Main.resx | 44 +-- .../Forms/Translate/AutoTranslate.Designer.cs | 279 ++++++++++++++++ src/ui/Forms/Translate/AutoTranslate.cs | 311 ++++++++++++++++++ src/ui/Forms/Translate/AutoTranslate.resx | 120 +++++++ src/ui/SubtitleEdit.csproj | 9 + 10 files changed, 1120 insertions(+), 47 deletions(-) create mode 100644 src/libse/AutoTranslate/AutoTranslator.cs create mode 100644 src/libse/AutoTranslate/IAutoTranslator.cs create mode 100644 src/ui/Forms/Translate/AutoTranslate.Designer.cs create mode 100644 src/ui/Forms/Translate/AutoTranslate.cs create mode 100644 src/ui/Forms/Translate/AutoTranslate.resx diff --git a/src/libse/AutoTranslate/AutoTranslator.cs b/src/libse/AutoTranslate/AutoTranslator.cs new file mode 100644 index 000000000..609bd680c --- /dev/null +++ b/src/libse/AutoTranslate/AutoTranslator.cs @@ -0,0 +1,275 @@ +using Nikse.SubtitleEdit.Core.Http; +using Nikse.SubtitleEdit.Core.SubtitleFormats; +using Nikse.SubtitleEdit.Core.Translate; +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Nikse.SubtitleEdit.Core.Common; +using System.Net.Http.Headers; + +namespace Nikse.SubtitleEdit.Core.AutoTranslate +{ + public class AutoTranslator : IAutoTranslator + { + private IDownloader _httpClient; + private const char SplitChar = '\n'; + + public string Url => "https://winstxnhdw-nllb-api.hf.space/api/v2/"; + + public void Initialize(string url) + { + _httpClient?.Dispose(); + _httpClient = DownloaderFactory.MakeHttpClient(); + _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json"); + _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("accept", "application/json"); + _httpClient.BaseAddress = new Uri(url); + } + + public List GetSupportedSourceLanguages() + { + return ListLanguages(); + } + + public List GetSupportedTargetLanguages() + { + return ListLanguages(); + } + + public async Task Translate(string text, string sourceLanguageCode, string targetLanguageCode) + { + var content = new StringContent("{\n \"text\": \"" + Json.EncodeJsonText(text) + "\",\n \"source\": \"" + sourceLanguageCode+ "\",\n \"target\": \"" + targetLanguageCode + "\"\n}", Encoding.UTF8, "application/json"); + var result = _httpClient.PostAsync("translate", content).Result; + result.EnsureSuccessStatusCode(); + var bytes = await result.Content.ReadAsByteArrayAsync(); + var resultText = Encoding.UTF8.GetString(bytes).Trim(); + + // error messages are returned as json, translated text are just returned as normal utf-8 text + var validator = new SeJsonValidator(); + var isValidJson = validator.ValidateJson(resultText); + if (isValidJson) + { + SeLogger.Error($"{this.GetType().Name} got json back which is probably an error: {resultText}"); + } + + return resultText; + } + + private static List ListLanguages() + { + return new List + { + MakePair("Acehnese (Arabic script)", "ace_Arab"), + MakePair("Acehnese (Latin script) ", "ace_Latn"), + MakePair("Mesopotamian Arabic ", "acm_Arab"), + MakePair("Ta’izzi-Adeni Arabic ", "acq_Arab"), + MakePair("Tunisian Arabic ", "aeb_Arab"), + MakePair("Afrikaans ", "afr_Latn"), + MakePair("South Levantine Arabic ", "ajp_Arab"), + MakePair("Akan ", "aka_Latn"), + MakePair("Amharic ", "amh_Ethi"), + MakePair("North Levantine Arabic ", "apc_Arab"), + MakePair("Modern Standard Arabic ", "arb_Arab"), + MakePair("Modern Standard Arabic (Romanized) ", "arb_Latn"), + MakePair("Najdi Arabic ", "ars_Arab"), + MakePair("Moroccan Arabic ", "ary_Arab"), + MakePair("Egyptian Arabic ", "arz_Arab"), + MakePair("Assamese ", "asm_Beng"), + MakePair("Asturian ", "ast_Latn"), + MakePair("Awadhi ", "awa_Deva"), + MakePair("Central Aymara ", "ayr_Latn"), + MakePair("South Azerbaijani ", "azb_Arab"), + MakePair("North Azerbaijani ", "azj_Latn"), + MakePair("Bashkir ", "bak_Cyrl"), + MakePair("Bambara ", "bam_Latn"), + MakePair("Balinese ", "ban_Latn"), + MakePair("Belarusian ", "bel_Cyrl"), + MakePair("Bemba ", "bem_Latn"), + MakePair("Bengali ", "ben_Beng"), + MakePair("Bhojpuri ", "bho_Deva"), + MakePair("Banjar (Arabic script) ", "bjn_Arab"), + MakePair("Banjar (Latin script) ", "bjn_Latn"), + MakePair("Standard Tibetan ", "bod_Tibt"), + MakePair("Bosnian ", "bos_Latn"), + MakePair("Buginese ", "bug_Latn"), + MakePair("Bulgarian ", "bul_Cyrl"), + MakePair("Catalan ", "cat_Latn"), + MakePair("Cebuano ", "ceb_Latn"), + MakePair("Czech ", "ces_Latn"), + MakePair("Chokwe ", "cjk_Latn"), + MakePair("Central Kurdish ", "ckb_Arab"), + MakePair("Crimean Tatar ", "crh_Latn"), + MakePair("Welsh ", "cym_Latn"), + MakePair("Danish ", "dan_Latn"), + MakePair("German ", "deu_Latn"), + MakePair("Southwestern Dinka ", "dik_Latn"), + MakePair("Dyula ", "dyu_Latn"), + MakePair("Dzongkha ", "dzo_Tibt"), + MakePair("Greek ", "ell_Grek"), + MakePair("English ", "eng_Latn"), + MakePair("Esperanto ", "epo_Latn"), + MakePair("Estonian ", "est_Latn"), + MakePair("Basque ", "eus_Latn"), + MakePair("Ewe ", "ewe_Latn"), + MakePair("Faroese ", "fao_Latn"), + MakePair("Fijian ", "fij_Latn"), + MakePair("Finnish ", "fin_Latn"), + MakePair("Fon ", "fon_Latn"), + MakePair("French ", "fra_Latn"), + MakePair("Friulian ", "fur_Latn"), + MakePair("Nigerian Fulfulde ", "fuv_Latn"), + MakePair("Scottish Gaelic ", "gla_Latn"), + MakePair("Irish ", "gle_Latn"), + MakePair("Galician ", "glg_Latn"), + MakePair("Guarani ", "grn_Latn"), + MakePair("Gujarati ", "guj_Gujr"), + MakePair("Haitian Creole ", "hat_Latn"), + MakePair("Hausa ", "hau_Latn"), + MakePair("Hebrew ", "heb_Hebr"), + MakePair("Hindi ", "hin_Deva"), + MakePair("Chhattisgarhi ", "hne_Deva"), + MakePair("Croatian ", "hrv_Latn"), + MakePair("Hungarian ", "hun_Latn"), + MakePair("Armenian ", "hye_Armn"), + MakePair("Igbo ", "ibo_Latn"), + MakePair("Ilocano ", "ilo_Latn"), + MakePair("Indonesian ", "ind_Latn"), + MakePair("Icelandic ", "isl_Latn"), + MakePair("Italian ", "ita_Latn"), + MakePair("Javanese ", "jav_Latn"), + MakePair("Japanese ", "jpn_Jpan"), + MakePair("Kabyle ", "kab_Latn"), + MakePair("Jingpho ", "kac_Latn"), + MakePair("Kamba ", "kam_Latn"), + MakePair("Kannada ", "kan_Knda"), + MakePair("Kashmiri (Arabic script) ", "kas_Arab"), + MakePair("Kashmiri (Devanagari script) ", "kas_Deva"), + MakePair("Georgian ", "kat_Geor"), + MakePair("Central Kanuri (Arabic script) ", "knc_Arab"), + MakePair("Central Kanuri (Latin script) ", "knc_Latn"), + MakePair("Kazakh ", "kaz_Cyrl"), + MakePair("Kabiyè ", "kbp_Latn"), + MakePair("Kabuverdianu ", "kea_Latn"), + MakePair("Khmer ", "khm_Khmr"), + MakePair("Kikuyu ", "kik_Latn"), + MakePair("Kinyarwanda ", "kin_Latn"), + MakePair("Kyrgyz ", "kir_Cyrl"), + MakePair("Kimbundu ", "kmb_Latn"), + MakePair("Northern Kurdish ", "kmr_Latn"), + MakePair("Kikongo ", "kon_Latn"), + MakePair("Korean ", "kor_Hang"), + MakePair("Lao ", "lao_Laoo"), + MakePair("Ligurian ", "lij_Latn"), + MakePair("Limburgish ", "lim_Latn"), + MakePair("Lingala ", "lin_Latn"), + MakePair("Lithuanian ", "lit_Latn"), + MakePair("Lombard ", "lmo_Latn"), + MakePair("Latgalian ", "ltg_Latn"), + MakePair("Luxembourgish ", "ltz_Latn"), + MakePair("Luba-Kasai ", "lua_Latn"), + MakePair("Ganda ", "lug_Latn"), + MakePair("Luo ", "luo_Latn"), + MakePair("Mizo ", "lus_Latn"), + MakePair("Standard Latvian ", "lvs_Latn"), + MakePair("Magahi ", "mag_Deva"), + MakePair("Maithili ", "mai_Deva"), + MakePair("Malayalam ", "mal_Mlym"), + MakePair("Marathi ", "mar_Deva"), + MakePair("Minangkabau (Arabic script) ", "min_Arab"), + MakePair("Minangkabau (Latin script) ", "min_Latn"), + MakePair("Macedonian ", "mkd_Cyrl"), + MakePair("Plateau Malagasy ", "plt_Latn"), + MakePair("Maltese ", "mlt_Latn"), + MakePair("Meitei (Bengali script) ", "mni_Beng"), + MakePair("Halh Mongolian ", "khk_Cyrl"), + MakePair("Mossi ", "mos_Latn"), + MakePair("Maori ", "mri_Latn"), + MakePair("Burmese ", "mya_Mymr"), + MakePair("Dutch ", "nld_Latn"), + MakePair("Norwegian Nynorsk ", "nno_Latn"), + MakePair("Norwegian Bokmål ", "nob_Latn"), + MakePair("Nepali ", "npi_Deva"), + MakePair("Northern Sotho ", "nso_Latn"), + MakePair("Nuer ", "nus_Latn"), + MakePair("Nyanja ", "nya_Latn"), + MakePair("Occitan ", "oci_Latn"), + MakePair("West Central Oromo ", "gaz_Latn"), + MakePair("Odia ", "ory_Orya"), + MakePair("Pangasinan ", "pag_Latn"), + MakePair("Eastern Panjabi ", "pan_Guru"), + MakePair("Papiamento ", "pap_Latn"), + MakePair("Western Persian ", "pes_Arab"), + MakePair("Polish ", "pol_Latn"), + MakePair("Portuguese ", "por_Latn"), + MakePair("Dari ", "prs_Arab"), + MakePair("Southern Pashto ", "pbt_Arab"), + MakePair("Ayacucho Quechua ", "quy_Latn"), + MakePair("Romanian ", "ron_Latn"), + MakePair("Rundi ", "run_Latn"), + MakePair("Russian ", "rus_Cyrl"), + MakePair("Sango ", "sag_Latn"), + MakePair("Sanskrit ", "san_Deva"), + MakePair("Santali ", "sat_Olck"), + MakePair("Sicilian ", "scn_Latn"), + MakePair("Shan ", "shn_Mymr"), + MakePair("Sinhala ", "sin_Sinh"), + MakePair("Slovak ", "slk_Latn"), + MakePair("Slovenian ", "slv_Latn"), + MakePair("Samoan ", "smo_Latn"), + MakePair("Shona ", "sna_Latn"), + MakePair("Sindhi ", "snd_Arab"), + MakePair("Somali ", "som_Latn"), + MakePair("Southern Sotho ", "sot_Latn"), + MakePair("Spanish ", "spa_Latn"), + MakePair("Tosk Albanian ", "als_Latn"), + MakePair("Sardinian ", "srd_Latn"), + MakePair("Serbian ", "srp_Cyrl"), + MakePair("Swati ", "ssw_Latn"), + MakePair("Sundanese ", "sun_Latn"), + MakePair("Swedish ", "swe_Latn"), + MakePair("Swahili ", "swh_Latn"), + MakePair("Silesian ", "szl_Latn"), + MakePair("Tamil ", "tam_Taml"), + MakePair("Tatar ", "tat_Cyrl"), + MakePair("Telugu ", "tel_Telu"), + MakePair("Tajik ", "tgk_Cyrl"), + MakePair("Tagalog ", "tgl_Latn"), + MakePair("Thai ", "tha_Thai"), + MakePair("Tigrinya ", "tir_Ethi"), + MakePair("Tamasheq (Latin script) ", "taq_Latn"), + MakePair("Tamasheq (Tifinagh script) ", "taq_Tfng"), + MakePair("Tok Pisin ", "tpi_Latn"), + MakePair("Tswana ", "tsn_Latn"), + MakePair("Tsonga ", "tso_Latn"), + MakePair("Turkmen ", "tuk_Latn"), + MakePair("Tumbuka ", "tum_Latn"), + MakePair("Turkish ", "tur_Latn"), + MakePair("Twi ", "twi_Latn"), + MakePair("Central Atlas Tamazight ", "tzm_Tfng"), + MakePair("Uyghur ", "uig_Arab"), + MakePair("Ukrainian ", "ukr_Cyrl"), + MakePair("Umbundu ", "umb_Latn"), + MakePair("Urdu ", "urd_Arab"), + MakePair("Northern Uzbek ", "uzn_Latn"), + MakePair("Venetian ", "vec_Latn"), + MakePair("Vietnamese ", "vie_Latn"), + MakePair("Waray ", "war_Latn"), + MakePair("Wolof ", "wol_Latn"), + MakePair("Xhosa ", "xho_Latn"), + MakePair("Eastern Yiddish ", "ydd_Hebr"), + MakePair("Yoruba ", "yor_Latn"), + MakePair("Yue Chinese ", "yue_Hant"), + MakePair("Chinese (Simplified) ", "zho_Hans"), + MakePair("Chinese (Traditional) ", "zho_Hant"), + MakePair("Standard Malay ", "zsm_Latn"), + MakePair("Zulu ", "zul_Latn"), + }; + } + + private static TranslationPair MakePair(string name, string code) + { + return new TranslationPair(name, code); + } + } +} diff --git a/src/libse/AutoTranslate/IAutoTranslator.cs b/src/libse/AutoTranslate/IAutoTranslator.cs new file mode 100644 index 000000000..8707e3130 --- /dev/null +++ b/src/libse/AutoTranslate/IAutoTranslator.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Nikse.SubtitleEdit.Core.Translate; + +namespace Nikse.SubtitleEdit.Core.AutoTranslate +{ + public interface IAutoTranslator + { + void Initialize(string url); + string Url { get; } + List GetSupportedSourceLanguages(); + List GetSupportedTargetLanguages(); + Task Translate(string text, string sourceLanguageCode, string targetLanguageCode); + } +} \ No newline at end of file diff --git a/src/libse/Http/DownloaderFactory.cs b/src/libse/Http/DownloaderFactory.cs index 13379f003..64a22c37c 100644 --- a/src/libse/Http/DownloaderFactory.cs +++ b/src/libse/Http/DownloaderFactory.cs @@ -10,7 +10,6 @@ namespace Nikse.SubtitleEdit.Core.Http public static IDownloader MakeHttpClient() { var httpClient = new HttpClient(GetHttpClientHandler(Configuration.Settings.Proxy)); - if (Configuration.Settings.General.UseLegacyDownloader) { return new LegacyDownloader(httpClient); diff --git a/src/ui/Forms/Main.Designer.cs b/src/ui/Forms/Main.Designer.cs index 7dd2ca8be..abd85533d 100644 --- a/src/ui/Forms/Main.Designer.cs +++ b/src/ui/Forms/Main.Designer.cs @@ -578,6 +578,7 @@ namespace Nikse.SubtitleEdit.Forms this.timerOriginalTextUndo = new System.Windows.Forms.Timer(this.components); this.contextMenuStripShowVideoControls = new System.Windows.Forms.ContextMenuStrip(this.components); this.toolStripMenuItemShowVideoControls = new System.Windows.Forms.ToolStripMenuItem(); + this.autotranslateNLLBToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.statusStrip1.SuspendLayout(); this.toolStrip1.SuspendLayout(); this.menuStrip1.SuspendLayout(); @@ -993,15 +994,14 @@ namespace Nikse.SubtitleEdit.Forms this.toolStripButtonSourceView.Text = "Toggle list/source view"; this.toolStripButtonSourceView.Click += new System.EventHandler(this.ToolStripButtonSourceViewClick); // - // toolStripButtonToggleWaveform + // toolStripButtonLayout // this.toolStripButtonLayout.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.toolStripButtonLayout.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F); - this.toolStripButtonLayout.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButtonToggleWaveform.Image"))); this.toolStripButtonLayout.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.toolStripButtonLayout.ImageTransparentColor = System.Drawing.Color.Magenta; this.toolStripButtonLayout.Name = "toolStripButtonLayout"; - this.toolStripButtonLayout.Size = new System.Drawing.Size(36, 37); + this.toolStripButtonLayout.Size = new System.Drawing.Size(23, 37); this.toolStripButtonLayout.Text = "Show/hide waveform"; this.toolStripButtonLayout.Click += new System.EventHandler(this.ToolStripButtonLayoutChooseClick); // @@ -1013,7 +1013,7 @@ namespace Nikse.SubtitleEdit.Forms // toolStripLabelSubtitleFormat // this.toolStripLabelSubtitleFormat.Name = "toolStripLabelSubtitleFormat"; - this.toolStripLabelSubtitleFormat.Size = new System.Drawing.Size(86, 15); + this.toolStripLabelSubtitleFormat.Size = new System.Drawing.Size(86, 37); this.toolStripLabelSubtitleFormat.Text = "Subtitle format"; // // comboBoxSubtitleFormats @@ -2415,6 +2415,11 @@ namespace Nikse.SubtitleEdit.Forms this.showhideWaveformToolStripMenuItem.Text = "Show/hide waveform"; this.showhideWaveformToolStripMenuItem.Click += new System.EventHandler(this.ShowhideWaveformToolStripMenuItemClick); // + // showhideVideoToolStripMenuItem + // + this.showhideVideoToolStripMenuItem.Name = "showhideVideoToolStripMenuItem"; + this.showhideVideoToolStripMenuItem.Size = new System.Drawing.Size(295, 22); + // // toolStripSeparator19 // this.toolStripSeparator19.Name = "toolStripSeparator19"; @@ -2500,6 +2505,7 @@ namespace Nikse.SubtitleEdit.Forms // this.toolStripMenuItemAutoTranslate.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.translateToolStripMenuItem, + this.autotranslateNLLBToolStripMenuItem, this.autotranslateViaCopypasteToolStripMenuItem, this.toolStripSeparator26, this.mergeSentencesToolStripMenuItem, @@ -5853,6 +5859,13 @@ namespace Nikse.SubtitleEdit.Forms this.toolStripMenuItemShowVideoControls.Text = "Show video controls"; this.toolStripMenuItemShowVideoControls.Click += new System.EventHandler(this.ToolStripMenuItemShowVideoControlsClick); // + // autotranslateNLLBToolStripMenuItem + // + this.autotranslateNLLBToolStripMenuItem.Name = "autotranslateNLLBToolStripMenuItem"; + this.autotranslateNLLBToolStripMenuItem.Size = new System.Drawing.Size(238, 22); + this.autotranslateNLLBToolStripMenuItem.Text = "Auto-translate (NLLB)..."; + this.autotranslateNLLBToolStripMenuItem.Click += new System.EventHandler(this.autotranslateNLLBToolStripMenuItem_Click); + // // Main // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -6470,5 +6483,6 @@ namespace Nikse.SubtitleEdit.Forms private System.Windows.Forms.ToolStripMenuItem beautifyTimeCodesOfSelectedLinesToolStripMenuItem; private NikseLabel labelAutoDuration; private System.Windows.Forms.ToolStripButton toolStripSplitButtonPlayRate; + private System.Windows.Forms.ToolStripMenuItem autotranslateNLLBToolStripMenuItem; } } \ No newline at end of file diff --git a/src/ui/Forms/Main.cs b/src/ui/Forms/Main.cs index 8756458be..54b8845c0 100644 --- a/src/ui/Forms/Main.cs +++ b/src/ui/Forms/Main.cs @@ -35823,5 +35823,96 @@ namespace Nikse.SubtitleEdit.Forms Configuration.Settings.General.Undocked = false; } + + private void autotranslateNLLBToolStripMenuItem_Click(object sender, EventArgs e) + { + var onlySelectedLines = false; + MakeAutoTranslate(onlySelectedLines); + } + + private void MakeAutoTranslate(bool onlySelectedLines) + { + if (!IsSubtitleLoaded) + { + DisplaySubtitleNotLoadedMessage(); + return; + } + + bool isOriginalVisible = SubtitleListview1.IsOriginalTextColumnVisible; + ReloadFromSourceView(); + string title = string.Empty; + using (var autoTranslate = new AutoTranslate(_subtitle, null, title, GetCurrentEncoding(), GetCurrentSubtitleFormat())) + { + SaveSubtitleListviewIndices(); + + if (autoTranslate.ShowDialog(this) == DialogResult.OK) + { + _subtitleListViewIndex = -1; + string oldFileName = _fileName; + MakeHistoryForUndo(_language.BeforeGoogleTranslation); + if (onlySelectedLines) + { + // we only update selected lines + int i = 0; + foreach (int index in SubtitleListview1.SelectedIndices) + { + _subtitle.Paragraphs[index].Text = autoTranslate.TranslatedSubtitle.Paragraphs[i].Text; + i++; + } + + ShowStatus(_language.SelectedLinesTranslated); + } + else + { + ShowSubtitleTimer.Stop(); + var oldHash = _changeSubtitleHash; + _subtitleOriginal = new Subtitle(_subtitle); + _subtitleOriginalFileName = _fileName; + _fileName = null; + _subtitle.Paragraphs.Clear(); + foreach (var p in autoTranslate.TranslatedSubtitle.Paragraphs) + { + _subtitle.Paragraphs.Add(new Paragraph(p)); + } + + SetAssaResolution(_subtitleOriginal); + ShowStatus(_language.SubtitleTranslated); + _changeOriginalSubtitleHash = oldHash; + _changeSubtitleHash = -1; + ShowSubtitleTimer.Start(); + } + + ShowSource(); + + if (!onlySelectedLines) + { + SubtitleListview1.ShowOriginalTextColumn(_languageGeneral.OriginalText); + SubtitleListview1.AutoSizeAllColumns(this); + var oldHash = _changeOriginalSubtitleHash; + SetupOriginalEdit(); + _changeOriginalSubtitleHash = oldHash; + } + + SubtitleListview1.Fill(_subtitle, _subtitleOriginal); + if (!onlySelectedLines) + { + ResetHistory(); + //TODO: _fileName = autoTranslate.GetFileNameWithTargetLanguage(oldFileName, _videoFileName, _subtitleOriginal, GetCurrentSubtitleFormat()); + _converted = true; + } + + RestoreSubtitleListviewIndices(); + + SetTitle(); + SetEncoding(Encoding.UTF8); + if (!isOriginalVisible) + { + toolStripMenuItemShowOriginalInPreview.Checked = false; + Configuration.Settings.General.ShowOriginalAsPreviewIfAvailable = false; + audioVisualizer.Invalidate(); + } + } + } + } } } \ No newline at end of file diff --git a/src/ui/Forms/Main.resx b/src/ui/Forms/Main.resx index f9ff45b00..65ad97d4b 100644 --- a/src/ui/Forms/Main.resx +++ b/src/ui/Forms/Main.resx @@ -646,46 +646,6 @@ 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 @@ -773,9 +733,9 @@ iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACJSURBVEhLYxjioPT6M4aKawVQHvEApAekFyfIuf6bofx6 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACJSURBVEhLYxjioPT6M4aKawVQHvEApAekFyfIvv6bofx6 A5RHPADpAenFCbAZXHk1ACi2nqHi6n44BokhA5INrrpiwFBx/T9Q7DxYHILPg8VAcjBAssEgNsgQdACx - DFXdqMFgMGowlDdqMCUG0yxLgwCowEEugEAFEsWFELGAoME0K+gHP2BgAABIMRkWA2B4ngAAAABJRU5E + DFXdqMFgMGowlDdqMCUG0yxLgwCowEEugEAFEsWFELGAoME0K+gHP2BgAADNshj2IuGeLgAAAABJRU5E rkJggg== diff --git a/src/ui/Forms/Translate/AutoTranslate.Designer.cs b/src/ui/Forms/Translate/AutoTranslate.Designer.cs new file mode 100644 index 000000000..669a5aabb --- /dev/null +++ b/src/ui/Forms/Translate/AutoTranslate.Designer.cs @@ -0,0 +1,279 @@ +namespace Nikse.SubtitleEdit.Forms.Translate +{ + sealed partial class AutoTranslate + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.labelPleaseWait = new System.Windows.Forms.Label(); + this.buttonCancel = new System.Windows.Forms.Button(); + this.buttonOK = new System.Windows.Forms.Button(); + this.buttonTranslate = new System.Windows.Forms.Button(); + this.labelTarget = new System.Windows.Forms.Label(); + this.labelSource = new System.Windows.Forms.Label(); + this.labelUrl = new System.Windows.Forms.Label(); + this.nikseComboBoxUrl = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.comboBoxSource = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.comboBoxTarget = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.subtitleListViewTarget = new Nikse.SubtitleEdit.Controls.SubtitleListView(); + this.subtitleListViewSource = new Nikse.SubtitleEdit.Controls.SubtitleListView(); + this.SuspendLayout(); + // + // progressBar1 + // + this.progressBar1.Location = new System.Drawing.Point(699, 27); + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = new System.Drawing.Size(192, 16); + this.progressBar1.TabIndex = 100; + // + // labelPleaseWait + // + this.labelPleaseWait.AutoSize = true; + this.labelPleaseWait.Location = new System.Drawing.Point(697, 11); + this.labelPleaseWait.Name = "labelPleaseWait"; + this.labelPleaseWait.Size = new System.Drawing.Size(171, 13); + this.labelPleaseWait.TabIndex = 99; + this.labelPleaseWait.Text = "Please wait... this may take a while"; + // + // buttonCancel + // + this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.buttonCancel.Location = new System.Drawing.Point(817, 528); + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(75, 23); + this.buttonCancel.TabIndex = 102; + this.buttonCancel.Text = "C&ancel"; + this.buttonCancel.UseVisualStyleBackColor = true; + // + // buttonOK + // + this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonOK.Location = new System.Drawing.Point(736, 528); + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(75, 23); + this.buttonOK.TabIndex = 101; + this.buttonOK.Text = "&OK"; + this.buttonOK.UseVisualStyleBackColor = true; + // + // buttonTranslate + // + this.buttonTranslate.Location = new System.Drawing.Point(618, 22); + this.buttonTranslate.Name = "buttonTranslate"; + this.buttonTranslate.Size = new System.Drawing.Size(75, 23); + this.buttonTranslate.TabIndex = 96; + this.buttonTranslate.Text = "Translate"; + this.buttonTranslate.UseVisualStyleBackColor = true; + this.buttonTranslate.Click += new System.EventHandler(this.buttonTranslate_Click); + // + // labelTarget + // + this.labelTarget.AutoSize = true; + this.labelTarget.Location = new System.Drawing.Point(462, 27); + this.labelTarget.Name = "labelTarget"; + this.labelTarget.Size = new System.Drawing.Size(23, 13); + this.labelTarget.TabIndex = 104; + this.labelTarget.Text = "To:"; + // + // labelSource + // + this.labelSource.AutoSize = true; + this.labelSource.Location = new System.Drawing.Point(279, 27); + this.labelSource.Name = "labelSource"; + this.labelSource.Size = new System.Drawing.Size(33, 13); + this.labelSource.TabIndex = 103; + this.labelSource.Text = "From:"; + // + // labelUrl + // + this.labelUrl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.labelUrl.AutoSize = true; + this.labelUrl.Location = new System.Drawing.Point(14, 532); + this.labelUrl.Name = "labelUrl"; + this.labelUrl.Size = new System.Drawing.Size(23, 13); + this.labelUrl.TabIndex = 106; + this.labelUrl.Text = "Url:"; + // + // nikseComboBoxUrl + // + this.nikseComboBoxUrl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.nikseComboBoxUrl.BackColor = System.Drawing.SystemColors.Window; + this.nikseComboBoxUrl.BackColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240))))); + this.nikseComboBoxUrl.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(171)))), ((int)(((byte)(173)))), ((int)(((byte)(179))))); + this.nikseComboBoxUrl.BorderColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(120)))), ((int)(((byte)(120))))); + this.nikseComboBoxUrl.ButtonForeColor = System.Drawing.SystemColors.ControlText; + this.nikseComboBoxUrl.ButtonForeColorDown = System.Drawing.Color.Orange; + this.nikseComboBoxUrl.ButtonForeColorOver = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); + this.nikseComboBoxUrl.DropDownHeight = 400; + this.nikseComboBoxUrl.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.nikseComboBoxUrl.DropDownWidth = 121; + this.nikseComboBoxUrl.FormattingEnabled = true; + this.nikseComboBoxUrl.Location = new System.Drawing.Point(56, 528); + this.nikseComboBoxUrl.MaxLength = 32767; + this.nikseComboBoxUrl.Name = "nikseComboBoxUrl"; + this.nikseComboBoxUrl.SelectedIndex = -1; + this.nikseComboBoxUrl.SelectedItem = null; + this.nikseComboBoxUrl.SelectedText = ""; + this.nikseComboBoxUrl.Size = new System.Drawing.Size(386, 21); + this.nikseComboBoxUrl.TabIndex = 105; + this.nikseComboBoxUrl.UsePopupWindow = false; + // + // comboBoxSource + // + this.comboBoxSource.BackColor = System.Drawing.SystemColors.Window; + this.comboBoxSource.BackColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240))))); + this.comboBoxSource.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(171)))), ((int)(((byte)(173)))), ((int)(((byte)(179))))); + this.comboBoxSource.BorderColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(120)))), ((int)(((byte)(120))))); + this.comboBoxSource.ButtonForeColor = System.Drawing.SystemColors.ControlText; + this.comboBoxSource.ButtonForeColorDown = System.Drawing.Color.Orange; + this.comboBoxSource.ButtonForeColorOver = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); + this.comboBoxSource.DropDownHeight = 400; + this.comboBoxSource.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxSource.DropDownWidth = 200; + this.comboBoxSource.FormattingEnabled = true; + this.comboBoxSource.Location = new System.Drawing.Point(321, 23); + this.comboBoxSource.MaxLength = 32767; + this.comboBoxSource.Name = "comboBoxSource"; + this.comboBoxSource.SelectedIndex = -1; + this.comboBoxSource.SelectedItem = null; + this.comboBoxSource.SelectedText = ""; + this.comboBoxSource.Size = new System.Drawing.Size(121, 21); + this.comboBoxSource.TabIndex = 94; + this.comboBoxSource.UsePopupWindow = false; + // + // comboBoxTarget + // + this.comboBoxTarget.BackColor = System.Drawing.SystemColors.Window; + this.comboBoxTarget.BackColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240))))); + this.comboBoxTarget.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(171)))), ((int)(((byte)(173)))), ((int)(((byte)(179))))); + this.comboBoxTarget.BorderColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(120)))), ((int)(((byte)(120))))); + this.comboBoxTarget.ButtonForeColor = System.Drawing.SystemColors.ControlText; + this.comboBoxTarget.ButtonForeColorDown = System.Drawing.Color.Orange; + this.comboBoxTarget.ButtonForeColorOver = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); + this.comboBoxTarget.DropDownHeight = 400; + this.comboBoxTarget.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxTarget.DropDownWidth = 200; + this.comboBoxTarget.FormattingEnabled = true; + this.comboBoxTarget.Location = new System.Drawing.Point(491, 23); + this.comboBoxTarget.MaxLength = 32767; + this.comboBoxTarget.Name = "comboBoxTarget"; + this.comboBoxTarget.SelectedIndex = -1; + this.comboBoxTarget.SelectedItem = null; + this.comboBoxTarget.SelectedText = ""; + this.comboBoxTarget.Size = new System.Drawing.Size(121, 21); + this.comboBoxTarget.TabIndex = 95; + this.comboBoxTarget.UsePopupWindow = false; + // + // subtitleListViewTarget + // + this.subtitleListViewTarget.AllowColumnReorder = true; + this.subtitleListViewTarget.FirstVisibleIndex = -1; + this.subtitleListViewTarget.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.subtitleListViewTarget.FullRowSelect = true; + this.subtitleListViewTarget.GridLines = true; + this.subtitleListViewTarget.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.subtitleListViewTarget.HideSelection = false; + this.subtitleListViewTarget.Location = new System.Drawing.Point(465, 52); + this.subtitleListViewTarget.Name = "subtitleListViewTarget"; + this.subtitleListViewTarget.OwnerDraw = true; + this.subtitleListViewTarget.Size = new System.Drawing.Size(428, 459); + this.subtitleListViewTarget.SubtitleFontBold = false; + this.subtitleListViewTarget.SubtitleFontName = "Tahoma"; + this.subtitleListViewTarget.SubtitleFontSize = 8; + this.subtitleListViewTarget.TabIndex = 98; + this.subtitleListViewTarget.UseCompatibleStateImageBehavior = false; + this.subtitleListViewTarget.UseSyntaxColoring = true; + this.subtitleListViewTarget.View = System.Windows.Forms.View.Details; + // + // subtitleListViewSource + // + this.subtitleListViewSource.AllowColumnReorder = true; + this.subtitleListViewSource.FirstVisibleIndex = -1; + this.subtitleListViewSource.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.subtitleListViewSource.FullRowSelect = true; + this.subtitleListViewSource.GridLines = true; + this.subtitleListViewSource.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.subtitleListViewSource.HideSelection = false; + this.subtitleListViewSource.Location = new System.Drawing.Point(12, 52); + this.subtitleListViewSource.Name = "subtitleListViewSource"; + this.subtitleListViewSource.OwnerDraw = true; + this.subtitleListViewSource.Size = new System.Drawing.Size(430, 459); + this.subtitleListViewSource.SubtitleFontBold = false; + this.subtitleListViewSource.SubtitleFontName = "Tahoma"; + this.subtitleListViewSource.SubtitleFontSize = 8; + this.subtitleListViewSource.TabIndex = 97; + this.subtitleListViewSource.UseCompatibleStateImageBehavior = false; + this.subtitleListViewSource.UseSyntaxColoring = true; + this.subtitleListViewSource.View = System.Windows.Forms.View.Details; + // + // AutoTranslate + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(904, 563); + this.Controls.Add(this.labelUrl); + this.Controls.Add(this.nikseComboBoxUrl); + this.Controls.Add(this.labelTarget); + this.Controls.Add(this.labelSource); + this.Controls.Add(this.comboBoxSource); + this.Controls.Add(this.progressBar1); + this.Controls.Add(this.labelPleaseWait); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.buttonOK); + this.Controls.Add(this.buttonTranslate); + this.Controls.Add(this.comboBoxTarget); + this.Controls.Add(this.subtitleListViewTarget); + this.Controls.Add(this.subtitleListViewSource); + this.KeyPreview = true; + this.Name = "AutoTranslate"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "AutoTranslate"; + this.Resize += new System.EventHandler(this.AutoTranslate_Resize); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private Controls.NikseComboBox comboBoxSource; + private System.Windows.Forms.ProgressBar progressBar1; + private System.Windows.Forms.Label labelPleaseWait; + private System.Windows.Forms.Button buttonCancel; + private System.Windows.Forms.Button buttonOK; + private System.Windows.Forms.Button buttonTranslate; + private Controls.NikseComboBox comboBoxTarget; + private Controls.SubtitleListView subtitleListViewTarget; + private Controls.SubtitleListView subtitleListViewSource; + private System.Windows.Forms.Label labelTarget; + private System.Windows.Forms.Label labelSource; + private System.Windows.Forms.Label labelUrl; + private Controls.NikseComboBox nikseComboBoxUrl; + } +} \ No newline at end of file diff --git a/src/ui/Forms/Translate/AutoTranslate.cs b/src/ui/Forms/Translate/AutoTranslate.cs new file mode 100644 index 000000000..944b05124 --- /dev/null +++ b/src/ui/Forms/Translate/AutoTranslate.cs @@ -0,0 +1,311 @@ +using Nikse.SubtitleEdit.Controls; +using Nikse.SubtitleEdit.Core.AutoTranslate; +using Nikse.SubtitleEdit.Core.Common; +using Nikse.SubtitleEdit.Core.SubtitleFormats; +using Nikse.SubtitleEdit.Core.Translate; +using Nikse.SubtitleEdit.Logic; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace Nikse.SubtitleEdit.Forms.Translate +{ + public sealed partial class AutoTranslate : Form + { + public Subtitle TranslatedSubtitle { get; private set; } + private Subtitle _subtitle; + private Encoding _encoding; + private SubtitleFormat _subtitleFormat; + private IAutoTranslator _autoTranslator; + private int _translationProgressIndex = -1; + private bool _translationProgressDirty; + private bool _breakTranslation; + + public AutoTranslate(Subtitle subtitle, Subtitle selectedLines, string title, Encoding encoding, SubtitleFormat subtitleFormat) + { + UiUtil.PreInitialize(this); + InitializeComponent(); + UiUtil.FixFonts(this); + + Text = LanguageSettings.Current.GoogleTranslate.Title; + buttonTranslate.Text = LanguageSettings.Current.GoogleTranslate.Translate; + labelPleaseWait.Text = LanguageSettings.Current.GoogleTranslate.PleaseWait; + buttonOK.Text = LanguageSettings.Current.General.Ok; + buttonCancel.Text = LanguageSettings.Current.General.Cancel; + subtitleListViewSource.InitializeLanguage(LanguageSettings.Current.General, Configuration.Settings); + subtitleListViewTarget.InitializeLanguage(LanguageSettings.Current.General, Configuration.Settings); + subtitleListViewSource.HideColumn(SubtitleListView.SubtitleColumn.CharactersPerSeconds); + subtitleListViewSource.HideColumn(SubtitleListView.SubtitleColumn.WordsPerMinute); + subtitleListViewTarget.HideColumn(SubtitleListView.SubtitleColumn.CharactersPerSeconds); + subtitleListViewTarget.HideColumn(SubtitleListView.SubtitleColumn.WordsPerMinute); + UiUtil.InitializeSubtitleFont(subtitleListViewSource); + UiUtil.InitializeSubtitleFont(subtitleListViewTarget); + subtitleListViewSource.AutoSizeColumns(); + subtitleListViewSource.AutoSizeColumns(); + UiUtil.FixLargeFonts(this, buttonOK); + ActiveControl = buttonTranslate; + + if (!string.IsNullOrEmpty(title)) + { + Text = title; + } + + nikseComboBoxUrl.Items.Clear(); + nikseComboBoxUrl.Items.Add("https://winstxnhdw-nllb-api.hf.space/api/v2/"); + nikseComboBoxUrl.Items.Add("http://localhost:7860/api/v2/"); + nikseComboBoxUrl.SelectedIndex = 0; + + labelPleaseWait.Visible = false; + progressBar1.Visible = false; + _subtitle = new Subtitle(subtitle); + _encoding = encoding; + _subtitleFormat = subtitleFormat; + + if (selectedLines != null) + { + TranslatedSubtitle = new Subtitle(selectedLines); + TranslatedSubtitle.Renumber(); + subtitleListViewTarget.Fill(TranslatedSubtitle); + } + else + { + TranslatedSubtitle = new Subtitle(_subtitle); + foreach (var paragraph in TranslatedSubtitle.Paragraphs) + { + paragraph.Text = string.Empty; + } + } + + subtitleListViewSource.Fill(_subtitle); + AutoTranslate_Resize(null, null); + + _autoTranslator = new AutoTranslator(); + SetupLanguageSettings(); + } + + private void SetupLanguageSettings() + { + FillComboWithLanguages(comboBoxSource, _autoTranslator.GetSupportedSourceLanguages()); + var sourceLanguageIsoCode = EvaluateDefaultSourceLanguageCode(_encoding, _subtitle); + SelectLanguageCode(comboBoxSource, sourceLanguageIsoCode); + + FillComboWithLanguages(comboBoxTarget, _autoTranslator.GetSupportedTargetLanguages()); + var targetLanguageIsoCode = EvaluateDefaultTargetLanguageCode(sourceLanguageIsoCode); + SelectLanguageCode(comboBoxTarget, targetLanguageIsoCode); + } + + public static void SelectLanguageCode(NikseComboBox comboBox, string languageIsoCode) + { + var i = 0; + var threeLetterLanguageCode = Iso639Dash2LanguageCode.GetThreeLetterCodeFromTwoLetterCode(languageIsoCode); + foreach (TranslationPair item in comboBox.Items) + { + if (item.Code.StartsWith(threeLetterLanguageCode)) + { + comboBox.SelectedIndex = i; + return; + } + i++; + } + + if (comboBox.SelectedIndex < 0 && comboBox.Items.Count > 0) + { + comboBox.SelectedIndex = 0; + } + } + + public static void FillComboWithLanguages(NikseComboBox comboBox, IEnumerable languages) + { + comboBox.Items.Clear(); + foreach (var language in languages) + { + comboBox.Items.Add(language); + } + } + + public static string EvaluateDefaultSourceLanguageCode(Encoding encoding, Subtitle subtitle) + { + var defaultSourceLanguageCode = LanguageAutoDetect.AutoDetectGoogleLanguage(encoding); // Guess language via encoding + if (string.IsNullOrEmpty(defaultSourceLanguageCode)) + { + defaultSourceLanguageCode = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); // Guess language based on subtitle contents + } + + return defaultSourceLanguageCode; + } + + public static string EvaluateDefaultTargetLanguageCode(string defaultSourceLanguage) + { + var installedLanguages = new List(); + foreach (InputLanguage language in InputLanguage.InstalledInputLanguages) + { + var iso639 = Iso639Dash2LanguageCode.GetTwoLetterCodeFromEnglishName(language.LayoutName); + if (!string.IsNullOrEmpty(iso639) && !installedLanguages.Contains(iso639)) + { + installedLanguages.Add(iso639.ToLowerInvariant()); + } + } + + var uiCultureTargetLanguage = Configuration.Settings.Tools.GoogleTranslateLastTargetLanguage; + if (uiCultureTargetLanguage == defaultSourceLanguage) + { + foreach (var s in Utilities.GetDictionaryLanguages()) + { + var temp = s.Replace("[", string.Empty).Replace("]", string.Empty); + if (temp.Length > 4) + { + temp = temp.Substring(temp.Length - 5, 2).ToLowerInvariant(); + if (temp != defaultSourceLanguage && installedLanguages.Any(p => p.Contains(temp))) + { + uiCultureTargetLanguage = temp; + break; + } + } + } + } + + if (uiCultureTargetLanguage == defaultSourceLanguage) + { + foreach (var language in installedLanguages) + { + if (language != defaultSourceLanguage) + { + uiCultureTargetLanguage = language; + break; + } + } + } + + if (uiCultureTargetLanguage == defaultSourceLanguage) + { + var name = CultureInfo.CurrentCulture.Name; + if (name.Length > 2) + { + name = name.Remove(0, name.Length - 2); + } + var iso = IsoCountryCodes.ThreeToTwoLetterLookup.FirstOrDefault(p => p.Value == name); + if (!iso.Equals(default(KeyValuePair))) + { + var iso639 = Iso639Dash2LanguageCode.GetTwoLetterCodeFromThreeLetterCode(iso.Key); + if (!string.IsNullOrEmpty(iso639)) + { + uiCultureTargetLanguage = iso639; + } + } + } + + // Set target language to something different than source language + if (uiCultureTargetLanguage == defaultSourceLanguage && defaultSourceLanguage == "en") + { + uiCultureTargetLanguage = "es"; + } + else if (uiCultureTargetLanguage == defaultSourceLanguage) + { + uiCultureTargetLanguage = "en"; + } + + return uiCultureTargetLanguage; + } + + private void AutoTranslate_Resize(object sender, System.EventArgs e) + { + var width = (Width / 2) - (subtitleListViewSource.Left * 3) + 19; + subtitleListViewSource.Width = width; + subtitleListViewTarget.Width = width; + + var height = Height - (subtitleListViewSource.Top + buttonTranslate.Height + 60); + subtitleListViewSource.Height = height; + subtitleListViewTarget.Height = height; + + comboBoxSource.Left = subtitleListViewSource.Left + (subtitleListViewSource.Width - comboBoxSource.Width); + labelSource.Left = comboBoxSource.Left - 5 - labelSource.Width; + + subtitleListViewTarget.Left = width + (subtitleListViewSource.Left * 2); + labelTarget.Left = subtitleListViewTarget.Left; + comboBoxTarget.Left = labelTarget.Left + labelTarget.Width + 5; + buttonTranslate.Left = comboBoxTarget.Left + comboBoxTarget.Width + 9; + labelPleaseWait.Left = buttonTranslate.Left + buttonTranslate.Width + 9; + progressBar1.Left = labelPleaseWait.Left; + progressBar1.Width = subtitleListViewTarget.Width - (progressBar1.Left - subtitleListViewTarget.Left); + } + + private async void buttonTranslate_Click(object sender, System.EventArgs e) + { + if (buttonTranslate.Text == LanguageSettings.Current.General.Cancel) + { + buttonTranslate.Enabled = false; + buttonOK.Enabled = true; + buttonCancel.Enabled = true; + _breakTranslation = true; + Application.DoEvents(); + buttonOK.Refresh(); + return; + } + + buttonOK.Enabled = false; + buttonCancel.Enabled = false; + _breakTranslation = false; + buttonTranslate.Text = LanguageSettings.Current.General.Cancel; + + _autoTranslator.Initialize(nikseComboBoxUrl.Text); + + var timerUpdate = new Timer(); + timerUpdate.Interval = 1000; + timerUpdate.Tick += TimerUpdate_Tick; + timerUpdate.Start(); + + if (comboBoxSource.SelectedItem is TranslationPair source && + comboBoxTarget.SelectedItem is TranslationPair target) + { + for (var index = 0; index < _subtitle.Paragraphs.Count; index++) + { + var p = _subtitle.Paragraphs[index]; + var translation = await _autoTranslator.Translate(p.Text, source.Code, target.Code); + TranslatedSubtitle.Paragraphs[index].Text = translation; + _translationProgressIndex = index; + _translationProgressDirty = true; + Application.DoEvents(); + if (_breakTranslation) + { + break; + } + } + } + + timerUpdate.Stop(); + + buttonOK.Enabled = true; + buttonCancel.Enabled = true; + _breakTranslation = false; + buttonTranslate.Text = LanguageSettings.Current.General.Cancel; + + timerUpdate.Dispose(); + _translationProgressDirty = true; + + UpdateTranslation(); + + buttonOK.Focus(); + } + + private void TimerUpdate_Tick(object sender, System.EventArgs e) + { + UpdateTranslation(); + } + + private void UpdateTranslation() + { + if (!_translationProgressDirty) + { + return; + } + + subtitleListViewTarget.BeginUpdate(); + subtitleListViewTarget.Fill(TranslatedSubtitle); + _translationProgressDirty = true; + subtitleListViewTarget.SelectIndexAndEnsureVisible(_translationProgressIndex); + subtitleListViewTarget.EndUpdate(); + } + } +} diff --git a/src/ui/Forms/Translate/AutoTranslate.resx b/src/ui/Forms/Translate/AutoTranslate.resx new file mode 100644 index 000000000..1af7de150 --- /dev/null +++ b/src/ui/Forms/Translate/AutoTranslate.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/ui/SubtitleEdit.csproj b/src/ui/SubtitleEdit.csproj index 3e7e27961..69eb908ff 100644 --- a/src/ui/SubtitleEdit.csproj +++ b/src/ui/SubtitleEdit.csproj @@ -646,6 +646,12 @@ TimedTextSmpteTiming.cs + + Form + + + AutoTranslate.cs + Form @@ -1868,6 +1874,9 @@ TimedTextSmpteTiming.cs + + AutoTranslate.cs + GenericTranslate.cs Designer