OSDN Git Service

#27314 記事名にコロンを含むページが正しく処理できないの対応(MediaWikiのAPIと設定からウィキ間リンクを判別するよう変更),
[wptscs/wpts.git] / Wptscs / MainForm.cs
1 // ================================================================================================
2 // <summary>
3 //      Wikipedia翻訳支援ツール主画面クラスソース</summary>
4 //
5 // <copyright file="MainForm.cs" company="honeplusのメモ帳">
6 //      Copyright (C) 2012 Honeplus. All rights reserved.</copyright>
7 // <author>
8 //      Honeplus</author>
9 // ================================================================================================
10
11 namespace Honememo.Wptscs
12 {
13     using System;
14     using System.Collections.Generic;
15     using System.ComponentModel;
16     using System.Data;
17     using System.Drawing;
18     using System.IO;
19     using System.Net;
20     using System.Text;
21     using System.Windows.Forms;
22     using Honememo.Utilities;
23     using Honememo.Wptscs.Logics;
24     using Honememo.Wptscs.Models;
25     using Honememo.Wptscs.Properties;
26     using Honememo.Wptscs.Utilities;
27     using Honememo.Wptscs.Websites;
28
29     /// <summary>
30     /// Wikipedia翻訳支援ツール主画面のクラスです。
31     /// </summary>
32     public partial class MainForm : Form
33     {
34         #region private変数
35
36         /// <summary>
37         /// 現在読み込んでいるアプリケーションの設定。
38         /// </summary>
39         private Config config;
40
41         /// <summary>
42         /// 検索支援処理クラスのオブジェクト。
43         /// </summary>
44         private Translator translator;
45
46         /// <summary>
47         /// 表示済みログ文字列長。
48         /// </summary>
49         private int logLength;
50
51         #endregion
52
53         #region コンストラクタ
54
55         /// <summary>
56         /// コンストラクタ。初期化メソッド呼び出しのみ。
57         /// </summary>
58         public MainForm()
59         {
60             // Windows フォーム デザイナで生成されたコード
61             this.InitializeComponent();
62         }
63
64         #endregion
65
66         #region 各イベントのメソッド
67
68         /// <summary>
69         /// フォームロード時の処理。初期化。
70         /// </summary>
71         /// <param name="sender">イベント発生オブジェクト。</param>
72         /// <param name="e">発生したイベント。</param>
73         private void MainForm_Load(object sender, EventArgs e)
74         {
75             // 設定ファイルの読み込み
76             if (!this.LoadConfig())
77             {
78                 // 読み込み失敗時はどうしようもないのでそのまま終了
79                 this.Close();
80             }
81
82             this.translator = null;
83             Control.CheckForIllegalCrossThreadCalls = false;
84
85             // コンボボックス設定
86             this.Initialize();
87
88             // 前回の処理状態を復元
89             this.textBoxSaveDirectory.Text = Settings.Default.SaveDirectory;
90             this.comboBoxSource.SelectedItem = Settings.Default.LastSelectedSource;
91             this.comboBoxTarget.SelectedItem = Settings.Default.LastSelectedTarget;
92
93             // コンボボックス変更時の処理をコール
94             this.ComboBoxSource_SelectedIndexChanged(sender, e);
95             this.ComboBoxTarget_SelectedIndexChanged(sender, e);
96         }
97
98         /// <summary>
99         /// フォームクローズ時の処理。処理状態を保存。
100         /// </summary>
101         /// <param name="sender">イベント発生オブジェクト。</param>
102         /// <param name="e">発生したイベント。</param>
103         private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
104         {
105             // 現在の作業フォルダ、絞込み文字列を保存
106             Settings.Default.SaveDirectory = this.textBoxSaveDirectory.Text;
107             Settings.Default.LastSelectedSource = this.comboBoxSource.Text;
108             Settings.Default.LastSelectedTarget = this.comboBoxTarget.Text;
109             Settings.Default.Save();
110         }
111
112         /// <summary>
113         /// 翻訳元コンボボックス変更時の処理。
114         /// </summary>
115         /// <param name="sender">イベント発生オブジェクト。</param>
116         /// <param name="e">発生したイベント。</param>
117         private void ComboBoxSource_SelectedIndexChanged(object sender, EventArgs e)
118         {
119             // ラベルに言語名を表示する
120             this.labelSource.Text = String.Empty;
121             this.linkLabelSourceURL.Text = "http://";
122             if (!String.IsNullOrWhiteSpace(this.comboBoxSource.Text))
123             {
124                 // その言語の、ユーザーが使用している言語での表示名を表示
125                 // (日本語環境だったら日本語を、英語だったら英語を)
126                 Language.LanguageName name;
127                 this.labelSource.Text = String.Empty;
128                 if (this.config.GetWebsite(this.comboBoxSource.Text) != null &&
129                     this.config.GetWebsite(this.comboBoxSource.Text).Language.Names.TryGetValue(
130                     System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName,
131                     out name))
132                 {
133                     this.labelSource.Text = name.Name;
134                 }
135
136                 // サーバーURLの表示
137                 this.linkLabelSourceURL.Text = this.config.GetWebsite(
138                     this.comboBoxSource.Text).Location;
139             }
140         }
141
142         /// <summary>
143         /// 翻訳元コンボボックスフォーカス喪失時の処理。
144         /// </summary>
145         /// <param name="sender">イベント発生オブジェクト。</param>
146         /// <param name="e">発生したイベント。</param>
147         private void ComboBoxSource_Leave(object sender, EventArgs e)
148         {
149             // 直接入力された場合の対策、変更時の処理をコール
150             this.ComboBoxSource_SelectedIndexChanged(sender, e);
151         }
152
153         /// <summary>
154         /// リンクラベルのリンククリック時の処理。
155         /// </summary>
156         /// <param name="sender">イベント発生オブジェクト。</param>
157         /// <param name="e">発生したイベント。</param>
158         private void LinkLabelSourceURL_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
159         {
160             // リンクを開く
161             System.Diagnostics.Process.Start(((LinkLabel)sender).Text);
162         }
163
164         /// <summary>
165         /// 翻訳先コンボボックス変更時の処理。
166         /// </summary>
167         /// <param name="sender">イベント発生オブジェクト。</param>
168         /// <param name="e">発生したイベント。</param>
169         private void ComboBoxTarget_SelectedIndexChanged(object sender, EventArgs e)
170         {
171             // ラベルに言語名を表示する
172             this.labelTarget.Text = String.Empty;
173             if (!String.IsNullOrWhiteSpace(this.comboBoxTarget.Text))
174             {
175                 this.comboBoxTarget.Text = this.comboBoxTarget.Text.Trim().ToLower();
176
177                 // その言語の、ユーザーが使用している言語での表示名を表示
178                 // (日本語環境だったら日本語を、英語だったら英語を)
179                 if (this.config.GetWebsite(this.comboBoxTarget.Text) != null)
180                 {
181                     this.labelTarget.Text = this.config.GetWebsite(
182                         this.comboBoxTarget.Text).Language.Names[System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName].Name;
183                 }
184             }
185         }
186
187         /// <summary>
188         /// 翻訳先コンボボックスフォーカス喪失時の処理。
189         /// </summary>
190         /// <param name="sender">イベント発生オブジェクト。</param>
191         /// <param name="e">発生したイベント。</param>
192         private void ComboBoxTarget_Leave(object sender, EventArgs e)
193         {
194             // 直接入力された場合の対策、変更時の処理をコール
195             this.ComboBoxTarget_SelectedIndexChanged(sender, e);
196         }
197
198         /// <summary>
199         /// 設定ボタン押下時の処理。
200         /// </summary>
201         /// <param name="sender">イベント発生オブジェクト。</param>
202         /// <param name="e">発生したイベント。</param>
203         private void ButtonConfig_Click(object sender, EventArgs e)
204         {
205             // 設定画面を開く
206             ConfigForm form = new ConfigForm(this.config);
207             form.ShowDialog();
208
209             // 戻ってきたら設定ファイルを再読み込み
210             // ※ キャンセル時もインスタンスは更新されてしまうので
211             this.LoadConfig();
212
213             // コンボボックス設定
214             string backupSourceSelected = this.comboBoxSource.Text;
215             string backupSourceTarget = this.comboBoxTarget.Text;
216             this.Initialize();
217             this.comboBoxSource.SelectedItem = backupSourceSelected;
218             this.comboBoxTarget.SelectedItem = backupSourceTarget;
219
220             // コンボボックス変更時の処理をコール
221             this.ComboBoxSource_SelectedIndexChanged(sender, e);
222             this.ComboBoxTarget_SelectedIndexChanged(sender, e);
223         }
224
225         /// <summary>
226         /// 参照ボタン押下時の処理。
227         /// </summary>
228         /// <param name="sender">イベント発生オブジェクト。</param>
229         /// <param name="e">発生したイベント。</param>
230         private void ButtonSaveDirectory_Click(object sender, EventArgs e)
231         {
232             // フォルダ名が入力されている場合、それを初期位置に設定
233             if (!String.IsNullOrEmpty(this.textBoxSaveDirectory.Text))
234             {
235                 this.folderBrowserDialogSaveDirectory.SelectedPath = this.textBoxSaveDirectory.Text;
236             }
237
238             // フォルダ選択画面をオープン
239             if (this.folderBrowserDialogSaveDirectory.ShowDialog() == System.Windows.Forms.DialogResult.OK)
240             {
241                 // フォルダが選択された場合、フォルダ名に選択されたフォルダを設定
242                 this.textBoxSaveDirectory.Text = this.folderBrowserDialogSaveDirectory.SelectedPath;
243             }
244         }
245
246         /// <summary>
247         /// 出力先テキストボックスフォーカス喪失時の処理。
248         /// </summary>
249         /// <param name="sender">イベント発生オブジェクト。</param>
250         /// <param name="e">発生したイベント。</param>
251         private void TextBoxSaveDirectory_Leave(object sender, EventArgs e)
252         {
253             // 空白を削除
254             this.textBoxSaveDirectory.Text = this.textBoxSaveDirectory.Text.Trim();
255         }
256
257         /// <summary>
258         /// 実行ボタン押下時の処理。
259         /// </summary>
260         /// <param name="sender">イベント発生オブジェクト。</param>
261         /// <param name="e">発生したイベント。</param>
262         private void ButtonRun_Click(object sender, EventArgs e)
263         {
264             // フォーム入力値をチェック
265             if (String.IsNullOrWhiteSpace(this.comboBoxSource.Text))
266             {
267                 FormUtils.WarningDialog(Resources.WarningMessageNotSelectedSource);
268                 this.comboBoxSource.Focus();
269                 return;
270             }
271             else if (String.IsNullOrWhiteSpace(this.comboBoxTarget.Text))
272             {
273                 FormUtils.WarningDialog(Resources.WarningMessageNotSelectedTarget);
274                 this.comboBoxTarget.Focus();
275                 return;
276             }
277             else if (!String.IsNullOrWhiteSpace(this.comboBoxSource.Text)
278                 && this.comboBoxSource.Text == this.comboBoxTarget.Text)
279             {
280                 FormUtils.WarningDialog(Resources.WarningMessageEqualsSourceAndTarget);
281                 this.comboBoxTarget.Focus();
282                 return;
283             }
284             else if (String.IsNullOrWhiteSpace(this.textBoxSaveDirectory.Text))
285             {
286                 FormUtils.WarningDialog(Resources.WarningMessageEmptySaveDirectory);
287                 this.textBoxSaveDirectory.Focus();
288                 return;
289             }
290             else if (!Directory.Exists(this.textBoxSaveDirectory.Text))
291             {
292                 FormUtils.WarningDialog(Resources.WarningMessageIgnoreSaveDirectory);
293                 this.textBoxSaveDirectory.Focus();
294                 return;
295             }
296             else if (String.IsNullOrWhiteSpace(this.textBoxArticle.Text))
297             {
298                 FormUtils.WarningDialog(Resources.WarningMessageEmptyArticle);
299                 this.textBoxArticle.Focus();
300                 return;
301             }
302
303             // 画面をロック
304             this.LockOperation();
305
306             // バックグラウンド処理を実行
307             this.backgroundWorkerRun.RunWorkerAsync();
308         }
309
310         /// <summary>
311         /// 中止ボタン押下時の処理。
312         /// </summary>
313         /// <param name="sender">イベント発生オブジェクト。</param>
314         /// <param name="e">発生したイベント。</param>
315         private void ButtonStop_Click(object sender, EventArgs e)
316         {
317             // 処理を中断
318             this.buttonStop.Enabled = false;
319             if (this.backgroundWorkerRun.IsBusy == true)
320             {
321                 System.Diagnostics.Debug.WriteLine("MainForm.-Stop_Click > 処理中断");
322                 this.backgroundWorkerRun.CancelAsync();
323                 if (this.translator != null)
324                 {
325                     this.translator.CancellationPending = true;
326                 }
327             }
328         }
329
330         /// <summary>
331         /// 実行ボタン バックグラウンド処理(スレッド)。
332         /// </summary>
333         /// <param name="sender">イベント発生オブジェクト。</param>
334         /// <param name="e">発生したイベント。</param>
335         private void BackgroundWorkerRun_DoWork(object sender, DoWorkEventArgs e)
336         {
337             try
338             {
339                 // 初期化と開始メッセージ
340                 this.textBoxLog.Clear();
341                 this.logLength = 0;
342                 this.textBoxLog.AppendText(String.Format(Resources.LogMessageStart, FormUtils.ApplicationName(), DateTime.Now.ToString("F")));
343
344                 // 翻訳支援処理ロジックのオブジェクトを生成
345                 try
346                 {
347                     this.translator = Translator.Create(this.config, this.comboBoxSource.Text, this.comboBoxTarget.Text);
348                 }
349                 catch (NotImplementedException)
350                 {
351                     // 設定ファイルに対応していないパターンが書かれている場合の例外、将来の拡張用
352                     this.textBoxLog.AppendText(String.Format(Resources.InformationMessageDevelopingMethod, "MediaWiki以外の処理"));
353                     FormUtils.InformationDialog(Resources.InformationMessageDevelopingMethod, "MediaWiki以外の処理");
354                     return;
355                 }
356
357                 // ログ・処理状態更新通知を受け取るためのイベント登録
358                 // 処理時間更新用にタイマーを起動
359                 this.translator.LogUpdate += new EventHandler(this.GetLogUpdate);
360                 this.translator.StatusUpdate += new EventHandler(this.GetStatusUpdate);
361                 this.Invoke((MethodInvoker)delegate { this.timerStatusStopwatch.Start(); });
362
363                 // 翻訳支援処理を実行
364                 bool success = true;
365                 try
366                 {
367                     this.translator.Run(this.textBoxArticle.Text.Trim());
368                 }
369                 catch (ApplicationException)
370                 {
371                     // 中止要求で停止した場合、その旨イベントに格納する
372                     e.Cancel = this.backgroundWorkerRun.CancellationPending;
373                     success = false;
374                 }
375                 finally
376                 {
377                     // 処理時間更新用のタイマーを終了
378                     this.Invoke((MethodInvoker)delegate { this.timerStatusStopwatch.Stop(); });
379                 }
380
381                 // 実行結果から、ログと変換後テキストをファイル出力
382                 this.WriteResult(success);
383             }
384             catch (WebException ex)
385             {
386                 // 想定外の通信エラー(↓とまとめてもよいが、こちらはサーバーの状況などで発生しやすいので)
387                 this.textBoxLog.AppendText(Environment.NewLine + String.Format(Resources.ErrorMessageConnectionFailed, ex.Message) + Environment.NewLine);
388                 if (ex.Response != null)
389                 {
390                     // 出せるならエラーとなったURLも出力
391                     this.textBoxLog.AppendText(Resources.RightArrow + " " + String.Format(Resources.LogMessageErrorURL, ex.Response.ResponseUri) + Environment.NewLine);
392                 }
393             }
394             catch (Exception ex)
395             {
396                 // 想定外のエラー
397                 this.textBoxLog.AppendText(Environment.NewLine + String.Format(Resources.ErrorMessageDevelopmentError, ex.Message, ex.StackTrace) + Environment.NewLine);
398             }
399         }
400
401         /// <summary>
402         /// 実行ボタン バックグラウンド処理(終了時)。
403         /// </summary>
404         /// <param name="sender">イベント発生オブジェクト。</param>
405         /// <param name="e">発生したイベント。</param>
406         private void BackgroundWorkerRun_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
407         {
408             // 設定ファイルのキャッシュ情報を更新
409             // ※ 微妙に時間がかかるので、ステータスバーに通知
410             try
411             {
412                 this.toolStripStatusLabelStatus.Text = Resources.StatusCacheUpdating;
413                 try
414                 {
415                     this.config.Save();
416                 }
417                 finally
418                 {
419                     this.toolStripStatusLabelStatus.Text = String.Empty;
420                 }
421             }
422             catch (Exception ex)
423             {
424                 FormUtils.WarningDialog(
425                     Resources.WarningMessageCacheSaveFailed,
426                     ex.Message);
427             }
428
429             // 画面をロック中から解放
430             this.Release();
431         }
432
433         /// <summary>
434         /// ステータスバー処理時間更新タイマー処理。
435         /// </summary>
436         /// <param name="sender">イベント発生オブジェクト。</param>
437         /// <param name="e">発生したイベント。</param>
438         private void TimerStatusStopwatch_Tick(object sender, EventArgs e)
439         {
440             // 処理時間をステータスバーに反映
441             this.toolStripStatusLabelStopwatch.Text = String.Format(Resources.ElapsedTime, this.translator.Stopwatch.Elapsed);
442         }
443
444         #endregion
445
446         #region それ以外のメソッド
447
448         /// <summary>
449         /// 画面初期化処理。
450         /// </summary>
451         private void Initialize()
452         {
453             // コンボボックス設定
454             this.comboBoxSource.Items.Clear();
455             this.comboBoxTarget.Items.Clear();
456
457             // 設定ファイルに存在する全言語を選択肢として登録する
458             foreach (Website site in this.config.Websites)
459             {
460                 this.comboBoxSource.Items.Add(site.Language.Code);
461                 this.comboBoxTarget.Items.Add(site.Language.Code);
462             }
463         }
464
465         /// <summary>
466         /// 設定ファイル読み込み。
467         /// </summary>
468         /// <returns>読み込み成功時は<c>true</c>。</returns>
469         private bool LoadConfig()
470         {
471             // 設定ファイルの読み込み
472             // ※ 微妙に時間がかかるので、ステータスバーに通知
473             try
474             {
475                 this.toolStripStatusLabelStatus.Text = Resources.StatusConfigReading;
476                 try
477                 {
478                     this.config = Config.GetInstance(Settings.Default.ConfigurationFile);
479                 }
480                 finally
481                 {
482                     this.toolStripStatusLabelStatus.Text = String.Empty;
483                 }
484             }
485             catch (FileNotFoundException ex)
486             {
487                 // 設定ファイルが見つからない場合
488                 System.Diagnostics.Debug.WriteLine(
489                     "MainForm.LoadConfig > 設定ファイル読み込み失敗 : " + ex.Message);
490                 FormUtils.ErrorDialog(
491                     Resources.ErrorMessageConfigNotFound,
492                     Settings.Default.ConfigurationFile);
493
494                 return false;
495             }
496             catch (Exception ex)
497             {
498                 System.Diagnostics.Debug.WriteLine(
499                     "MainForm.LoadConfig > 設定ファイル読み込み時エラー : " + ex.StackTrace);
500                 FormUtils.ErrorDialog(
501                     Resources.ErrorMessageConfigLordFailed,
502                     ex.Message);
503
504                 return false;
505             }
506
507             return true;
508         }
509
510         /// <summary>
511         /// 画面をロック中に移行。
512         /// </summary>
513         private void LockOperation()
514         {
515             // 各種ボタンなどを入力不可に変更
516             this.groupBoxTransfer.Enabled = false;
517             this.groupBoxSaveDirectory.Enabled = false;
518             this.textBoxArticle.Enabled = false;
519             this.buttonRun.Enabled = false;
520
521             // 中止ボタンを有効に変更
522             this.buttonStop.Enabled = true;
523         }
524
525         /// <summary>
526         /// 画面をロック中から解放。
527         /// </summary>
528         private void Release()
529         {
530             // 中止ボタンを入力不可に変更
531             this.buttonStop.Enabled = false;
532
533             // 各種ボタンなどを有効に変更
534             this.groupBoxTransfer.Enabled = true;
535             this.groupBoxSaveDirectory.Enabled = true;
536             this.textBoxArticle.Enabled = true;
537             this.buttonRun.Enabled = true;
538         }
539
540         /// <summary>
541         /// 翻訳支援処理のログ・変換後テキストをファイル出力。
542         /// </summary>
543         /// <param name="success">翻訳支援処理が成功した場合<c>true</c>。</param>
544         private void WriteResult(bool success)
545         {
546             // 若干時間がかかるのでステータスバーに通知
547             this.toolStripStatusLabelStatus.Text = Resources.StatusFileWriting;
548             try
549             {
550                 // 使用可能な出力ファイル名を生成
551                 string fileName;
552                 string logName;
553                 this.MakeFileName(out fileName, out logName, this.textBoxArticle.Text.Trim(), this.textBoxSaveDirectory.Text);
554
555                 if (success)
556                 {
557                     // 翻訳支援処理成功時は変換後テキストを出力
558                     try
559                     {
560                         File.WriteAllText(Path.Combine(this.textBoxSaveDirectory.Text, fileName), this.translator.Text);
561                         this.textBoxLog.AppendText(String.Format(Resources.LogMessageEnd, fileName, logName));
562                     }
563                     catch (Exception ex)
564                     {
565                         this.textBoxLog.AppendText(String.Format(Resources.LogMessageFileSaveFailed, Path.Combine(this.textBoxSaveDirectory.Text, fileName), ex.Message));
566                         this.textBoxLog.AppendText(String.Format(Resources.LogMessageStop, logName));
567                     }
568                 }
569                 else
570                 {
571                     this.textBoxLog.AppendText(String.Format(Resources.LogMessageStop, logName));
572                 }
573
574                 // ログを出力
575                 try
576                 {
577                     File.WriteAllText(Path.Combine(this.textBoxSaveDirectory.Text, logName), this.textBoxLog.Text);
578                 }
579                 catch (Exception ex)
580                 {
581                     this.textBoxLog.AppendText(String.Format(Resources.LogMessageFileSaveFailed, Path.Combine(this.textBoxSaveDirectory.Text, logName), ex.Message));
582                 }
583             }
584             finally
585             {
586                 // ステータスバーをクリア
587                 this.toolStripStatusLabelStatus.Text = String.Empty;
588             }
589         }
590
591         /// <summary>
592         /// 渡された文字列から.txtと.logの重複していないファイル名を作成。
593         /// </summary>
594         /// <param name="fileName">出力結果ファイル名。</param>
595         /// <param name="logName">出力ログファイル名。</param>
596         /// <param name="text">出力する結果テキスト。</param>
597         /// <param name="dir">出力先ディレクトリ。</param>
598         /// <returns><c>true</c> 出力成功</returns>
599         private bool MakeFileName(out string fileName, out string logName, string text, string dir)
600         {
601             // 出力先フォルダに存在しないファイル名(の拡張子より前)を作成
602             // ※渡されたWikipedia等の記事名にファイル名に使えない文字が含まれている場合、_ に置き換える
603             //   また、ファイル名が重複している場合、xx[0].txtのように連番を付ける
604             string fileNameBase = FormUtils.ReplaceInvalidFileNameChars(text);
605             fileName = fileNameBase + ".txt";
606             logName = fileNameBase + ".log";
607             bool success = false;
608             for (int i = 0; i < 100000; i++)
609             {
610                 // ※100000まで試して空きが見つからないことは無いはず、もし見つからなかったら最後のを上書き
611                 if (!File.Exists(Path.Combine(dir, fileName))
612                     && !File.Exists(Path.Combine(dir, logName)))
613                 {
614                     success = true;
615                     break;
616                 }
617
618                 fileName = fileNameBase + "[" + i + "]" + ".txt";
619                 logName = fileNameBase + "[" + i + "]" + ".log";
620             }
621
622             // 結果設定
623             return success;
624         }
625
626         /// <summary>
627         /// 翻訳支援処理クラスのログ更新イベント用。
628         /// </summary>
629         /// <param name="sender">イベント発生オブジェクト。</param>
630         /// <param name="e">発生したイベント。</param>
631         private void GetLogUpdate(object sender, EventArgs e)
632         {
633             // 前回以降に追加されたログをテキストボックスに出力
634             int length = this.translator.Log.Length;
635             if (length > this.logLength)
636             {
637                 this.textBoxLog.AppendText(this.translator.Log.Substring(this.logLength, length - this.logLength));
638             }
639
640             this.logLength = length;
641         }
642
643         /// <summary>
644         /// 翻訳支援処理クラスの処理状態更新イベント用。
645         /// </summary>
646         /// <param name="sender">イベント発生オブジェクト。</param>
647         /// <param name="e">発生したイベント。</param>
648         private void GetStatusUpdate(object sender, EventArgs e)
649         {
650             // 処理状態をステータスバーに通知
651             this.toolStripStatusLabelStatus.Text = this.translator.Status;
652         }
653
654         #endregion
655     }
656 }