From 62310ce4a4ebf37c24c4e98e43649e29aa9f9945 Mon Sep 17 00:00:00 2001
From: chylex <contact@chylex.com>
Date: Sun, 31 Dec 2017 13:59:19 +0100
Subject: [PATCH] Add an option to set target language for tweet translations

---
 Configuration/UserConfig.cs                   |  1 +
 Core/Bridge/PropertyBridge.cs                 |  6 +-
 Core/Other/FormSettings.cs                    |  2 +-
 .../Settings/TabSettingsLocales.Designer.cs   | 66 +++++++++++++++----
 Core/Other/Settings/TabSettingsLocales.cs     | 17 +++--
 Core/Utils/LocaleUtils.cs                     |  9 +++
 Resources/Scripts/code.js                     | 11 ++++
 7 files changed, 90 insertions(+), 22 deletions(-)

diff --git a/Configuration/UserConfig.cs b/Configuration/UserConfig.cs
index fa0ea261..c414a779 100644
--- a/Configuration/UserConfig.cs
+++ b/Configuration/UserConfig.cs
@@ -52,6 +52,7 @@ static UserConfig(){
         
         public bool EnableSpellCheck    { get; set; } = false;
         public string AppLocale         { get; set; } = "en-US";
+        public string TranslationTarget { get; set; } = "en";
         
         private TrayIcon.Behavior _trayBehavior       = TrayIcon.Behavior.Disabled;
         public bool EnableTrayHighlight { get; set; } = true;
diff --git a/Core/Bridge/PropertyBridge.cs b/Core/Bridge/PropertyBridge.cs
index 01731a4b..06604802 100644
--- a/Core/Bridge/PropertyBridge.cs
+++ b/Core/Bridge/PropertyBridge.cs
@@ -7,9 +7,8 @@ public enum Environment{
         }
 
         public static string GenerateScript(Environment environment){
-            string Bool(bool value){
-                return value ? "true;" : "false;";
-            }
+            string Bool(bool value) => value ? "true;" : "false;";
+            string Str(string value) => '"'+value+"\";";
 
             StringBuilder build = new StringBuilder().Append("(function(x){");
 
@@ -21,6 +20,7 @@ string Bool(bool value){
                 build.Append("x.muteNotifications=").Append(Bool(Program.UserConfig.MuteNotifications));
                 build.Append("x.hasCustomNotificationSound=").Append(Bool(Program.UserConfig.NotificationSoundPath.Length > 0));
                 build.Append("x.notificationMediaPreviews=").Append(Bool(Program.UserConfig.NotificationMediaPreviews));
+                build.Append("x.translationTarget=").Append(Str(Program.UserConfig.TranslationTarget));
             }
 
             if (environment == Environment.Notification){
diff --git a/Core/Other/FormSettings.cs b/Core/Other/FormSettings.cs
index 2930834a..60ae3b9a 100644
--- a/Core/Other/FormSettings.cs
+++ b/Core/Other/FormSettings.cs
@@ -37,7 +37,7 @@ public FormSettings(FormBrowser browser, PluginManager plugins, UpdateHandler up
             this.buttonHeight = BrowserUtils.Scale(39, this.GetDPIScale()) | 1;
 
             AddButton("General", () => new TabSettingsGeneral(this.browser, updates));
-            AddButton("Locales", () => new TabSettingsLocales(this.browser));
+            AddButton("Locales", () => new TabSettingsLocales());
             AddButton("System Tray", () => new TabSettingsTray());
             AddButton("Notifications", () => new TabSettingsNotifications(new FormNotificationExample(this.browser, this.plugins)));
             AddButton("Sounds", () => new TabSettingsSounds());
diff --git a/Core/Other/Settings/TabSettingsLocales.Designer.cs b/Core/Other/Settings/TabSettingsLocales.Designer.cs
index 193e677a..789e782f 100644
--- a/Core/Other/Settings/TabSettingsLocales.Designer.cs
+++ b/Core/Other/Settings/TabSettingsLocales.Designer.cs
@@ -28,8 +28,11 @@ private void InitializeComponent() {
             this.checkSpellCheck = new System.Windows.Forms.CheckBox();
             this.labelLocales = new System.Windows.Forms.Label();
             this.flowPanel = new System.Windows.Forms.FlowLayoutPanel();
-            this.comboBoxAppLocale = new System.Windows.Forms.ComboBox();
             this.labelAppLanguage = new System.Windows.Forms.Label();
+            this.comboBoxAppLocale = new System.Windows.Forms.ComboBox();
+            this.labelTranslations = new System.Windows.Forms.Label();
+            this.labelTranslationTarget = new System.Windows.Forms.Label();
+            this.comboBoxTranslationTarget = new System.Windows.Forms.ComboBox();
             this.flowPanel.SuspendLayout();
             this.SuspendLayout();
             // 
@@ -64,23 +67,16 @@ private void InitializeComponent() {
             this.flowPanel.Controls.Add(this.checkSpellCheck);
             this.flowPanel.Controls.Add(this.labelAppLanguage);
             this.flowPanel.Controls.Add(this.comboBoxAppLocale);
+            this.flowPanel.Controls.Add(this.labelTranslations);
+            this.flowPanel.Controls.Add(this.labelTranslationTarget);
+            this.flowPanel.Controls.Add(this.comboBoxTranslationTarget);
             this.flowPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
             this.flowPanel.Location = new System.Drawing.Point(9, 9);
             this.flowPanel.Name = "flowPanel";
-            this.flowPanel.Size = new System.Drawing.Size(322, 320);
+            this.flowPanel.Size = new System.Drawing.Size(322, 193);
             this.flowPanel.TabIndex = 4;
             this.flowPanel.WrapContents = false;
             // 
-            // comboBoxAppLocale
-            // 
-            this.comboBoxAppLocale.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-            this.comboBoxAppLocale.FormattingEnabled = true;
-            this.comboBoxAppLocale.Location = new System.Drawing.Point(5, 74);
-            this.comboBoxAppLocale.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
-            this.comboBoxAppLocale.Name = "comboBoxAppLocale";
-            this.comboBoxAppLocale.Size = new System.Drawing.Size(311, 21);
-            this.comboBoxAppLocale.TabIndex = 9;
-            // 
             // labelAppLanguage
             // 
             this.labelAppLanguage.AutoSize = true;
@@ -91,13 +87,54 @@ private void InitializeComponent() {
             this.labelAppLanguage.TabIndex = 11;
             this.labelAppLanguage.Text = "App Language";
             // 
+            // comboBoxAppLocale
+            // 
+            this.comboBoxAppLocale.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.comboBoxAppLocale.FormattingEnabled = true;
+            this.comboBoxAppLocale.Location = new System.Drawing.Point(5, 74);
+            this.comboBoxAppLocale.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
+            this.comboBoxAppLocale.Name = "comboBoxAppLocale";
+            this.comboBoxAppLocale.Size = new System.Drawing.Size(311, 21);
+            this.comboBoxAppLocale.TabIndex = 9;
+            // 
+            // labelTranslations
+            // 
+            this.labelTranslations.AutoSize = true;
+            this.labelTranslations.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
+            this.labelTranslations.Location = new System.Drawing.Point(0, 118);
+            this.labelTranslations.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
+            this.labelTranslations.Name = "labelTranslations";
+            this.labelTranslations.Size = new System.Drawing.Size(116, 20);
+            this.labelTranslations.TabIndex = 10;
+            this.labelTranslations.Text = "Bing Translator";
+            // 
+            // labelTranslationTarget
+            // 
+            this.labelTranslationTarget.AutoSize = true;
+            this.labelTranslationTarget.Location = new System.Drawing.Point(3, 150);
+            this.labelTranslationTarget.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
+            this.labelTranslationTarget.Name = "labelTranslationTarget";
+            this.labelTranslationTarget.Size = new System.Drawing.Size(89, 13);
+            this.labelTranslationTarget.TabIndex = 8;
+            this.labelTranslationTarget.Text = "Target Language";
+            // 
+            // comboBoxTranslationTarget
+            // 
+            this.comboBoxTranslationTarget.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.comboBoxTranslationTarget.FormattingEnabled = true;
+            this.comboBoxTranslationTarget.Location = new System.Drawing.Point(5, 166);
+            this.comboBoxTranslationTarget.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
+            this.comboBoxTranslationTarget.Name = "comboBoxTranslationTarget";
+            this.comboBoxTranslationTarget.Size = new System.Drawing.Size(311, 21);
+            this.comboBoxTranslationTarget.TabIndex = 7;
+            // 
             // TabSettingsLocales
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
             this.Controls.Add(this.flowPanel);
             this.Name = "TabSettingsLocales";
-            this.Size = new System.Drawing.Size(340, 338);
+            this.Size = new System.Drawing.Size(340, 211);
             this.flowPanel.ResumeLayout(false);
             this.flowPanel.PerformLayout();
             this.ResumeLayout(false);
@@ -109,7 +146,10 @@ private void InitializeComponent() {
         private System.Windows.Forms.CheckBox checkSpellCheck;
         private System.Windows.Forms.Label labelLocales;
         private System.Windows.Forms.FlowLayoutPanel flowPanel;
+        private System.Windows.Forms.ComboBox comboBoxTranslationTarget;
+        private System.Windows.Forms.Label labelTranslationTarget;
         private System.Windows.Forms.ComboBox comboBoxAppLocale;
+        private System.Windows.Forms.Label labelTranslations;
         private System.Windows.Forms.Label labelAppLanguage;
     }
 }
diff --git a/Core/Other/Settings/TabSettingsLocales.cs b/Core/Other/Settings/TabSettingsLocales.cs
index bb8cf220..6b06d6ec 100644
--- a/Core/Other/Settings/TabSettingsLocales.cs
+++ b/Core/Other/Settings/TabSettingsLocales.cs
@@ -4,15 +4,12 @@
 
 namespace TweetDuck.Core.Other.Settings{
     sealed partial class TabSettingsLocales : BaseTabSettings{
-        private readonly FormBrowser browser;
-
-        public TabSettingsLocales(FormBrowser browser){
+        public TabSettingsLocales(){
             InitializeComponent();
-
-            this.browser = browser;
             
             toolTip.SetToolTip(checkSpellCheck, "Underlines words that are spelled incorrectly.");
             toolTip.SetToolTip(comboBoxAppLocale, "Language used for spell check and context menu items.");
+            toolTip.SetToolTip(comboBoxTranslationTarget, "Language tweets are translated into.");
             
             checkSpellCheck.Checked = Config.EnableSpellCheck;
 
@@ -26,11 +23,17 @@ public TabSettingsLocales(FormBrowser browser){
 
             comboBoxAppLocale.SelectedItem = new LocaleUtils.Item(Config.AppLocale);
 
+            foreach(LocaleUtils.Item item in LocaleUtils.TweetDeckTranslationLocales){
+                comboBoxTranslationTarget.Items.Add(item);
+            }
+
+            comboBoxTranslationTarget.SelectedItem = new LocaleUtils.Item(Config.TranslationTarget);
         }
 
         public override void OnReady(){
             checkSpellCheck.CheckedChanged += checkSpellCheck_CheckedChanged;
             comboBoxAppLocale.SelectedValueChanged += comboBoxAppLocale_SelectedValueChanged;
+            comboBoxTranslationTarget.SelectedValueChanged += comboBoxTranslationTarget_SelectedValueChanged;
         }
 
         private void checkSpellCheck_CheckedChanged(object sender, EventArgs e){
@@ -42,5 +45,9 @@ private void comboBoxAppLocale_SelectedValueChanged(object sender, EventArgs e){
             Config.AppLocale = (comboBoxAppLocale.SelectedItem as LocaleUtils.Item)?.Code;
             PromptRestart();
         }
+
+        private void comboBoxTranslationTarget_SelectedValueChanged(object sender, EventArgs e){
+            Config.TranslationTarget = (comboBoxTranslationTarget.SelectedItem as LocaleUtils.Item)?.Code;
+        }
     }
 }
diff --git a/Core/Utils/LocaleUtils.cs b/Core/Utils/LocaleUtils.cs
index 829f41d0..43d752d3 100644
--- a/Core/Utils/LocaleUtils.cs
+++ b/Core/Utils/LocaleUtils.cs
@@ -13,6 +13,15 @@ static class LocaleUtils{
             .Select(file => new Item(Path.GetFileNameWithoutExtension(file)))
             .OrderBy(code => code);
         
+        // TD.languages.getSupportedTranslationDestinationLanguages() except for "ht", "in", "iw" which are missing/duplicates
+        public static IEnumerable<Item> TweetDeckTranslationLocales { get; } = new List<string>{
+            "bg", "ca", "zh-cn", "zh-tw", "cs", "da", "nl",
+            "en", "et", "fi", "fr", "de", "el", "he", "hi",
+            "hu", "id", "it", "ja", "ko", "lv", "lt", "no",
+            "pl", "pt", "ro", "ru", "sk", "sl", "es", "sv",
+            "th", "tr", "uk", "vi", "ar", "fa"
+        }.Select(code => new Item(code)).OrderBy(code => code).ToList();
+
         public sealed class Item : IComparable<Item>{
             public string Code { get; }
             public CultureInfo Info { get; }
diff --git a/Resources/Scripts/code.js b/Resources/Scripts/code.js
index 16d5ccbe..60544b64 100644
--- a/Resources/Scripts/code.js
+++ b/Resources/Scripts/code.js
@@ -1129,6 +1129,17 @@
     });
   });
   
+  //
+  // Block: Override language used for translations.
+  //
+  if (ensurePropertyExists(TD, "languages", "getSystemLanguageCode")){
+    const prevFunc = TD.languages.getSystemLanguageCode;
+    
+    TD.languages.getSystemLanguageCode = function(returnShortCode){
+      return returnShortCode ? ($TDX.translationTarget || "en") : prevFunc.apply(this, arguments);
+    };
+  }
+  
   //
   // Block: Setup global function to refresh all columns.
   //