-// ================================================================================================\r
-// <summary>\r
-// Wikipedia翻訳支援ツール主画面クラスソース</summary>\r
-//\r
-// <copyright file="MainForm.cs" company="honeplusのメモ帳">\r
-// Copyright (C) 2011 Honeplus. All rights reserved.</copyright>\r
-// <author>\r
-// Honeplus</author>\r
-// ================================================================================================\r
-\r
-namespace Honememo.Wptscs\r
-{\r
- using System;\r
- using System.Collections.Generic;\r
- using System.ComponentModel;\r
- using System.Data;\r
- using System.Drawing;\r
- using System.IO;\r
- using System.Text;\r
- using System.Windows.Forms;\r
- using Honememo.Utilities;\r
- using Honememo.Wptscs.Logics;\r
- using Honememo.Wptscs.Models;\r
- using Honememo.Wptscs.Properties;\r
-\r
- /// <summary>\r
- /// Wikipedia翻訳支援ツール主画面のクラスです。\r
- /// </summary>\r
- public partial class MainForm : Form\r
- {\r
- #region private変数\r
-\r
- /// <summary>\r
- /// 現在読み込んでいるアプリケーションの設定。\r
- /// </summary>\r
- private Config config;\r
-\r
- /// <summary>\r
- /// 検索支援処理クラスのオブジェクト。\r
- /// </summary>\r
- private Translator translate;\r
-\r
- /// <summary>\r
- /// 表示済みログ文字列長。\r
- /// </summary>\r
- private int logLastLength;\r
-\r
- #endregion\r
-\r
- #region コンストラクタ\r
-\r
- /// <summary>\r
- /// コンストラクタ。初期化メソッド呼び出しのみ。\r
- /// </summary>\r
- public MainForm()\r
- {\r
- // Windows フォーム デザイナで生成されたコード\r
- this.InitializeComponent();\r
- }\r
-\r
- #endregion\r
-\r
- #region 各イベントのメソッド\r
-\r
- /// <summary>\r
- /// フォームロード時の処理。初期化。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void MainForm_Load(object sender, EventArgs e)\r
- {\r
- // 設定ファイルの読み込み\r
- if (!this.LoadConfig())\r
- {\r
- // 読み込み失敗時はどうしようもないのでそのまま終了\r
- this.Close();\r
- }\r
-\r
- this.translate = null;\r
- Control.CheckForIllegalCrossThreadCalls = false;\r
-\r
- // コンボボックス設定\r
- this.Initialize();\r
-\r
- // 前回の処理状態を復元\r
- this.textBoxSaveDirectory.Text = Settings.Default.SaveDirectory;\r
- this.comboBoxSource.SelectedText = Settings.Default.LastSelectedSource;\r
- this.comboBoxTarget.SelectedText = Settings.Default.LastSelectedTarget;\r
-\r
- // コンボボックス変更時の処理をコール\r
- this.ComboBoxSource_SelectedIndexChanged(sender, e);\r
- this.ComboBoxTarget_SelectedIndexChanged(sender, e);\r
- }\r
-\r
- /// <summary>\r
- /// フォームクローズ時の処理。処理状態を保存。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void MainForm_FormClosed(object sender, FormClosedEventArgs e)\r
- {\r
- // 現在の作業フォルダ、絞込み文字列を保存\r
- Settings.Default.SaveDirectory = this.textBoxSaveDirectory.Text;\r
- Settings.Default.LastSelectedSource = this.comboBoxSource.Text;\r
- Settings.Default.LastSelectedTarget = this.comboBoxTarget.Text;\r
- Settings.Default.Save();\r
- }\r
-\r
- /// <summary>\r
- /// 翻訳元コンボボックス変更時の処理。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void ComboBoxSource_SelectedIndexChanged(object sender, EventArgs e)\r
- {\r
- // ラベルに言語名を表示する\r
- this.labelSource.Text = String.Empty;\r
- this.linkLabelSourceURL.Text = "http://";\r
- if (!String.IsNullOrWhiteSpace(this.comboBoxSource.Text))\r
- {\r
- this.comboBoxSource.Text = this.comboBoxSource.Text.Trim().ToLower();\r
-\r
- // その言語の、ユーザーが使用している言語での表示名を表示\r
- // (日本語環境だったら日本語を、英語だったら英語を)\r
- Language.LanguageName name;\r
- this.labelSource.Text = String.Empty;\r
- if (this.config.GetWebsite(this.comboBoxSource.Text) != null &&\r
- this.config.GetWebsite(this.comboBoxSource.Text).Language.Names.TryGetValue(\r
- System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName,\r
- out name))\r
- {\r
- this.labelSource.Text = name.Name;\r
- }\r
-\r
- // サーバーURLの表示\r
- this.linkLabelSourceURL.Text = this.config.GetWebsite(\r
- this.comboBoxSource.Text).Location;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// 翻訳元コンボボックスフォーカス喪失時の処理。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void ComboBoxSource_Leave(object sender, EventArgs e)\r
- {\r
- // 直接入力された場合の対策、変更時の処理をコール\r
- this.ComboBoxSource_SelectedIndexChanged(sender, e);\r
- }\r
-\r
- /// <summary>\r
- /// リンクラベルのリンククリック時の処理。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void LinkLabelSourceURL_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\r
- {\r
- // リンクを開く\r
- System.Diagnostics.Process.Start(((LinkLabel)sender).Text);\r
- }\r
-\r
- /// <summary>\r
- /// 翻訳先コンボボックス変更時の処理。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void ComboBoxTarget_SelectedIndexChanged(object sender, EventArgs e)\r
- {\r
- // ラベルに言語名を表示する\r
- this.labelTarget.Text = String.Empty;\r
- if (!String.IsNullOrWhiteSpace(this.comboBoxTarget.Text))\r
- {\r
- this.comboBoxTarget.Text = this.comboBoxTarget.Text.Trim().ToLower();\r
-\r
- // その言語の、ユーザーが使用している言語での表示名を表示\r
- // (日本語環境だったら日本語を、英語だったら英語を)\r
- if (this.config.GetWebsite(\r
- this.comboBoxTarget.Text) != null)\r
- {\r
- this.labelTarget.Text = this.config.GetWebsite(\r
- this.comboBoxTarget.Text).Language.Names[System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName].Name;\r
- }\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// 翻訳先コンボボックスフォーカス喪失時の処理。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void ComboBoxTarget_Leave(object sender, EventArgs e)\r
- {\r
- // 直接入力された場合の対策、変更時の処理をコール\r
- this.ComboBoxTarget_SelectedIndexChanged(sender, e);\r
- }\r
-\r
- /// <summary>\r
- /// 設定ボタン押下時の処理。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void ButtonConfig_Click(object sender, EventArgs e)\r
- {\r
- // 設定画面を開く\r
- ConfigForm form = new ConfigForm(this.config);\r
- form.ShowDialog();\r
-\r
- // 戻ってきたら設定ファイルを再読み込み\r
- // ※ 万が一エラーでもとりあえず続行\r
- this.LoadConfig();\r
-\r
- // コンボボックス設定\r
- string backupSourceSelected = this.comboBoxSource.SelectedText;\r
- string backupSourceTarget = this.comboBoxTarget.SelectedText;\r
- this.Initialize();\r
- this.comboBoxSource.SelectedText = backupSourceSelected;\r
- this.comboBoxTarget.SelectedText = backupSourceTarget;\r
-\r
- // コンボボックス変更時の処理をコール\r
- this.ComboBoxSource_SelectedIndexChanged(sender, e);\r
- this.ComboBoxTarget_SelectedIndexChanged(sender, e);\r
- }\r
-\r
- /// <summary>\r
- /// 参照ボタン押下時の処理。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void ButtonSaveDirectory_Click(object sender, EventArgs e)\r
- {\r
- // フォルダ名が入力されている場合、それを初期位置に設定\r
- if (!String.IsNullOrEmpty(this.textBoxSaveDirectory.Text))\r
- {\r
- this.folderBrowserDialogSaveDirectory.SelectedPath = this.textBoxSaveDirectory.Text;\r
- }\r
-\r
- // フォルダ選択画面をオープン\r
- if (this.folderBrowserDialogSaveDirectory.ShowDialog() == System.Windows.Forms.DialogResult.OK)\r
- {\r
- // フォルダが選択された場合、フォルダ名に選択されたフォルダを設定\r
- this.textBoxSaveDirectory.Text = this.folderBrowserDialogSaveDirectory.SelectedPath;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// 出力先テキストボックスフォーカス喪失時の処理。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void TextBoxSaveDirectory_Leave(object sender, EventArgs e)\r
- {\r
- // 空白を削除\r
- this.textBoxSaveDirectory.Text = this.textBoxSaveDirectory.Text.Trim();\r
- }\r
-\r
- /// <summary>\r
- /// 実行ボタン押下時の処理。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void ButtonRun_Click(object sender, EventArgs e)\r
- {\r
- // フォーム入力値をチェック\r
- if (String.IsNullOrWhiteSpace(this.comboBoxSource.Text))\r
- {\r
- FormUtils.WarningDialog(Resources.WarningMessageNotSelectedSource);\r
- this.comboBoxSource.Focus();\r
- return;\r
- }\r
- else if (String.IsNullOrWhiteSpace(this.comboBoxTarget.Text))\r
- {\r
- FormUtils.WarningDialog(Resources.WarningMessageNotSelectedTarget);\r
- this.comboBoxTarget.Focus();\r
- return;\r
- }\r
- else if (!String.IsNullOrWhiteSpace(this.comboBoxSource.Text)\r
- && this.comboBoxSource.Text == this.comboBoxTarget.Text)\r
- {\r
- FormUtils.WarningDialog(Resources.WarningMessageEqualsSourceAndTarget);\r
- this.comboBoxTarget.Focus();\r
- return;\r
- }\r
- else if (String.IsNullOrWhiteSpace(this.textBoxSaveDirectory.Text))\r
- {\r
- FormUtils.WarningDialog(Resources.WarningMessageEmptySaveDirectory);\r
- this.textBoxSaveDirectory.Focus();\r
- return;\r
- }\r
- else if (!Directory.Exists(this.textBoxSaveDirectory.Text))\r
- {\r
- FormUtils.WarningDialog(Resources.WarningMessageIgnoreSaveDirectory);\r
- this.textBoxSaveDirectory.Focus();\r
- return;\r
- }\r
- else if (String.IsNullOrWhiteSpace(this.textBoxArticle.Text))\r
- {\r
- FormUtils.WarningDialog(Resources.WarningMessageEmptyArticle);\r
- this.textBoxArticle.Focus();\r
- return;\r
- }\r
-\r
- // 画面をロック\r
- this.LockOperation();\r
-\r
- // バックグラウンド処理を実行\r
- this.backgroundWorkerRun.RunWorkerAsync();\r
- }\r
-\r
- /// <summary>\r
- /// 中止ボタン押下時の処理。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void ButtonStop_Click(object sender, EventArgs e)\r
- {\r
- // 処理を中断\r
- this.buttonStop.Enabled = false;\r
- if (this.backgroundWorkerRun.IsBusy == true)\r
- {\r
- System.Diagnostics.Debug.WriteLine("MainForm.-Stop_Click > 処理中断");\r
- this.backgroundWorkerRun.CancelAsync();\r
- if (this.translate != null)\r
- {\r
- this.translate.CancellationPending = true;\r
- }\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// 実行ボタン バックグラウンド処理(スレッド)。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void BackgroundWorkerRun_DoWork(object sender, DoWorkEventArgs e)\r
- {\r
- try\r
- {\r
- // 翻訳支援処理の前処理\r
- this.textBoxLog.Clear();\r
- this.logLastLength = 0;\r
- this.textBoxLog.AppendText(\r
- String.Format(\r
- Resources.LogMessage_Start,\r
- FormUtils.ApplicationName(),\r
- DateTime.Now.ToString("F")));\r
-\r
- // 処理結果とログのための出力ファイル名を作成\r
- string fileName;\r
- string logName;\r
- this.MakeFileName(out fileName, out logName, this.textBoxArticle.Text.Trim(), this.textBoxSaveDirectory.Text);\r
-\r
- // 翻訳支援処理を実行し、結果とログをファイルに出力\r
- try\r
- {\r
- this.translate = Translator.Create(this.config, this.comboBoxSource.Text, this.comboBoxTarget.Text);\r
- }\r
- catch (NotImplementedException)\r
- {\r
- // 将来の拡張用\r
- this.textBoxLog.AppendText(String.Format(Resources.InformationMessage_DevelopingMethod, "Wikipedia以外の処理"));\r
- FormUtils.InformationDialog(Resources.InformationMessage_DevelopingMethod, "Wikipedia以外の処理");\r
- return;\r
- }\r
-\r
- this.translate.LogUpdate += new EventHandler(this.GetLogUpdate);\r
-\r
- // 実行前に、ユーザーから中止要求がされているかをチェック\r
- if (this.backgroundWorkerRun.CancellationPending)\r
- {\r
- this.textBoxLog.AppendText(String.Format(Resources.LogMessage_Stop, logName));\r
- }\r
- else\r
- {\r
- // 翻訳支援処理を実行\r
- bool successFlag = this.translate.Run(this.textBoxArticle.Text.Trim());\r
-\r
- // 処理に時間がかかるため、出力ファイル名を再確認\r
- this.MakeFileName(out fileName, out logName, this.textBoxArticle.Text.Trim(), this.textBoxSaveDirectory.Text);\r
- if (successFlag)\r
- {\r
- // 処理結果を出力\r
- try\r
- {\r
- StreamWriter sw = new StreamWriter(Path.Combine(this.textBoxSaveDirectory.Text, fileName));\r
- try\r
- {\r
- sw.Write(this.translate.Text);\r
- this.textBoxLog.AppendText(String.Format(Resources.LogMessage_End, fileName, logName));\r
- }\r
- finally\r
- {\r
- sw.Close();\r
- }\r
- }\r
- catch (Exception ex)\r
- {\r
- this.textBoxLog.AppendText(String.Format(Resources.LogMessage_ErrorFileSave, Path.Combine(this.textBoxSaveDirectory.Text, fileName), ex.Message));\r
- this.textBoxLog.AppendText(String.Format(Resources.LogMessage_Stop, logName));\r
- }\r
- }\r
- else\r
- {\r
- this.textBoxLog.AppendText(String.Format(Resources.LogMessage_Stop, logName));\r
- }\r
- }\r
-\r
- // ログを出力\r
- try\r
- {\r
- StreamWriter sw = new StreamWriter(Path.Combine(this.textBoxSaveDirectory.Text, logName));\r
- try\r
- {\r
- sw.Write(this.textBoxLog.Text);\r
- }\r
- finally\r
- {\r
- sw.Close();\r
- }\r
- }\r
- catch (Exception ex)\r
- {\r
- this.textBoxLog.AppendText(String.Format(Resources.LogMessage_ErrorFileSave, Path.Combine(this.textBoxSaveDirectory.Text, logName), ex.Message));\r
- }\r
- }\r
- catch (Exception ex)\r
- {\r
- this.textBoxLog.AppendText("\r\n" + String.Format(Resources.ErrorMessageDevelopmentError, ex.Message, ex.StackTrace) + "\r\n");\r
- System.Diagnostics.Debug.WriteLine("MainForm.backgroundWorkerRun_DoWork > 想定外のエラー : " + ex.Message);\r
- System.Diagnostics.Debug.WriteLine(ex.StackTrace);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// 実行ボタン バックグラウンド処理(終了時)。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void BackgroundWorkerRun_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)\r
- {\r
- // 設定ファイルのキャッシュ情報を更新\r
- try\r
- {\r
- this.config.Save(Settings.Default.ConfigurationFile);\r
- }\r
- catch (Exception ex)\r
- {\r
- FormUtils.WarningDialog(\r
- Resources.WarningMessageCacheSaveFailed,\r
- ex.Message);\r
- }\r
-\r
- // 画面をロック中から解放\r
- this.Release();\r
- }\r
-\r
- #endregion\r
-\r
- #region それ以外のメソッド\r
-\r
- /// <summary>\r
- /// 画面初期化処理。\r
- /// </summary>\r
- private void Initialize()\r
- {\r
- // コンボボックス設定\r
- this.comboBoxSource.Items.Clear();\r
- this.comboBoxTarget.Items.Clear();\r
-\r
- // 設定ファイルに存在する全言語を選択肢として登録する\r
- foreach (Website site in this.config.Websites)\r
- {\r
- this.comboBoxSource.Items.Add(site.Language.Code);\r
- this.comboBoxTarget.Items.Add(site.Language.Code);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// 設定ファイル読み込み。\r
- /// </summary>\r
- /// <returns>読み込み成功時は<c>true</c>。</returns>\r
- private bool LoadConfig()\r
- {\r
- // 設定ファイルの読み込み\r
- try\r
- {\r
- this.config = Config.GetInstance(Settings.Default.ConfigurationFile);\r
- }\r
- catch (FileNotFoundException ex)\r
- {\r
- // 設定ファイルが見つからない場合\r
- System.Diagnostics.Debug.WriteLine(\r
- "MainForm.LoadConfig > 設定ファイル読み込み失敗 : " + ex.Message);\r
- FormUtils.ErrorDialog(\r
- Resources.ErrorMessageConfigNotFound,\r
- Settings.Default.ConfigurationFile);\r
-\r
- return false;\r
- }\r
- catch (Exception ex)\r
- {\r
- System.Diagnostics.Debug.WriteLine(\r
- "MainForm.LoadConfig > 設定ファイル読み込み時エラー : " + ex.StackTrace);\r
- FormUtils.ErrorDialog(\r
- Resources.ErrorMessageConfigLordFailed,\r
- ex.Message);\r
-\r
- return false;\r
- }\r
-\r
- return true;\r
- }\r
-\r
- /// <summary>\r
- /// 画面をロック中に移行。\r
- /// </summary>\r
- private void LockOperation()\r
- {\r
- // 各種ボタンなどを入力不可に変更\r
- this.groupBoxTransfer.Enabled = false;\r
- this.groupBoxSaveDirectory.Enabled = false;\r
- this.textBoxArticle.Enabled = false;\r
- this.buttonRun.Enabled = false;\r
-\r
- // 中止ボタンを有効に変更\r
- this.buttonStop.Enabled = true;\r
- }\r
-\r
- /// <summary>\r
- /// 画面をロック中から解放。\r
- /// </summary>\r
- private void Release()\r
- {\r
- // 中止ボタンを入力不可に変更\r
- this.buttonStop.Enabled = false;\r
-\r
- // 各種ボタンなどを有効に変更\r
- this.groupBoxTransfer.Enabled = true;\r
- this.groupBoxSaveDirectory.Enabled = true;\r
- this.textBoxArticle.Enabled = true;\r
- this.buttonRun.Enabled = true;\r
- }\r
-\r
- /// <summary>\r
- /// 渡された文字列から.txtと.logの重複していないファイル名を作成。\r
- /// </summary>\r
- /// <param name="fileName">出力結果ファイル名。</param>\r
- /// <param name="logName">出力ログファイル名。</param>\r
- /// <param name="text">出力する結果テキスト。</param>\r
- /// <param name="dir">出力先ディレクトリ。</param>\r
- /// <returns><c>true</c> 出力成功</returns>\r
- private bool MakeFileName(out string fileName, out string logName, string text, string dir)\r
- {\r
- // 出力先フォルダに存在しないファイル名(の拡張子より前)を作成\r
- // ※渡されたWikipedia等の記事名にファイル名に使えない文字が含まれている場合、_ に置き換える\r
- // また、ファイル名が重複している場合、xx[0].txtのように連番を付ける\r
- string fileNameBase = FormUtils.ReplaceInvalidFileNameChars(text);\r
- fileName = fileNameBase + ".txt";\r
- logName = fileNameBase + ".log";\r
- bool success = false;\r
- for (int i = 0; i < 100000; i++)\r
- {\r
- // ※100000まで試して空きが見つからないことは無いはず、もし見つからなかったら最後のを上書き\r
- if (!File.Exists(Path.Combine(dir, fileName))\r
- && !File.Exists(Path.Combine(dir, logName)))\r
- {\r
- success = true;\r
- break;\r
- }\r
-\r
- fileName = fileNameBase + "[" + i + "]" + ".txt";\r
- logName = fileNameBase + "[" + i + "]" + ".log";\r
- }\r
-\r
- // 結果設定\r
- return success;\r
- }\r
-\r
- /// <summary>\r
- /// 翻訳支援処理クラスのイベント用。\r
- /// </summary>\r
- /// <param name="sender">イベント発生オブジェクト。</param>\r
- /// <param name="e">発生したイベント。</param>\r
- private void GetLogUpdate(object sender, System.EventArgs e)\r
- {\r
- // 前回以降に追加されたログをテキストボックスに出力\r
- int length = this.translate.Log.Length;\r
- if (length > this.logLastLength)\r
- {\r
- this.textBoxLog.AppendText(this.translate.Log.Substring(this.logLastLength, length - this.logLastLength));\r
- }\r
-\r
- this.logLastLength = length;\r
- }\r
-\r
- #endregion\r
- }\r
+// ================================================================================================
+// <summary>
+// Wikipedia翻訳支援ツール主画面クラスソース</summary>
+//
+// <copyright file="MainForm.cs" company="honeplusのメモ帳">
+// Copyright (C) 2011 Honeplus. All rights reserved.</copyright>
+// <author>
+// Honeplus</author>
+// ================================================================================================
+
+namespace Honememo.Wptscs
+{
+ using System;
+ using System.Collections.Generic;
+ using System.ComponentModel;
+ using System.Data;
+ using System.Drawing;
+ using System.IO;
+ using System.Text;
+ using System.Windows.Forms;
+ using Honememo.Utilities;
+ using Honememo.Wptscs.Logics;
+ using Honememo.Wptscs.Models;
+ using Honememo.Wptscs.Properties;
+
+ /// <summary>
+ /// Wikipedia翻訳支援ツール主画面のクラスです。
+ /// </summary>
+ public partial class MainForm : Form
+ {
+ #region private変数
+
+ /// <summary>
+ /// 現在読み込んでいるアプリケーションの設定。
+ /// </summary>
+ private Config config;
+
+ /// <summary>
+ /// 検索支援処理クラスのオブジェクト。
+ /// </summary>
+ private Translator translate;
+
+ /// <summary>
+ /// 表示済みログ文字列長。
+ /// </summary>
+ private int logLastLength;
+
+ #endregion
+
+ #region コンストラクタ
+
+ /// <summary>
+ /// コンストラクタ。初期化メソッド呼び出しのみ。
+ /// </summary>
+ public MainForm()
+ {
+ // Windows フォーム デザイナで生成されたコード
+ this.InitializeComponent();
+ }
+
+ #endregion
+
+ #region 各イベントのメソッド
+
+ /// <summary>
+ /// フォームロード時の処理。初期化。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void MainForm_Load(object sender, EventArgs e)
+ {
+ // 設定ファイルの読み込み
+ if (!this.LoadConfig())
+ {
+ // 読み込み失敗時はどうしようもないのでそのまま終了
+ this.Close();
+ }
+
+ this.translate = null;
+ Control.CheckForIllegalCrossThreadCalls = false;
+
+ // コンボボックス設定
+ this.Initialize();
+
+ // 前回の処理状態を復元
+ this.textBoxSaveDirectory.Text = Settings.Default.SaveDirectory;
+ this.comboBoxSource.SelectedText = Settings.Default.LastSelectedSource;
+ this.comboBoxTarget.SelectedText = Settings.Default.LastSelectedTarget;
+
+ // コンボボックス変更時の処理をコール
+ this.ComboBoxSource_SelectedIndexChanged(sender, e);
+ this.ComboBoxTarget_SelectedIndexChanged(sender, e);
+ }
+
+ /// <summary>
+ /// フォームクローズ時の処理。処理状態を保存。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
+ {
+ // 現在の作業フォルダ、絞込み文字列を保存
+ Settings.Default.SaveDirectory = this.textBoxSaveDirectory.Text;
+ Settings.Default.LastSelectedSource = this.comboBoxSource.Text;
+ Settings.Default.LastSelectedTarget = this.comboBoxTarget.Text;
+ Settings.Default.Save();
+ }
+
+ /// <summary>
+ /// 翻訳元コンボボックス変更時の処理。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void ComboBoxSource_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ // ラベルに言語名を表示する
+ this.labelSource.Text = String.Empty;
+ this.linkLabelSourceURL.Text = "http://";
+ if (!String.IsNullOrWhiteSpace(this.comboBoxSource.Text))
+ {
+ this.comboBoxSource.Text = this.comboBoxSource.Text.Trim().ToLower();
+
+ // その言語の、ユーザーが使用している言語での表示名を表示
+ // (日本語環境だったら日本語を、英語だったら英語を)
+ Language.LanguageName name;
+ this.labelSource.Text = String.Empty;
+ if (this.config.GetWebsite(this.comboBoxSource.Text) != null &&
+ this.config.GetWebsite(this.comboBoxSource.Text).Language.Names.TryGetValue(
+ System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName,
+ out name))
+ {
+ this.labelSource.Text = name.Name;
+ }
+
+ // サーバーURLの表示
+ this.linkLabelSourceURL.Text = this.config.GetWebsite(
+ this.comboBoxSource.Text).Location;
+ }
+ }
+
+ /// <summary>
+ /// 翻訳元コンボボックスフォーカス喪失時の処理。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void ComboBoxSource_Leave(object sender, EventArgs e)
+ {
+ // 直接入力された場合の対策、変更時の処理をコール
+ this.ComboBoxSource_SelectedIndexChanged(sender, e);
+ }
+
+ /// <summary>
+ /// リンクラベルのリンククリック時の処理。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void LinkLabelSourceURL_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ // リンクを開く
+ System.Diagnostics.Process.Start(((LinkLabel)sender).Text);
+ }
+
+ /// <summary>
+ /// 翻訳先コンボボックス変更時の処理。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void ComboBoxTarget_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ // ラベルに言語名を表示する
+ this.labelTarget.Text = String.Empty;
+ if (!String.IsNullOrWhiteSpace(this.comboBoxTarget.Text))
+ {
+ this.comboBoxTarget.Text = this.comboBoxTarget.Text.Trim().ToLower();
+
+ // その言語の、ユーザーが使用している言語での表示名を表示
+ // (日本語環境だったら日本語を、英語だったら英語を)
+ if (this.config.GetWebsite(
+ this.comboBoxTarget.Text) != null)
+ {
+ this.labelTarget.Text = this.config.GetWebsite(
+ this.comboBoxTarget.Text).Language.Names[System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName].Name;
+ }
+ }
+ }
+
+ /// <summary>
+ /// 翻訳先コンボボックスフォーカス喪失時の処理。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void ComboBoxTarget_Leave(object sender, EventArgs e)
+ {
+ // 直接入力された場合の対策、変更時の処理をコール
+ this.ComboBoxTarget_SelectedIndexChanged(sender, e);
+ }
+
+ /// <summary>
+ /// 設定ボタン押下時の処理。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void ButtonConfig_Click(object sender, EventArgs e)
+ {
+ // 設定画面を開く
+ ConfigForm form = new ConfigForm(this.config);
+ form.ShowDialog();
+
+ // 戻ってきたら設定ファイルを再読み込み
+ // ※ 万が一エラーでもとりあえず続行
+ this.LoadConfig();
+
+ // コンボボックス設定
+ string backupSourceSelected = this.comboBoxSource.SelectedText;
+ string backupSourceTarget = this.comboBoxTarget.SelectedText;
+ this.Initialize();
+ this.comboBoxSource.SelectedText = backupSourceSelected;
+ this.comboBoxTarget.SelectedText = backupSourceTarget;
+
+ // コンボボックス変更時の処理をコール
+ this.ComboBoxSource_SelectedIndexChanged(sender, e);
+ this.ComboBoxTarget_SelectedIndexChanged(sender, e);
+ }
+
+ /// <summary>
+ /// 参照ボタン押下時の処理。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void ButtonSaveDirectory_Click(object sender, EventArgs e)
+ {
+ // フォルダ名が入力されている場合、それを初期位置に設定
+ if (!String.IsNullOrEmpty(this.textBoxSaveDirectory.Text))
+ {
+ this.folderBrowserDialogSaveDirectory.SelectedPath = this.textBoxSaveDirectory.Text;
+ }
+
+ // フォルダ選択画面をオープン
+ if (this.folderBrowserDialogSaveDirectory.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+ {
+ // フォルダが選択された場合、フォルダ名に選択されたフォルダを設定
+ this.textBoxSaveDirectory.Text = this.folderBrowserDialogSaveDirectory.SelectedPath;
+ }
+ }
+
+ /// <summary>
+ /// 出力先テキストボックスフォーカス喪失時の処理。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void TextBoxSaveDirectory_Leave(object sender, EventArgs e)
+ {
+ // 空白を削除
+ this.textBoxSaveDirectory.Text = this.textBoxSaveDirectory.Text.Trim();
+ }
+
+ /// <summary>
+ /// 実行ボタン押下時の処理。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void ButtonRun_Click(object sender, EventArgs e)
+ {
+ // フォーム入力値をチェック
+ if (String.IsNullOrWhiteSpace(this.comboBoxSource.Text))
+ {
+ FormUtils.WarningDialog(Resources.WarningMessageNotSelectedSource);
+ this.comboBoxSource.Focus();
+ return;
+ }
+ else if (String.IsNullOrWhiteSpace(this.comboBoxTarget.Text))
+ {
+ FormUtils.WarningDialog(Resources.WarningMessageNotSelectedTarget);
+ this.comboBoxTarget.Focus();
+ return;
+ }
+ else if (!String.IsNullOrWhiteSpace(this.comboBoxSource.Text)
+ && this.comboBoxSource.Text == this.comboBoxTarget.Text)
+ {
+ FormUtils.WarningDialog(Resources.WarningMessageEqualsSourceAndTarget);
+ this.comboBoxTarget.Focus();
+ return;
+ }
+ else if (String.IsNullOrWhiteSpace(this.textBoxSaveDirectory.Text))
+ {
+ FormUtils.WarningDialog(Resources.WarningMessageEmptySaveDirectory);
+ this.textBoxSaveDirectory.Focus();
+ return;
+ }
+ else if (!Directory.Exists(this.textBoxSaveDirectory.Text))
+ {
+ FormUtils.WarningDialog(Resources.WarningMessageIgnoreSaveDirectory);
+ this.textBoxSaveDirectory.Focus();
+ return;
+ }
+ else if (String.IsNullOrWhiteSpace(this.textBoxArticle.Text))
+ {
+ FormUtils.WarningDialog(Resources.WarningMessageEmptyArticle);
+ this.textBoxArticle.Focus();
+ return;
+ }
+
+ // 画面をロック
+ this.LockOperation();
+
+ // バックグラウンド処理を実行
+ this.backgroundWorkerRun.RunWorkerAsync();
+ }
+
+ /// <summary>
+ /// 中止ボタン押下時の処理。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void ButtonStop_Click(object sender, EventArgs e)
+ {
+ // 処理を中断
+ this.buttonStop.Enabled = false;
+ if (this.backgroundWorkerRun.IsBusy == true)
+ {
+ System.Diagnostics.Debug.WriteLine("MainForm.-Stop_Click > 処理中断");
+ this.backgroundWorkerRun.CancelAsync();
+ if (this.translate != null)
+ {
+ this.translate.CancellationPending = true;
+ }
+ }
+ }
+
+ /// <summary>
+ /// 実行ボタン バックグラウンド処理(スレッド)。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void BackgroundWorkerRun_DoWork(object sender, DoWorkEventArgs e)
+ {
+ try
+ {
+ // 翻訳支援処理の前処理
+ this.textBoxLog.Clear();
+ this.logLastLength = 0;
+ this.textBoxLog.AppendText(
+ String.Format(
+ Resources.LogMessage_Start,
+ FormUtils.ApplicationName(),
+ DateTime.Now.ToString("F")));
+
+ // 処理結果とログのための出力ファイル名を作成
+ string fileName;
+ string logName;
+ this.MakeFileName(out fileName, out logName, this.textBoxArticle.Text.Trim(), this.textBoxSaveDirectory.Text);
+
+ // 翻訳支援処理を実行し、結果とログをファイルに出力
+ try
+ {
+ this.translate = Translator.Create(this.config, this.comboBoxSource.Text, this.comboBoxTarget.Text);
+ }
+ catch (NotImplementedException)
+ {
+ // 将来の拡張用
+ this.textBoxLog.AppendText(String.Format(Resources.InformationMessage_DevelopingMethod, "Wikipedia以外の処理"));
+ FormUtils.InformationDialog(Resources.InformationMessage_DevelopingMethod, "Wikipedia以外の処理");
+ return;
+ }
+
+ this.translate.LogUpdate += new EventHandler(this.GetLogUpdate);
+
+ // 実行前に、ユーザーから中止要求がされているかをチェック
+ if (this.backgroundWorkerRun.CancellationPending)
+ {
+ this.textBoxLog.AppendText(String.Format(Resources.LogMessage_Stop, logName));
+ }
+ else
+ {
+ // 翻訳支援処理を実行
+ bool successFlag = this.translate.Run(this.textBoxArticle.Text.Trim());
+
+ // 処理に時間がかかるため、出力ファイル名を再確認
+ this.MakeFileName(out fileName, out logName, this.textBoxArticle.Text.Trim(), this.textBoxSaveDirectory.Text);
+ if (successFlag)
+ {
+ // 処理結果を出力
+ try
+ {
+ StreamWriter sw = new StreamWriter(Path.Combine(this.textBoxSaveDirectory.Text, fileName));
+ try
+ {
+ sw.Write(this.translate.Text);
+ this.textBoxLog.AppendText(String.Format(Resources.LogMessage_End, fileName, logName));
+ }
+ finally
+ {
+ sw.Close();
+ }
+ }
+ catch (Exception ex)
+ {
+ this.textBoxLog.AppendText(String.Format(Resources.LogMessage_ErrorFileSave, Path.Combine(this.textBoxSaveDirectory.Text, fileName), ex.Message));
+ this.textBoxLog.AppendText(String.Format(Resources.LogMessage_Stop, logName));
+ }
+ }
+ else
+ {
+ this.textBoxLog.AppendText(String.Format(Resources.LogMessage_Stop, logName));
+ }
+ }
+
+ // ログを出力
+ try
+ {
+ StreamWriter sw = new StreamWriter(Path.Combine(this.textBoxSaveDirectory.Text, logName));
+ try
+ {
+ sw.Write(this.textBoxLog.Text);
+ }
+ finally
+ {
+ sw.Close();
+ }
+ }
+ catch (Exception ex)
+ {
+ this.textBoxLog.AppendText(String.Format(Resources.LogMessage_ErrorFileSave, Path.Combine(this.textBoxSaveDirectory.Text, logName), ex.Message));
+ }
+ }
+ catch (Exception ex)
+ {
+ this.textBoxLog.AppendText("\r\n" + String.Format(Resources.ErrorMessageDevelopmentError, ex.Message, ex.StackTrace) + "\r\n");
+ System.Diagnostics.Debug.WriteLine("MainForm.backgroundWorkerRun_DoWork > 想定外のエラー : " + ex.Message);
+ System.Diagnostics.Debug.WriteLine(ex.StackTrace);
+ }
+ }
+
+ /// <summary>
+ /// 実行ボタン バックグラウンド処理(終了時)。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void BackgroundWorkerRun_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
+ {
+ // 設定ファイルのキャッシュ情報を更新
+ try
+ {
+ this.config.Save(Settings.Default.ConfigurationFile);
+ }
+ catch (Exception ex)
+ {
+ FormUtils.WarningDialog(
+ Resources.WarningMessageCacheSaveFailed,
+ ex.Message);
+ }
+
+ // 画面をロック中から解放
+ this.Release();
+ }
+
+ #endregion
+
+ #region それ以外のメソッド
+
+ /// <summary>
+ /// 画面初期化処理。
+ /// </summary>
+ private void Initialize()
+ {
+ // コンボボックス設定
+ this.comboBoxSource.Items.Clear();
+ this.comboBoxTarget.Items.Clear();
+
+ // 設定ファイルに存在する全言語を選択肢として登録する
+ foreach (Website site in this.config.Websites)
+ {
+ this.comboBoxSource.Items.Add(site.Language.Code);
+ this.comboBoxTarget.Items.Add(site.Language.Code);
+ }
+ }
+
+ /// <summary>
+ /// 設定ファイル読み込み。
+ /// </summary>
+ /// <returns>読み込み成功時は<c>true</c>。</returns>
+ private bool LoadConfig()
+ {
+ // 設定ファイルの読み込み
+ try
+ {
+ this.config = Config.GetInstance(Settings.Default.ConfigurationFile);
+ }
+ catch (FileNotFoundException ex)
+ {
+ // 設定ファイルが見つからない場合
+ System.Diagnostics.Debug.WriteLine(
+ "MainForm.LoadConfig > 設定ファイル読み込み失敗 : " + ex.Message);
+ FormUtils.ErrorDialog(
+ Resources.ErrorMessageConfigNotFound,
+ Settings.Default.ConfigurationFile);
+
+ return false;
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine(
+ "MainForm.LoadConfig > 設定ファイル読み込み時エラー : " + ex.StackTrace);
+ FormUtils.ErrorDialog(
+ Resources.ErrorMessageConfigLordFailed,
+ ex.Message);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// 画面をロック中に移行。
+ /// </summary>
+ private void LockOperation()
+ {
+ // 各種ボタンなどを入力不可に変更
+ this.groupBoxTransfer.Enabled = false;
+ this.groupBoxSaveDirectory.Enabled = false;
+ this.textBoxArticle.Enabled = false;
+ this.buttonRun.Enabled = false;
+
+ // 中止ボタンを有効に変更
+ this.buttonStop.Enabled = true;
+ }
+
+ /// <summary>
+ /// 画面をロック中から解放。
+ /// </summary>
+ private void Release()
+ {
+ // 中止ボタンを入力不可に変更
+ this.buttonStop.Enabled = false;
+
+ // 各種ボタンなどを有効に変更
+ this.groupBoxTransfer.Enabled = true;
+ this.groupBoxSaveDirectory.Enabled = true;
+ this.textBoxArticle.Enabled = true;
+ this.buttonRun.Enabled = true;
+ }
+
+ /// <summary>
+ /// 渡された文字列から.txtと.logの重複していないファイル名を作成。
+ /// </summary>
+ /// <param name="fileName">出力結果ファイル名。</param>
+ /// <param name="logName">出力ログファイル名。</param>
+ /// <param name="text">出力する結果テキスト。</param>
+ /// <param name="dir">出力先ディレクトリ。</param>
+ /// <returns><c>true</c> 出力成功</returns>
+ private bool MakeFileName(out string fileName, out string logName, string text, string dir)
+ {
+ // 出力先フォルダに存在しないファイル名(の拡張子より前)を作成
+ // ※渡されたWikipedia等の記事名にファイル名に使えない文字が含まれている場合、_ に置き換える
+ // また、ファイル名が重複している場合、xx[0].txtのように連番を付ける
+ string fileNameBase = FormUtils.ReplaceInvalidFileNameChars(text);
+ fileName = fileNameBase + ".txt";
+ logName = fileNameBase + ".log";
+ bool success = false;
+ for (int i = 0; i < 100000; i++)
+ {
+ // ※100000まで試して空きが見つからないことは無いはず、もし見つからなかったら最後のを上書き
+ if (!File.Exists(Path.Combine(dir, fileName))
+ && !File.Exists(Path.Combine(dir, logName)))
+ {
+ success = true;
+ break;
+ }
+
+ fileName = fileNameBase + "[" + i + "]" + ".txt";
+ logName = fileNameBase + "[" + i + "]" + ".log";
+ }
+
+ // 結果設定
+ return success;
+ }
+
+ /// <summary>
+ /// 翻訳支援処理クラスのイベント用。
+ /// </summary>
+ /// <param name="sender">イベント発生オブジェクト。</param>
+ /// <param name="e">発生したイベント。</param>
+ private void GetLogUpdate(object sender, System.EventArgs e)
+ {
+ // 前回以降に追加されたログをテキストボックスに出力
+ int length = this.translate.Log.Length;
+ if (length > this.logLastLength)
+ {
+ this.textBoxLog.AppendText(this.translate.Log.Substring(this.logLastLength, length - this.logLastLength));
+ }
+
+ this.logLastLength = length;
+ }
+
+ #endregion
+ }
}
\ No newline at end of file