218 lines
9.4 KiB
C#
218 lines
9.4 KiB
C#
using DataModel.Database;
|
|
using Processor;
|
|
using UI_WinForms.Resources;
|
|
|
|
namespace UI_WinForms.Components;
|
|
|
|
public sealed partial class Setting : UserControl
|
|
{
|
|
public Setting()
|
|
{
|
|
this.InitializeComponent();
|
|
}
|
|
|
|
private Setting(SettingUIData settingMetaData)
|
|
{
|
|
this.InitializeComponent();
|
|
this.Dock = DockStyle.Top;
|
|
this.labelIcon.Image = settingMetaData.Icon;
|
|
this.labelSettingName.Text = settingMetaData.SettingName();
|
|
this.labelExplanation.Text = settingMetaData.SettingExplanation();
|
|
|
|
var dataControl = settingMetaData.SetupDataControl();
|
|
this.tableLayout.Controls.Add(dataControl, 2, 0);
|
|
|
|
// Ensure, that this data control is vertical centered by calculating the needed margin, considering the outer size of the table layout:
|
|
var margin = (this.tableLayout.GetRowHeights().First() - dataControl.Height) / 2f;
|
|
dataControl.Margin = new Padding(0, (int) margin, 0, (int)margin);
|
|
|
|
// Calculate the needed height of the explanation label & centering of the data control when the parent window is resized:
|
|
this.tableLayout.Resize += (sender, args) =>
|
|
{
|
|
// Adjust the height of the parent controls (table & user control):
|
|
this.tableLayout.Height = Math.Max((int)this.labelExplanation.CreateGraphics().MeasureString(this.labelExplanation.Text, this.labelExplanation.Font, new SizeF(this.labelExplanation.Width, 1000)).Height, 66);
|
|
this.Height = this.tableLayout.Height + this.tableLayout.Margin.Vertical;
|
|
|
|
// Ensure, that this data control is vertical centered by calculating the needed margin, considering the outer size of the table layout:
|
|
var margin = (this.tableLayout.GetRowHeights().First() - dataControl.Height) / 2f;
|
|
dataControl.Margin = new Padding(0, (int) margin, 0, (int)margin);
|
|
};
|
|
}
|
|
|
|
private readonly record struct SettingUIData(
|
|
Bitmap Icon,
|
|
Func<string> SettingName,
|
|
Func<string> SettingExplanation,
|
|
Func<Control> SetupDataControl
|
|
);
|
|
|
|
private static async Task<Setting> ShowDeepLModeSettingAsync()
|
|
{
|
|
var currentSetting = await AppSettings.GetDeepLMode();
|
|
var settingData = new SettingUIData(
|
|
Icon: Icons.deepl_logo_icon_170284,
|
|
SettingName: () => "DeepL Service",
|
|
SettingExplanation: () => "DeepL is a translation service that offers a wide range of translation services. This setting allows you to choose between the free and pro version of DeepL.",
|
|
SetupDataControl: () =>
|
|
{
|
|
var dropdown = new ComboBox();
|
|
dropdown.Items.Add("Disabled");
|
|
dropdown.Items.Add("Free version");
|
|
dropdown.Items.Add("Pro version");
|
|
dropdown.SelectedIndex = currentSetting switch
|
|
{
|
|
SettingDeepLMode.DISABLED => 0,
|
|
SettingDeepLMode.USE_FREE_ACCOUNT => 1,
|
|
SettingDeepLMode.USE_PRO_ACCOUNT => 2,
|
|
|
|
_ => 0,
|
|
};
|
|
|
|
// Setup the change event handler:
|
|
dropdown.SelectedValueChanged += async (sender, args) => await AppSettings.SetDeepLMode(dropdown.SelectedIndex switch
|
|
{
|
|
0 => SettingDeepLMode.DISABLED,
|
|
1 => SettingDeepLMode.USE_FREE_ACCOUNT,
|
|
2 => SettingDeepLMode.USE_PRO_ACCOUNT,
|
|
|
|
_ => SettingDeepLMode.DISABLED,
|
|
});
|
|
|
|
// Apply the desired layout:
|
|
dropdown.Dock = DockStyle.Fill;
|
|
dropdown.DropDownStyle = ComboBoxStyle.DropDownList;
|
|
|
|
return dropdown;
|
|
}
|
|
);
|
|
|
|
return new Setting(settingData);
|
|
}
|
|
|
|
private static async Task<Setting> ShowDeepLAPIKeySettingAsync()
|
|
{
|
|
var currentSetting = await AppSettings.GetDeepLAPIKey();
|
|
var settingData = new SettingUIData(
|
|
Icon: Icons.icons8_key_512,
|
|
SettingName: () => "DeepL API Key",
|
|
SettingExplanation: () => "The API key is required to use the DeepL translation service. You can find your API key on the DeepL website.",
|
|
SetupDataControl: () =>
|
|
{
|
|
var textbox = new TextBox();
|
|
textbox.Text = currentSetting;
|
|
textbox.TextChanged += async (sender, args) => await AppSettings.SetDeepLAPIKey(textbox.Text);
|
|
textbox.Dock = DockStyle.Fill;
|
|
return textbox;
|
|
}
|
|
);
|
|
|
|
return new Setting(settingData);
|
|
}
|
|
|
|
private static async Task<Setting> ShowDeepLActionSettingAsync()
|
|
{
|
|
var currentSetting = await AppSettings.GetDeepLAction();
|
|
var settingData = new SettingUIData(
|
|
Icon: Icons.icons8_play_512__2_,
|
|
SettingName: () => "DeepL Operation",
|
|
SettingExplanation: () => "Should the missing translations be automatically completed by DeepL? This can lead to higher costs. By default, DeepL is only applied manually.",
|
|
SetupDataControl: () =>
|
|
{
|
|
// We set up a combo box with the available actions:
|
|
var dropdown = new ComboBox();
|
|
dropdown.Items.Add("Manual");
|
|
dropdown.Items.Add("Automatic");
|
|
dropdown.SelectedIndex = currentSetting switch
|
|
{
|
|
SettingDeepLAction.MANUAL => 0,
|
|
SettingDeepLAction.AUTOMATIC_ALL => 1,
|
|
|
|
_ => 0,
|
|
};
|
|
|
|
// Setup the change event handler:
|
|
dropdown.SelectedValueChanged += async (sender, args) => await AppSettings.SetDeepLAction(dropdown.SelectedIndex switch
|
|
{
|
|
0 => SettingDeepLAction.MANUAL,
|
|
1 => SettingDeepLAction.AUTOMATIC_ALL,
|
|
|
|
_ => SettingDeepLAction.MANUAL,
|
|
});
|
|
|
|
// Apply the desired layout:
|
|
dropdown.Dock = DockStyle.Fill;
|
|
dropdown.DropDownStyle = ComboBoxStyle.DropDownList;
|
|
|
|
return dropdown;
|
|
}
|
|
);
|
|
|
|
return new Setting(settingData);
|
|
}
|
|
|
|
private static IEnumerable<Task<Setting>> ShowCultureSettingsAsync()
|
|
{
|
|
var isFirstCulture = true; // We need this flag to distinguish the first task from the others.
|
|
var cultureIndices = new List<int>(new []{ -1 });
|
|
while (cultureIndices.Count > 0)
|
|
{
|
|
var innerLoopIndex = cultureIndices.Last(); // needed to avoid closure issues.
|
|
yield return Task.Run(async () =>
|
|
{
|
|
var localCultureIndex = innerLoopIndex;
|
|
|
|
// Get a list of culture indices. Thus, we know the number of cultures. We cannot do this in the outer loop,
|
|
// because we cannot await there. The AppSettings is caching the answer, though. The list of indices is ordered
|
|
// ascending.
|
|
var localCultureIndices = await AppSettings.GetCultureIndices();
|
|
|
|
// Update the number of cultures in the outer loop for the first call:
|
|
if(isFirstCulture)
|
|
{
|
|
localCultureIndex = localCultureIndices.Last();
|
|
innerLoopIndex = localCultureIndices.Last();
|
|
|
|
cultureIndices.Clear();
|
|
cultureIndices.AddRange(localCultureIndices);
|
|
isFirstCulture = false;
|
|
}
|
|
|
|
// Get the current culture code:
|
|
var currentCultureCode = await AppSettings.GetCultureCode(localCultureIndex);
|
|
|
|
// Construct the setting:
|
|
return new Setting(new()
|
|
{
|
|
Icon = Icons.icons8_chat_bubble_512,
|
|
SettingName = () => $"{localCultureIndex}. Culture",
|
|
SettingExplanation = () => "The culture according to RFC 4646: First comes the ISO 639-1 language code in lower case, followed by a hyphen, followed by the ISO 3166-1 alpha-2 country code in upper case. Example: en-US for English in the USA, de-DE for German in Germany.",
|
|
SetupDataControl = () =>
|
|
{
|
|
var textbox = new TextBox();
|
|
textbox.Text = currentCultureCode;
|
|
textbox.TextChanged += async (sender, args) =>
|
|
{
|
|
await AppSettings.SetCultureCode(localCultureIndex, textbox.Text);
|
|
};
|
|
textbox.Dock = DockStyle.Fill;
|
|
return textbox;
|
|
}
|
|
});
|
|
});
|
|
|
|
cultureIndices.Remove(innerLoopIndex);
|
|
}
|
|
}
|
|
|
|
public static IEnumerable<Task<Setting>> GetAllSettings()
|
|
{
|
|
foreach (var setting in ShowCultureSettingsAsync())
|
|
{
|
|
yield return setting;
|
|
}
|
|
|
|
yield return ShowDeepLActionSettingAsync();
|
|
yield return ShowDeepLAPIKeySettingAsync();
|
|
yield return ShowDeepLModeSettingAsync();
|
|
}
|
|
} |