feat: base function to switch language
This commit is contained in:
1022
SpineViewer/Forms/SpineViewerForm.Designer.cs
generated
1022
SpineViewer/Forms/SpineViewerForm.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
@@ -8,460 +8,494 @@ using SpineViewer.Spine.SpineExporter;
|
|||||||
|
|
||||||
namespace SpineViewer
|
namespace SpineViewer
|
||||||
{
|
{
|
||||||
internal partial class SpineViewerForm : Form
|
internal partial class SpineViewerForm : Form
|
||||||
{
|
{
|
||||||
private readonly Logger logger = LogManager.GetCurrentClassLogger();
|
private readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
private readonly Dictionary<string, Exporter> exporterCache = [];
|
private readonly Dictionary<string, Exporter> exporterCache = [];
|
||||||
|
|
||||||
public SpineViewerForm()
|
public SpineViewerForm()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeLogConfiguration();
|
InitializeLogConfiguration();
|
||||||
|
|
||||||
// 执行一些初始化工作
|
// 执行一些初始化工作
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SFMLShader.Init();
|
SFMLShader.Init();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.Error(ex.ToString());
|
logger.Error(ex.ToString());
|
||||||
logger.Error("Failed to load fragment shader");
|
logger.Error("Failed to load fragment shader");
|
||||||
MessagePopup.Warn("Fragment shader 加载失败,预乘Alpha通道属性失效");
|
MessagePopup.Warn("Fragment shader 加载失败,预乘Alpha通道属性失效");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
toolStripMenuItem_Debug.Visible = true;
|
toolStripMenuItem_Debug.Visible = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化窗口日志器
|
/// 初始化窗口日志器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeLogConfiguration()
|
private void InitializeLogConfiguration()
|
||||||
{
|
{
|
||||||
// 窗口日志
|
// 窗口日志
|
||||||
var rtbTarget = new NLog.Windows.Forms.RichTextBoxTarget
|
var rtbTarget = new NLog.Windows.Forms.RichTextBoxTarget
|
||||||
{
|
{
|
||||||
Name = "rtbTarget",
|
Name = "rtbTarget",
|
||||||
TargetForm = this,
|
TargetForm = this,
|
||||||
TargetRichTextBox = rtbLog,
|
TargetRichTextBox = rtbLog,
|
||||||
AutoScroll = true,
|
AutoScroll = true,
|
||||||
MaxLines = 3000,
|
MaxLines = 3000,
|
||||||
SupportLinks = true,
|
SupportLinks = true,
|
||||||
Layout = "[${level:format=OneLetter}]${date:format=yyyy-MM-dd HH\\:mm\\:ss} - ${message}"
|
Layout = "[${level:format=OneLetter}]${date:format=yyyy-MM-dd HH\\:mm\\:ss} - ${message}"
|
||||||
};
|
};
|
||||||
|
|
||||||
rtbTarget.WordColoringRules.Add(new("[D]", "Gray", "Empty", FontStyle.Bold));
|
rtbTarget.WordColoringRules.Add(new("[D]", "Gray", "Empty", FontStyle.Bold));
|
||||||
rtbTarget.WordColoringRules.Add(new("[I]", "DimGray", "Empty", FontStyle.Bold));
|
rtbTarget.WordColoringRules.Add(new("[I]", "DimGray", "Empty", FontStyle.Bold));
|
||||||
rtbTarget.WordColoringRules.Add(new("[W]", "DarkOrange", "Empty", FontStyle.Bold));
|
rtbTarget.WordColoringRules.Add(new("[W]", "DarkOrange", "Empty", FontStyle.Bold));
|
||||||
rtbTarget.WordColoringRules.Add(new("[E]", "Red", "Empty", FontStyle.Bold));
|
rtbTarget.WordColoringRules.Add(new("[E]", "Red", "Empty", FontStyle.Bold));
|
||||||
rtbTarget.WordColoringRules.Add(new("[F]", "DarkRed", "Empty", FontStyle.Bold));
|
rtbTarget.WordColoringRules.Add(new("[F]", "DarkRed", "Empty", FontStyle.Bold));
|
||||||
|
|
||||||
LogManager.Configuration.AddTarget(rtbTarget);
|
LogManager.Configuration.AddTarget(rtbTarget);
|
||||||
LogManager.Configuration.AddRule(LogLevel.Debug, LogLevel.Fatal, rtbTarget);
|
LogManager.Configuration.AddRule(LogLevel.Debug, LogLevel.Fatal, rtbTarget);
|
||||||
LogManager.ReconfigExistingLoggers();
|
LogManager.ReconfigExistingLoggers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MainForm_Load(object sender, EventArgs e)
|
private void MainForm_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
spinePreviewPanel.StartRender();
|
spinePreviewPanel.StartRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
{
|
{
|
||||||
spinePreviewPanel.StopRender();
|
spinePreviewPanel.StopRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_Open_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_Open_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
spineListView.Add();
|
spineListView.Add();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_BatchOpen_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_BatchOpen_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
spineListView.BatchAdd();
|
spineListView.BatchAdd();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region private void toolStripMenuItem_ExportXXX_Click(object sender, EventArgs e)
|
#region private void toolStripMenuItem_ExportXXX_Click(object sender, EventArgs e)
|
||||||
|
|
||||||
private void toolStripMenuItem_ExportFrame_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ExportFrame_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (spinePreviewPanel.IsUpdating && MessagePopup.Quest("画面仍在更新,建议手动暂停画面后导出固定的一帧,是否继续?") != DialogResult.OK)
|
if (spinePreviewPanel.IsUpdating && MessagePopup.Quest("画面仍在更新,建议手动暂停画面后导出固定的一帧,是否继续?") != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var k = nameof(toolStripMenuItem_ExportFrame);
|
var k = nameof(toolStripMenuItem_ExportFrame);
|
||||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new FrameExporter();
|
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new FrameExporter();
|
||||||
|
|
||||||
var exporter = exporterCache[k];
|
var exporter = exporterCache[k];
|
||||||
using var view = spinePreviewPanel.GetView();
|
using var view = spinePreviewPanel.GetView();
|
||||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||||
exporter.PreviewerView = view;
|
exporter.PreviewerView = view;
|
||||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||||
|
|
||||||
var exportDialog = new Dialogs.ExportDialog(new FrameExporterProperty((FrameExporter)exporter));
|
var exportDialog = new Dialogs.ExportDialog(new FrameExporterProperty((FrameExporter)exporter));
|
||||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
progressDialog.DoWork += Export_Work;
|
progressDialog.DoWork += Export_Work;
|
||||||
progressDialog.RunWorkerAsync(exporter);
|
progressDialog.RunWorkerAsync(exporter);
|
||||||
progressDialog.ShowDialog();
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_ExportFrameSequence_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ExportFrameSequence_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var k = nameof(toolStripMenuItem_ExportFrameSequence);
|
var k = nameof(toolStripMenuItem_ExportFrameSequence);
|
||||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new FrameSequenceExporter();
|
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new FrameSequenceExporter();
|
||||||
|
|
||||||
var exporter = exporterCache[k];
|
var exporter = exporterCache[k];
|
||||||
using var view = spinePreviewPanel.GetView();
|
using var view = spinePreviewPanel.GetView();
|
||||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||||
exporter.PreviewerView = view;
|
exporter.PreviewerView = view;
|
||||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||||
|
|
||||||
var exportDialog = new Dialogs.ExportDialog(new FrameSequenceExporterProperty((FrameSequenceExporter)exporter));
|
var exportDialog = new Dialogs.ExportDialog(new FrameSequenceExporterProperty((FrameSequenceExporter)exporter));
|
||||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
progressDialog.DoWork += Export_Work;
|
progressDialog.DoWork += Export_Work;
|
||||||
progressDialog.RunWorkerAsync(exporter);
|
progressDialog.RunWorkerAsync(exporter);
|
||||||
progressDialog.ShowDialog();
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_ExportGif_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ExportGif_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var k = nameof(toolStripMenuItem_ExportGif);
|
var k = nameof(toolStripMenuItem_ExportGif);
|
||||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new GifExporter();
|
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new GifExporter();
|
||||||
|
|
||||||
var exporter = exporterCache[k];
|
var exporter = exporterCache[k];
|
||||||
using var view = spinePreviewPanel.GetView();
|
using var view = spinePreviewPanel.GetView();
|
||||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||||
exporter.PreviewerView = view;
|
exporter.PreviewerView = view;
|
||||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||||
|
|
||||||
var exportDialog = new Dialogs.ExportDialog(new GifExporterProperty((GifExporter)exporter));
|
var exportDialog = new Dialogs.ExportDialog(new GifExporterProperty((GifExporter)exporter));
|
||||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
progressDialog.DoWork += Export_Work;
|
progressDialog.DoWork += Export_Work;
|
||||||
progressDialog.RunWorkerAsync(exporter);
|
progressDialog.RunWorkerAsync(exporter);
|
||||||
progressDialog.ShowDialog();
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_ExportWebp_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ExportWebp_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var k = nameof(toolStripMenuItem_ExportWebp);
|
var k = nameof(toolStripMenuItem_ExportWebp);
|
||||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new WebpExporter();
|
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new WebpExporter();
|
||||||
|
|
||||||
var exporter = exporterCache[k];
|
var exporter = exporterCache[k];
|
||||||
using var view = spinePreviewPanel.GetView();
|
using var view = spinePreviewPanel.GetView();
|
||||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||||
exporter.PreviewerView = view;
|
exporter.PreviewerView = view;
|
||||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||||
|
|
||||||
var exportDialog = new Dialogs.ExportDialog(new WebpExporterProperty((WebpExporter)exporter));
|
var exportDialog = new Dialogs.ExportDialog(new WebpExporterProperty((WebpExporter)exporter));
|
||||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
progressDialog.DoWork += Export_Work;
|
progressDialog.DoWork += Export_Work;
|
||||||
progressDialog.RunWorkerAsync(exporter);
|
progressDialog.RunWorkerAsync(exporter);
|
||||||
progressDialog.ShowDialog();
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_ExportAvif_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ExportAvif_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var k = nameof(toolStripMenuItem_ExportAvif);
|
var k = nameof(toolStripMenuItem_ExportAvif);
|
||||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new AvifExporter();
|
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new AvifExporter();
|
||||||
|
|
||||||
var exporter = exporterCache[k];
|
var exporter = exporterCache[k];
|
||||||
using var view = spinePreviewPanel.GetView();
|
using var view = spinePreviewPanel.GetView();
|
||||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||||
exporter.PreviewerView = view;
|
exporter.PreviewerView = view;
|
||||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||||
|
|
||||||
var exportDialog = new Dialogs.ExportDialog(new AvifExporterProperty((AvifExporter)exporter));
|
var exportDialog = new Dialogs.ExportDialog(new AvifExporterProperty((AvifExporter)exporter));
|
||||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
progressDialog.DoWork += Export_Work;
|
progressDialog.DoWork += Export_Work;
|
||||||
progressDialog.RunWorkerAsync(exporter);
|
progressDialog.RunWorkerAsync(exporter);
|
||||||
progressDialog.ShowDialog();
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_ExportMp4_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ExportMp4_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var k = nameof(toolStripMenuItem_ExportMp4);
|
var k = nameof(toolStripMenuItem_ExportMp4);
|
||||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new Mp4Exporter();
|
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new Mp4Exporter();
|
||||||
|
|
||||||
var exporter = exporterCache[k];
|
var exporter = exporterCache[k];
|
||||||
using var view = spinePreviewPanel.GetView();
|
using var view = spinePreviewPanel.GetView();
|
||||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||||
exporter.PreviewerView = view;
|
exporter.PreviewerView = view;
|
||||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||||
|
|
||||||
var exportDialog = new Dialogs.ExportDialog(new Mp4ExporterProperty((Mp4Exporter)exporter));
|
var exportDialog = new Dialogs.ExportDialog(new Mp4ExporterProperty((Mp4Exporter)exporter));
|
||||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
progressDialog.DoWork += Export_Work;
|
progressDialog.DoWork += Export_Work;
|
||||||
progressDialog.RunWorkerAsync(exporter);
|
progressDialog.RunWorkerAsync(exporter);
|
||||||
progressDialog.ShowDialog();
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_ExportWebm_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ExportWebm_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var k = nameof(toolStripMenuItem_ExportWebm);
|
var k = nameof(toolStripMenuItem_ExportWebm);
|
||||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new WebmExporter();
|
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new WebmExporter();
|
||||||
|
|
||||||
var exporter = exporterCache[k];
|
var exporter = exporterCache[k];
|
||||||
using var view = spinePreviewPanel.GetView();
|
using var view = spinePreviewPanel.GetView();
|
||||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||||
exporter.PreviewerView = view;
|
exporter.PreviewerView = view;
|
||||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||||
|
|
||||||
var exportDialog = new Dialogs.ExportDialog(new WebmExporterProperty((WebmExporter)exporter));
|
var exportDialog = new Dialogs.ExportDialog(new WebmExporterProperty((WebmExporter)exporter));
|
||||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
progressDialog.DoWork += Export_Work;
|
progressDialog.DoWork += Export_Work;
|
||||||
progressDialog.RunWorkerAsync(exporter);
|
progressDialog.RunWorkerAsync(exporter);
|
||||||
progressDialog.ShowDialog();
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_ExportMkv_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ExportMkv_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var k = nameof(toolStripMenuItem_ExportMkv);
|
var k = nameof(toolStripMenuItem_ExportMkv);
|
||||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new MkvExporter();
|
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new MkvExporter();
|
||||||
|
|
||||||
var exporter = exporterCache[k];
|
var exporter = exporterCache[k];
|
||||||
using var view = spinePreviewPanel.GetView();
|
using var view = spinePreviewPanel.GetView();
|
||||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||||
exporter.PreviewerView = view;
|
exporter.PreviewerView = view;
|
||||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||||
|
|
||||||
var exportDialog = new Dialogs.ExportDialog(new MkvExporterProperty((MkvExporter)exporter));
|
var exportDialog = new Dialogs.ExportDialog(new MkvExporterProperty((MkvExporter)exporter));
|
||||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
progressDialog.DoWork += Export_Work;
|
progressDialog.DoWork += Export_Work;
|
||||||
progressDialog.RunWorkerAsync(exporter);
|
progressDialog.RunWorkerAsync(exporter);
|
||||||
progressDialog.ShowDialog();
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_ExportMov_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ExportMov_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var k = nameof(toolStripMenuItem_ExportMov);
|
var k = nameof(toolStripMenuItem_ExportMov);
|
||||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new MovExporter();
|
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new MovExporter();
|
||||||
|
|
||||||
var exporter = exporterCache[k];
|
var exporter = exporterCache[k];
|
||||||
using var view = spinePreviewPanel.GetView();
|
using var view = spinePreviewPanel.GetView();
|
||||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||||
exporter.PreviewerView = view;
|
exporter.PreviewerView = view;
|
||||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||||
|
|
||||||
var exportDialog = new Dialogs.ExportDialog(new MovExporterProperty((MovExporter)exporter));
|
var exportDialog = new Dialogs.ExportDialog(new MovExporterProperty((MovExporter)exporter));
|
||||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
progressDialog.DoWork += Export_Work;
|
progressDialog.DoWork += Export_Work;
|
||||||
progressDialog.RunWorkerAsync(exporter);
|
progressDialog.RunWorkerAsync(exporter);
|
||||||
progressDialog.ShowDialog();
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_ExportCustom_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ExportCustom_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var k = nameof(toolStripMenuItem_ExportCustom);
|
var k = nameof(toolStripMenuItem_ExportCustom);
|
||||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new CustomExporter();
|
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new CustomExporter();
|
||||||
|
|
||||||
var exporter = exporterCache[k];
|
var exporter = exporterCache[k];
|
||||||
using var view = spinePreviewPanel.GetView();
|
using var view = spinePreviewPanel.GetView();
|
||||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||||
exporter.PreviewerView = view;
|
exporter.PreviewerView = view;
|
||||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||||
|
|
||||||
var exportDialog = new Dialogs.ExportDialog(new CustomExporterProperty((CustomExporter)exporter));
|
var exportDialog = new Dialogs.ExportDialog(new CustomExporterProperty((CustomExporter)exporter));
|
||||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
progressDialog.DoWork += Export_Work;
|
progressDialog.DoWork += Export_Work;
|
||||||
progressDialog.RunWorkerAsync(exporter);
|
progressDialog.RunWorkerAsync(exporter);
|
||||||
progressDialog.ShowDialog();
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void toolStripMenuItem_Exit_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_Exit_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_ConvertFileFormat_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ConvertFileFormat_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var openDialog = new Dialogs.ConvertFileFormatDialog();
|
var openDialog = new Dialogs.ConvertFileFormatDialog();
|
||||||
if (openDialog.ShowDialog() != DialogResult.OK)
|
if (openDialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var progressDialog = new Dialogs.ProgressDialog();
|
var progressDialog = new Dialogs.ProgressDialog();
|
||||||
progressDialog.DoWork += ConvertFileFormat_Work;
|
progressDialog.DoWork += ConvertFileFormat_Work;
|
||||||
progressDialog.RunWorkerAsync(openDialog.Result);
|
progressDialog.RunWorkerAsync(openDialog.Result);
|
||||||
progressDialog.ShowDialog();
|
progressDialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_ManageResource_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_ManageResource_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_About_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_About_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
using var dialog = new Dialogs.AboutDialog();
|
using var dialog = new Dialogs.AboutDialog();
|
||||||
dialog.ShowDialog();
|
dialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_Diagnostics_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_Diagnostics_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
using var dialog = new Dialogs.DiagnosticsDialog();
|
using var dialog = new Dialogs.DiagnosticsDialog();
|
||||||
dialog.ShowDialog();
|
dialog.ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void splitContainer_SplitterMoved(object sender, SplitterEventArgs e) => ActiveControl = null;
|
private void splitContainer_SplitterMoved(object sender, SplitterEventArgs e) => ActiveControl = null;
|
||||||
|
|
||||||
private void splitContainer_MouseUp(object sender, MouseEventArgs e) => ActiveControl = null;
|
private void splitContainer_MouseUp(object sender, MouseEventArgs e) => ActiveControl = null;
|
||||||
|
|
||||||
private void Export_Work(object? sender, DoWorkEventArgs e)
|
private void Export_Work(object? sender, DoWorkEventArgs e)
|
||||||
{
|
{
|
||||||
var worker = (BackgroundWorker)sender;
|
var worker = (BackgroundWorker)sender;
|
||||||
var exporter = (Exporter)e.Argument;
|
var exporter = (Exporter)e.Argument;
|
||||||
Invoke(() => TaskbarManager.SetProgressState(Handle, TBPFLAG.TBPF_INDETERMINATE));
|
Invoke(() => TaskbarManager.SetProgressState(Handle, TBPFLAG.TBPF_INDETERMINATE));
|
||||||
spinePreviewPanel.StopRender();
|
spinePreviewPanel.StopRender();
|
||||||
lock (spineListView.Spines) { exporter.Export(spineListView.Spines.Where(sp => !sp.IsHidden).ToArray(), (BackgroundWorker)sender); }
|
lock (spineListView.Spines) { exporter.Export(spineListView.Spines.Where(sp => !sp.IsHidden).ToArray(), (BackgroundWorker)sender); }
|
||||||
e.Cancel = worker.CancellationPending;
|
e.Cancel = worker.CancellationPending;
|
||||||
spinePreviewPanel.StartRender();
|
spinePreviewPanel.StartRender();
|
||||||
Invoke(() => TaskbarManager.SetProgressState(Handle, TBPFLAG.TBPF_NOPROGRESS));
|
Invoke(() => TaskbarManager.SetProgressState(Handle, TBPFLAG.TBPF_NOPROGRESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConvertFileFormat_Work(object? sender, DoWorkEventArgs e)
|
private void ConvertFileFormat_Work(object? sender, DoWorkEventArgs e)
|
||||||
{
|
{
|
||||||
var worker = sender as BackgroundWorker;
|
var worker = sender as BackgroundWorker;
|
||||||
var args = e.Argument as Dialogs.ConvertFileFormatDialogResult;
|
var args = e.Argument as Dialogs.ConvertFileFormatDialogResult;
|
||||||
var newSuffix = args.JsonTarget ? ".json" : ".skel";
|
var newSuffix = args.JsonTarget ? ".json" : ".skel";
|
||||||
|
|
||||||
int totalCount = args.SkelPaths.Length;
|
int totalCount = args.SkelPaths.Length;
|
||||||
int success = 0;
|
int success = 0;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
SkeletonConverter srcCvter = args.SourceVersion != SpineVersion.Auto ? SkeletonConverter.New(args.SourceVersion) : null;
|
SkeletonConverter srcCvter = args.SourceVersion != SpineVersion.Auto ? SkeletonConverter.New(args.SourceVersion) : null;
|
||||||
SkeletonConverter tgtCvter = SkeletonConverter.New(args.TargetVersion);
|
SkeletonConverter tgtCvter = SkeletonConverter.New(args.TargetVersion);
|
||||||
|
|
||||||
worker.ReportProgress(0, $"已处理 0/{totalCount}");
|
worker.ReportProgress(0, $"已处理 0/{totalCount}");
|
||||||
for (int i = 0; i < totalCount; i++)
|
for (int i = 0; i < totalCount; i++)
|
||||||
{
|
{
|
||||||
if (worker.CancellationPending)
|
if (worker.CancellationPending)
|
||||||
{
|
{
|
||||||
e.Cancel = true;
|
e.Cancel = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var skelPath = args.SkelPaths[i];
|
var skelPath = args.SkelPaths[i];
|
||||||
var newPath = Path.ChangeExtension(skelPath, newSuffix);
|
var newPath = Path.ChangeExtension(skelPath, newSuffix);
|
||||||
if (args.OutputDir is string outputDir) newPath = Path.Combine(outputDir, Path.GetFileName(newPath));
|
if (args.OutputDir is string outputDir) newPath = Path.Combine(outputDir, Path.GetFileName(newPath));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (args.SourceVersion == SpineVersion.Auto)
|
if (args.SourceVersion == SpineVersion.Auto)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
srcCvter = SkeletonConverter.New(SpineUtils.GetVersion(skelPath));
|
srcCvter = SkeletonConverter.New(SpineUtils.GetVersion(skelPath));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new InvalidDataException($"Auto version detection failed for {skelPath}, try to use a specific version", ex);
|
throw new InvalidDataException($"Auto version detection failed for {skelPath}, try to use a specific version", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var root = srcCvter.Read(skelPath);
|
var root = srcCvter.Read(skelPath);
|
||||||
root = srcCvter.ToVersion(root, args.TargetVersion);
|
root = srcCvter.ToVersion(root, args.TargetVersion);
|
||||||
if (args.JsonTarget) tgtCvter.WriteJson(root, newPath);
|
if (args.JsonTarget) tgtCvter.WriteJson(root, newPath);
|
||||||
else tgtCvter.WriteBinary(root, newPath);
|
else tgtCvter.WriteBinary(root, newPath);
|
||||||
success++;
|
success++;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.Error(ex.ToString());
|
logger.Error(ex.ToString());
|
||||||
logger.Error("Failed to convert {}", skelPath);
|
logger.Error("Failed to convert {}", skelPath);
|
||||||
error++;
|
error++;
|
||||||
}
|
}
|
||||||
|
|
||||||
worker.ReportProgress((int)((i + 1) * 100.0) / totalCount, $"已处理 {i + 1}/{totalCount}");
|
worker.ReportProgress((int)((i + 1) * 100.0) / totalCount, $"已处理 {i + 1}/{totalCount}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error > 0)
|
if (error > 0)
|
||||||
{
|
{
|
||||||
logger.Warn("Batch convert {} successfully, {} failed", success, error);
|
logger.Warn("Batch convert {} successfully, {} failed", success, error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger.Info("{} skel converted successfully", success);
|
logger.Info("{} skel converted successfully", success);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_DesktopProjection_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_DesktopProjection_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
toolStripMenuItem_DesktopProjection.Checked = !toolStripMenuItem_DesktopProjection.Checked;
|
toolStripMenuItem_DesktopProjection.Checked = !toolStripMenuItem_DesktopProjection.Checked;
|
||||||
spinePreviewPanel.EnableDesktopProjection = toolStripMenuItem_DesktopProjection.Checked;
|
spinePreviewPanel.EnableDesktopProjection = toolStripMenuItem_DesktopProjection.Checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toolStripMenuItem_Debug_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_Debug_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
//var cvt = SkeletonConverter.New(SpineVersion.V38);
|
//var cvt = SkeletonConverter.New(SpineVersion.V38);
|
||||||
//var root = cvt.ReadBinary(@"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3 - 副本.skel");
|
//var root = cvt.ReadBinary(@"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3 - 副本.skel");
|
||||||
//cvt.WriteJson(root, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.json");
|
//cvt.WriteJson(root, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.json");
|
||||||
|
|
||||||
//root = cvt.ReadJson(@"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.json");
|
//root = cvt.ReadJson(@"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.json");
|
||||||
//cvt.WriteBinary(root, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.skel");
|
//cvt.WriteBinary(root, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.skel");
|
||||||
//var sp = SpineObject.New(SpineVersion.V38, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.skel");
|
//var sp = SpineObject.New(SpineVersion.V38, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.skel");
|
||||||
|
|
||||||
//var cvt = SkeletonConverter.New(SpineVersion.V38);
|
//var cvt = SkeletonConverter.New(SpineVersion.V38);
|
||||||
//var root = cvt.ReadJson(@"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.json");
|
//var root = cvt.ReadJson(@"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.json");
|
||||||
//cvt.WriteBinary(root, @"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.skel");
|
//cvt.WriteBinary(root, @"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.skel");
|
||||||
//var sp = SpineObject.New(SpineVersion.V38, @"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.skel");
|
//var sp = SpineObject.New(SpineVersion.V38, @"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.skel");
|
||||||
//_Test();
|
//_Test();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//private void spinePreviewer_KeyDown(object sender, KeyEventArgs e)
|
private void ToolStripMenuItem_English_Click(object sender, EventArgs e)
|
||||||
//{
|
{
|
||||||
// switch (e.KeyCode)
|
LocalizeConfiguration.SetCulture("en-US");
|
||||||
// {
|
DialogResult result = MessageBox.Show(
|
||||||
// case Keys.Space:
|
"The language has been changed. The application needs to restart for changes to take effect.\nDo you want to restart now?",
|
||||||
// if ((ModifierKeys & Keys.Alt) != 0)
|
"Restart Required",
|
||||||
// spinePreviewer.ClickStopButton();
|
MessageBoxButtons.YesNo,
|
||||||
// else
|
MessageBoxIcon.Question
|
||||||
// spinePreviewer.ClickStartButton();
|
);
|
||||||
// break;
|
|
||||||
// case Keys.Right:
|
if (result == DialogResult.Yes)
|
||||||
// if ((ModifierKeys & Keys.Alt) != 0)
|
{
|
||||||
// spinePreviewer.ClickForwardFastButton();
|
Application.Restart(); // Restarts the app
|
||||||
// else
|
Environment.Exit(0); // Ensures the current process ends
|
||||||
// spinePreviewer.ClickForwardStepButton();
|
}
|
||||||
// break;
|
}
|
||||||
// case Keys.Left:
|
|
||||||
// if ((ModifierKeys & Keys.Alt) != 0)
|
private void ToolStripMenuItem_Chinese_Click(object sender, EventArgs e)
|
||||||
// spinePreviewer.ClickRestartButton();
|
{
|
||||||
// break;
|
LocalizeConfiguration.SetCulture();
|
||||||
// }
|
DialogResult result = MessageBox.Show(
|
||||||
//}
|
"The language has been changed. The application needs to restart for changes to take effect.\nDo you want to restart now?",
|
||||||
}
|
"Restart Required",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Question
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
Application.Restart(); // Restarts the app
|
||||||
|
Environment.Exit(0); // Ensures the current process ends
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//private void spinePreviewer_KeyDown(object sender, KeyEventArgs e)
|
||||||
|
//{
|
||||||
|
// switch (e.KeyCode)
|
||||||
|
// {
|
||||||
|
// case Keys.Space:
|
||||||
|
// if ((ModifierKeys & Keys.Alt) != 0)
|
||||||
|
// spinePreviewer.ClickStopButton();
|
||||||
|
// else
|
||||||
|
// spinePreviewer.ClickStartButton();
|
||||||
|
// break;
|
||||||
|
// case Keys.Right:
|
||||||
|
// if ((ModifierKeys & Keys.Alt) != 0)
|
||||||
|
// spinePreviewer.ClickForwardFastButton();
|
||||||
|
// else
|
||||||
|
// spinePreviewer.ClickForwardStepButton();
|
||||||
|
// break;
|
||||||
|
// case Keys.Left:
|
||||||
|
// if ((ModifierKeys & Keys.Alt) != 0)
|
||||||
|
// spinePreviewer.ClickRestartButton();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3400
SpineViewer/Forms/SpineViewerForm.en-AS.resx
Normal file
3400
SpineViewer/Forms/SpineViewerForm.en-AS.resx
Normal file
File diff suppressed because it is too large
Load Diff
3316
SpineViewer/Forms/SpineViewerForm.en.resx
Normal file
3316
SpineViewer/Forms/SpineViewerForm.en.resx
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,8 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using SpineViewer.Utils;
|
using SpineViewer.Utils;
|
||||||
|
using System.Configuration;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace SpineViewer
|
namespace SpineViewer
|
||||||
@@ -44,9 +46,13 @@ namespace SpineViewer
|
|||||||
InitializeLogConfiguration();
|
InitializeLogConfiguration();
|
||||||
logger.Info("Program Started");
|
logger.Info("Program Started");
|
||||||
|
|
||||||
// To customize application configuration such as set high DPI settings or default font,
|
string localize = ConfigurationManager.AppSettings["localize"];
|
||||||
// see https://aka.ms/applicationconfiguration.
|
LocalizeConfiguration.SetCulture(localize);
|
||||||
ApplicationConfiguration.Initialize();
|
logger.Info($"Culture info: {CultureInfo.CurrentCulture}");
|
||||||
|
|
||||||
|
// To customize application configuration such as set high DPI settings or default font,
|
||||||
|
// see https://aka.ms/applicationconfiguration.
|
||||||
|
ApplicationConfiguration.Initialize();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
27
SpineViewer/Utils/LocalizeConfiguration.cs
Normal file
27
SpineViewer/Utils/LocalizeConfiguration.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SpineViewer.Utils
|
||||||
|
{
|
||||||
|
public static class LocalizeConfiguration
|
||||||
|
{
|
||||||
|
|
||||||
|
public static void SetCulture(string cultureName = null)
|
||||||
|
{
|
||||||
|
CultureInfo culture;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(cultureName))
|
||||||
|
culture = CultureInfo.InstalledUICulture;
|
||||||
|
else
|
||||||
|
culture = new CultureInfo(cultureName);
|
||||||
|
|
||||||
|
Thread.CurrentThread.CurrentCulture = culture;
|
||||||
|
Thread.CurrentThread.CurrentUICulture = culture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user