1 // ================================================================================================
3 // Wikipedia翻訳支援ツール設定画面クラスソース</summary>
5 // <copyright file="ConfigForm.cs" company="honeplusのメモ帳">
6 // Copyright (C) 2013 Honeplus. All rights reserved.</copyright>
9 // ================================================================================================
11 namespace Honememo.Wptscs
14 using System.Collections.Generic;
15 using System.ComponentModel;
19 using System.Reflection;
21 using System.Threading;
22 using System.Windows.Forms;
23 using Honememo.Utilities;
24 using Honememo.Wptscs.Models;
25 using Honememo.Wptscs.Properties;
26 using Honememo.Wptscs.Utilities;
27 using Honememo.Wptscs.Websites;
30 /// Wikipedia翻訳支援ツール設定画面のクラスです。
32 public partial class ConfigForm : Form
37 /// 現在設定中のアプリケーションの設定。
39 /// <remarks>設定画面を閉じた後は再読み込みされるので、必要に応じて随時更新してよい。</remarks>
40 private Config config;
43 /// <seealso cref="comboBoxLanguage"/>で選択していたアイテムのバックアップ。
45 private string comboBoxLanguageSelectedText;
54 /// <param name="config">設定対象のConfig。</param>
55 /// <remarks>configは設定画面の操作により随時更新される。呼び出し元では再読み込みすること。</remarks>
56 public ConfigForm(Config config)
58 this.InitializeComponent();
61 this.config = Honememo.Utilities.Validate.NotNull(config, "config");
66 #region フォームの各イベントのメソッド
71 /// <param name="sender">イベント発生オブジェクト。</param>
72 /// <param name="e">発生したイベント。</param>
73 private void ConfigForm_Load(object sender, EventArgs e)
80 this.ImportTranslationDictionaryView(this.dataGridViewItems, this.config.ItemTables);
83 this.ImportTranslationTableView(this.dataGridViewHeading, this.config.HeadingTable);
86 foreach (Website site in this.config.Websites)
88 this.comboBoxLanguage.Items.Add(site.Language.Code);
92 this.textBoxCacheExpire.Text = Settings.Default.CacheExpire.Days.ToString();
93 this.textBoxUserAgent.Text = Settings.Default.UserAgent;
94 this.textBoxReferer.Text = Settings.Default.Referer;
95 this.textBoxMaxConnectRetries.Text = Settings.Default.MaxConnectRetries.ToString();
96 this.textBoxConnectRetryTime.Text = Settings.Default.ConnectRetryTime.ToString();
97 this.checkBoxIgnoreError.Checked = Settings.Default.IgnoreError;
98 this.labelApplicationName.Text = FormUtils.ApplicationName();
99 AssemblyCopyrightAttribute copyright = Attribute.GetCustomAttribute(
100 Assembly.GetExecutingAssembly(),
101 typeof(AssemblyCopyrightAttribute)) as AssemblyCopyrightAttribute;
102 if (copyright != null)
104 this.labelCopyright.Text = copyright.Copyright;
109 // 通常この処理では例外は発生しないはず(Configに読めているので)。想定外のエラー用
110 FormUtils.ErrorDialog(Resources.ErrorMessageDevelopmentError, ex.Message, ex.StackTrace);
117 /// <param name="sender">イベント発生オブジェクト。</param>
118 /// <param name="e">発生したイベント。</param>
119 private void ButtonOk_Click(object sender, EventArgs e)
123 // 各タブの内容を設定ファイルに保存する
126 this.config.ItemTables = this.ExportTranslationDictionaryView(this.dataGridViewItems);
129 this.config.HeadingTable = this.ExportTranslationTableView(this.dataGridViewHeading);
132 // ※ このタブはコンボボックス変更のタイミングで保存されるので、そのメソッドを呼ぶ
133 this.ComboBoxLanguuage_SelectedIndexChanged(sender, e);
136 Settings.Default.CacheExpire = new TimeSpan(int.Parse(this.textBoxCacheExpire.Text), 0, 0, 0);
137 Settings.Default.UserAgent = this.textBoxUserAgent.Text;
138 Settings.Default.Referer = this.textBoxReferer.Text;
139 Settings.Default.MaxConnectRetries = int.Parse(this.textBoxMaxConnectRetries.Text);
140 Settings.Default.ConnectRetryTime = int.Parse(this.textBoxConnectRetryTime.Text);
141 Settings.Default.IgnoreError = this.checkBoxIgnoreError.Checked;
144 Settings.Default.Save();
150 // ※ エラーの場合、どうしても駄目ならキャンセルボタンで閉じてもらう
151 this.DialogResult = DialogResult.OK;
156 System.Diagnostics.Debug.WriteLine(ex.ToString());
157 FormUtils.ErrorDialog(Resources.ErrorMessageConfigSaveFailed, ex.Message);
162 // 通常ファイル保存以外では例外は発生しないはず。想定外のエラー用
163 FormUtils.ErrorDialog(Resources.ErrorMessageDevelopmentError, ex.Message, ex.StackTrace);
169 #region 記事の置き換えタブのイベントのメソッド
172 /// 記事の置き換え対訳表への行追加時の処理。
174 /// <param name="sender">イベント発生オブジェクト。</param>
175 /// <param name="e">発生したイベント。</param>
176 private void DataGridViewItems_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
178 for (int i = e.RowIndex - 1; i < this.dataGridViewItems.Rows.Count; i++)
180 // プログラムから追加された場合は現在のインデックス、画面から追加した場合は+1したインデックスが来る
183 this.dataGridViewItems.Rows[i].Cells["ColumnArrow"].Value = Resources.RightArrow;
189 /// 記事の置き換え対訳表のセル編集時のバリデート処理。
191 /// <param name="sender">イベント発生オブジェクト。</param>
192 /// <param name="e">発生したイベント。</param>
193 private void DataGridViewItems_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
196 if (this.dataGridViewItems.Columns[e.ColumnIndex].Name != "ColumnTimestamp")
201 // 空または日付として認識可能な値の場合OK
202 string value = e.FormattedValue.ToString();
204 if (string.IsNullOrWhiteSpace(value) || DateTime.TryParse(value, out dummy))
209 // 不許可値の場合、NGメッセージを表示
210 this.dataGridViewItems.Rows[e.RowIndex].ErrorText = Resources.WarningMessageUnformatedTimestamp;
215 /// 記事の置き換え対訳表のセル編集時のバリデート成功時の処理。
217 /// <param name="sender">イベント発生オブジェクト。</param>
218 /// <param name="e">発生したイベント。</param>
219 private void DataGridViewItems_CellValidated(object sender, DataGridViewCellEventArgs e)
221 // 取得日時列の場合、バリデートNGメッセージを消す
222 // ※ 他の列で消さないのは、エラーを出しているのがRowValidatingの場合もあるから
223 if (this.dataGridViewItems.Columns[e.ColumnIndex].Name == "ColumnTimestamp")
225 this.dataGridViewItems.Rows[e.RowIndex].ErrorText = string.Empty;
230 /// 記事の置き換え対訳表のセル変更時の処理。
232 /// <param name="sender">イベント発生オブジェクト。</param>
233 /// <param name="e">発生したイベント。</param>
234 private void DataGridViewItems_CellValueChanged(object sender, DataGridViewCellEventArgs e)
236 // 取得日時列が空の場合、有効期限が無期限として背景色を変更
237 // ※ ただし全列が空(新規行など)の場合は無視
240 DataGridViewRow row = this.dataGridViewItems.Rows[e.RowIndex];
241 if (string.IsNullOrWhiteSpace(FormUtils.ToString(row.Cells["ColumnTimestamp"]))
242 && !this.IsEmptyDataGridViewItemsRow(row))
245 row.DefaultCellStyle.BackColor = Color.Bisque;
247 else if (row.InheritedStyle.BackColor != this.dataGridViewItems.DefaultCellStyle.BackColor)
250 // ※ DefaultCellStyleプロパティにアクセスしたタイミングでインスタンスが
251 // 作成されてしまうため、InheritedStyleを調べて変更が必要な場合だけアクセス
252 row.DefaultCellStyle.BackColor = this.dataGridViewItems.DefaultCellStyle.BackColor;
258 /// 記事の置き換え対訳表の行編集時のバリデート処理。
260 /// <param name="sender">イベント発生オブジェクト。</param>
261 /// <param name="e">発生したイベント。</param>
262 private void DataGridViewItems_RowValidating(object sender, DataGridViewCellCancelEventArgs e)
264 // 翻訳元、記事名、翻訳先が未入力の場合、バリデートNGメッセージを表示
265 // ※ ただし全列が空(新規行など)の場合は無視
266 DataGridViewRow row = this.dataGridViewItems.Rows[e.RowIndex];
267 if ((string.IsNullOrWhiteSpace(FormUtils.ToString(row.Cells["ColumnFromCode"]))
268 || string.IsNullOrWhiteSpace(FormUtils.ToString(row.Cells["ColumnToCode"]))
269 || string.IsNullOrWhiteSpace(FormUtils.ToString(row.Cells["ColumnFromTitle"])))
270 && !this.IsEmptyDataGridViewItemsRow(row))
272 row.ErrorText = Resources.WarningMessageEmptyTranslationDictionary;
278 /// 記事の置き換え対訳表を使用する<see cref="DataGridView"/>の値設定を行う。
280 /// <param name="view">対訳表を表示するビュー。</param>
281 /// <param name="dictionaries">対訳表データ。</param>
282 private void ImportTranslationDictionaryView(DataGridView view, IList<TranslationDictionary> dictionaries)
284 // 初期設定以外の場合も想定して最初にクリア
286 foreach (TranslationDictionary dic in dictionaries)
288 foreach (KeyValuePair<string, TranslationDictionary.Item> item in dic)
291 DataGridViewRow row = view.Rows[view.Rows.Add()];
293 // 1行分の初期値を設定。右矢印は別途イベントで追加すること
294 row.Cells["ColumnFromCode"].Value = dic.From;
295 row.Cells["ColumnFromTitle"].Value = item.Key;
296 row.Cells["ColumnAlias"].Value = item.Value.Alias;
297 row.Cells["ColumnToCode"].Value = dic.To;
298 row.Cells["ColumnToTitle"].Value = item.Value.Word;
299 if (item.Value.Timestamp.HasValue)
301 row.Cells["ColumnTimestamp"].Value = item.Value.Timestamp.Value.ToLocalTime().ToString("G");
306 // 取得日時の降順でソート、空の列は先頭にする
307 this.dataGridViewItems.Sort(new TranslationDictionaryViewComparer());
310 // ※ 常に行ってしまうと、読み込みに非常に時間がかかるため
311 view.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
315 /// 記事の置き換え対訳表を使用する<see cref="DataGridView"/>からデータを抽出する。
317 /// <param name="view">対訳表を表示するビュー。</param>
318 /// <returns>対訳表データ。</returns>
319 private IList<TranslationDictionary> ExportTranslationDictionaryView(DataGridView view)
321 IList<TranslationDictionary> dictionaries = new List<TranslationDictionary>();
322 foreach (DataGridViewRow row in view.Rows)
324 // 画面での追加用の最終行が空で渡されてくるので無視
325 if (this.IsEmptyDataGridViewItemsRow(row))
330 // その行で対象とする言語を探索、無ければ新規作成
331 string from = FormUtils.ToString(row.Cells["ColumnFromCode"]);
332 string to = FormUtils.ToString(row.Cells["ColumnToCode"]);
333 TranslationDictionary dic
334 = TranslationDictionary.GetDictionaryNeedCreate(dictionaries, from, to);
337 TranslationDictionary.Item item = new TranslationDictionary.Item
339 Word = FormUtils.ToString(row.Cells["ColumnToTitle"]),
340 Alias = FormUtils.ToString(row.Cells["ColumnAlias"])
343 string timestamp = FormUtils.ToString(row.Cells["ColumnTimestamp"]);
344 if (!string.IsNullOrWhiteSpace(timestamp))
346 item.Timestamp = DateTime.Parse(timestamp);
348 // UTCでもなくタイムゾーンでも無い場合、ローカル時刻として設定する
349 if (item.Timestamp.Value.Kind == DateTimeKind.Unspecified)
351 item.Timestamp = DateTime.SpecifyKind(item.Timestamp.Value, DateTimeKind.Local);
355 dic[FormUtils.ToString(row.Cells["ColumnFromTitle"])] = item;
362 /// 記事の置き換え対訳表の行が空かを判定する。
364 /// <param name="row">対訳表の1行。</param>
365 /// <returns>空の場合<c>true</c>。</returns>
366 private bool IsEmptyDataGridViewItemsRow(DataGridViewRow row)
368 return string.IsNullOrWhiteSpace(FormUtils.ToString(row.Cells["ColumnFromCode"]))
369 && string.IsNullOrWhiteSpace(FormUtils.ToString(row.Cells["ColumnFromTitle"]))
370 && string.IsNullOrWhiteSpace(FormUtils.ToString(row.Cells["ColumnAlias"]))
371 && string.IsNullOrWhiteSpace(FormUtils.ToString(row.Cells["ColumnToCode"]))
372 && string.IsNullOrWhiteSpace(FormUtils.ToString(row.Cells["ColumnToTitle"]))
373 && string.IsNullOrWhiteSpace(FormUtils.ToString(row.Cells["ColumnTimestamp"]));
378 #region 見出しの置き換えタブのイベントのメソッド
381 /// 見出しの置き換え対訳表を使用する<see cref="DataGridView"/>の値設定を行う。
383 /// <param name="view">対訳表を表示するビュー。</param>
384 /// <param name="table">対訳表データ。</param>
385 private void ImportTranslationTableView(DataGridView view, TranslationTable table)
387 // 初期設定以外の場合も想定して最初にクリア
388 view.Columns.Clear();
390 // 言語コードを列、語句を行とする。登録されている全言語分の列を作成する
391 foreach (Website site in this.config.Websites)
393 this.AddTranslationTableColumn(view.Columns, site.Language.Code, this.GetHeaderLanguage(site.Language));
397 foreach (IDictionary<string, string[]> record in table)
400 DataGridViewRow row = view.Rows[view.Rows.Add()];
402 foreach (KeyValuePair<string, string[]> cell in record)
404 // 上で登録した列では足りなかった場合、その都度生成する
405 if (!view.Columns.Contains(cell.Key))
407 this.AddTranslationTableColumn(view.Columns, cell.Key, cell.Key);
411 row.Cells[cell.Key].Value = string.Join("\n", cell.Value);
415 // 可能であれば現在表示中の言語の列の昇順でソートする
417 string code = Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName;
418 if (view.Columns.Contains(code))
420 view.Sort(view.Columns[code], ListSortDirection.Ascending);
422 else if (view.Columns.Contains("en"))
424 view.Sort(view.Columns["en"], ListSortDirection.Ascending);
429 /// 見出しの置き換え対訳表を使用する<see cref="DataGridView"/>からデータを抽出する。
431 /// <param name="view">対訳表を表示するビュー。</param>
432 /// <returns>対訳表データ。</returns>
433 private TranslationTable ExportTranslationTableView(DataGridView view)
435 TranslationTable table = new TranslationTable();
436 foreach (DataGridViewRow row in view.Rows)
438 IDictionary<string, string[]> record = new SortedDictionary<string, string[]>();
439 foreach (DataGridViewCell cell in row.Cells)
441 // 空のセルは格納しない、該当の組み合わせは消える
442 string value = FormUtils.ToString(cell);
443 if (!string.IsNullOrWhiteSpace(value))
446 record[cell.OwningColumn.Name] = CollectionUtils.Trim(value.Split('\n'));
450 // 1件もデータが無い行は丸々カットする
451 if (record.Count > 0)
461 /// 指定された情報を元に見出しの置き換え対訳表の列を追加する。
463 /// <param name="columns">列コレクション。</param>
464 /// <param name="columnName">列名。</param>
465 /// <param name="headerText">列見出し。</param>
466 private void AddTranslationTableColumn(DataGridViewColumnCollection columns, string columnName, string headerText)
468 columns.Add(columnName, headerText);
474 /// <param name="lang">表示言語コード。</param>
475 /// <returns>表示名、無ければ言語コード。</returns>
476 private string GetHeaderLanguage(Language lang)
478 Language.LanguageName name;
479 if (lang.Names.TryGetValue(
480 Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName, out name))
482 if (!string.IsNullOrEmpty(name.Name))
484 return string.Format(Resources.HeadingViewHeaderText, name.Name, lang.Code);
493 #region 言語/サーバータブのイベントのメソッド
498 /// <param name="sender">イベント発生オブジェクト。</param>
499 /// <param name="e">発生したイベント。</param>
500 private void ComboBoxLanguuage_SelectedIndexChanged(object sender, EventArgs e)
505 if (!string.IsNullOrEmpty(this.comboBoxLanguageSelectedText))
508 this.SaveChangedValue(this.GetMediaWikiNeedCreate(this.config.Websites, this.comboBoxLanguageSelectedText));
512 if (!string.IsNullOrEmpty(this.comboBoxLanguage.Text))
514 // 設定が存在しなければ基本的に自動生成されるのでそのまま使用
515 this.LoadCurrentValue(this.GetMediaWikiNeedCreate(this.config.Websites, this.comboBoxLanguage.Text));
518 this.buttonLanguageRemove.Enabled = true;
519 this.groupBoxServer.Enabled = true;
520 this.groupBoxLanguage.Enabled = true;
523 this.comboBoxLanguageSelectedText = this.comboBoxLanguage.Text;
528 this.buttonLanguageRemove.Enabled = false;
529 this.groupBoxServer.Enabled = false;
530 this.groupBoxLanguage.Enabled = false;
533 this.comboBoxLanguageSelectedText = string.Empty;
538 // 通常この処理では例外は発生しないはず。想定外のエラー用
539 FormUtils.ErrorDialog(Resources.ErrorMessageDevelopmentError, ex.Message, ex.StackTrace);
546 /// <param name="sender">イベント発生オブジェクト。</param>
547 /// <param name="e">発生したイベント。</param>
548 private void ButtonLunguageAdd_Click(object sender, EventArgs e)
550 // 言語追加用ダイアログで言語コードを入力
551 using (AddLanguageDialog form = new AddLanguageDialog(this.config))
553 if (form.ShowDialog() == DialogResult.OK)
555 // 値をコンボボックスと見出しの対訳表に追加、登録した値を選択状態に変更
556 this.comboBoxLanguage.Items.Add(form.LanguageCode);
557 this.dataGridViewHeading.Columns.Add(form.LanguageCode, form.LanguageCode);
558 this.comboBoxLanguage.SelectedItem = form.LanguageCode;
566 /// <param name="sender">イベント発生オブジェクト。</param>
567 /// <param name="e">発生したイベント。</param>
568 private void ButtonLanguageRemove_Click(object sender, EventArgs e)
570 // 表示されている言語を設定から削除する
571 for (int i = this.config.Websites.Count - 1; i >= 0; i--)
573 if (this.config.Websites[i].Language.Code == this.comboBoxLanguage.Text)
576 this.config.Websites.RemoveAt(i);
580 // 値を見出しの対訳表とコンボボックスからも削除し、表示を更新する
581 this.comboBoxLanguageSelectedText = null;
582 this.dataGridViewHeading.Columns.Remove(this.comboBoxLanguage.Text);
583 this.comboBoxLanguage.Items.Remove(this.comboBoxLanguage.Text);
584 this.ComboBoxLanguuage_SelectedIndexChanged(sender, e);
588 /// 各名前空間のIDボックスバリデート処理。
590 /// <param name="sender">イベント発生オブジェクト。</param>
591 /// <param name="e">発生したイベント。</param>
592 private void TextBoxNamespace_Validating(object sender, CancelEventArgs e)
595 TextBox box = (TextBox)sender;
596 box.Text = StringUtils.DefaultString(box.Text).Trim();
598 if (!string.IsNullOrEmpty(box.Text) && !int.TryParse(box.Text, out value))
600 this.errorProvider.SetError(box, Resources.WarningMessageIgnoreNumericNamespace);
606 /// 括弧のスタイルボックスバリデート処理。
608 /// <param name="sender">イベント発生オブジェクト。</param>
609 /// <param name="e">発生したイベント。</param>
610 private void TextBoxBracket_Validating(object sender, CancelEventArgs e)
613 TextBox box = (TextBox)sender;
614 if (!string.IsNullOrEmpty(box.Text) && !box.Text.Contains("$1"))
616 this.errorProvider.SetError(box, Resources.WarningMessageUnformatedBracket);
622 /// 言語の設定表の行編集時のバリデート処理。
624 /// <param name="sender">イベント発生オブジェクト。</param>
625 /// <param name="e">発生したイベント。</param>
626 private void DataGridViewLanguageName_RowValidating(object sender, DataGridViewCellCancelEventArgs e)
628 DataGridViewRow row = this.dataGridViewLanguageName.Rows[e.RowIndex];
631 if (FormUtils.IsEmptyRow(row))
636 // 言語コードは必須、またトリムして小文字に変換
637 string code = FormUtils.ToString(row.Cells["ColumnCode"]).Trim().ToLower();
638 row.Cells["ColumnCode"].Value = code;
639 if (string.IsNullOrEmpty(code))
641 row.ErrorText = Resources.WarningMessageEmptyCodeColumn;
646 // 略称を設定する場合、呼称を必須とする
647 if (!string.IsNullOrWhiteSpace(FormUtils.ToString(row.Cells["ColumnShortName"]))
648 && string.IsNullOrWhiteSpace(FormUtils.ToString(row.Cells["ColumnName"])))
650 row.ErrorText = Resources.WarningMessageShortNameColumnOnly;
658 /// <param name="sender">イベント発生オブジェクト。</param>
659 /// <param name="e">発生したイベント。</param>
660 private void DataGridViewLanguageName_Validating(object sender, CancelEventArgs e)
663 IDictionary<string, int> codeMap = new Dictionary<string, int>();
664 for (int i = 0; i < this.dataGridViewLanguageName.RowCount - 1; i++)
666 string code = FormUtils.ToString(this.dataGridViewLanguageName["ColumnCode", i]);
668 if (codeMap.TryGetValue(code, out y))
671 this.dataGridViewLanguageName.Rows[i].ErrorText = Resources.WarningMessageDuplicateCodeColumn;
672 this.dataGridViewLanguageName.Rows[y].ErrorText = Resources.WarningMessageDuplicateCodeColumn;
677 // それ以外はマップに出現行とともに追加
683 #region イベント実装支援用メソッド
686 /// コレクションから指定された言語のMediaWikiを取得する。
687 /// 存在しない場合は空のインスタンスを生成、コレクションに追加して返す。
689 /// <param name="collection">翻訳元言語。</param>
690 /// <param name="lang">言語コード。</param>
691 /// <returns>翻訳パターン。存在しない場合は新たに作成した翻訳パターンを返す。</returns>
692 private MediaWiki GetMediaWikiNeedCreate(ICollection<Website> collection, string lang)
695 foreach (Website s in collection)
697 if (s.Language.Code == lang)
701 return s as MediaWiki;
704 // 万が一同じ言語コードで違う型の値があったら上書き
705 collection.Remove(s);
710 // 存在しないか上書きの場合、作成した翻訳パターンをコレクションに追加し、返す
711 MediaWiki site = new MediaWiki(new Language(lang));
712 collection.Add(site);
717 /// 指定されたLanguage設定を画面表示/編集用に読み込む。
719 /// <param name="lang">読込元Language設定。</param>
720 /// <remarks>一部パラメータには初期値が存在するが、格納時に対処するため全て読み込む。</remarks>
721 private void LoadCurrentValue(Language lang)
724 // ※ Bracketは初期値があるパラメータのため、必ず値が返る
725 this.textBoxBracket.Text = lang.Bracket;
728 this.dataGridViewLanguageName.Rows.Clear();
729 foreach (KeyValuePair<string, Language.LanguageName> name in lang.Names)
731 int index = this.dataGridViewLanguageName.Rows.Add();
732 this.dataGridViewLanguageName["ColumnCode", index].Value = name.Key;
733 this.dataGridViewLanguageName["ColumnName", index].Value = name.Value.Name;
734 this.dataGridViewLanguageName["ColumnShortName", index].Value = name.Value.ShortName;
738 this.dataGridViewLanguageName.Sort(this.dataGridViewLanguageName.Columns["ColumnCode"], ListSortDirection.Ascending);
742 /// 指定されたWebsite設定を画面表示/編集用に読み込む。
744 /// <param name="site">読込元Website設定。</param>
745 private void LoadCurrentValue(Website site)
747 // Languageクラス分の読み込みを行う
748 this.LoadCurrentValue(site.Language);
751 this.textBoxLocation.Text = site.Location;
755 /// 指定されたMediaWiki設定を画面表示/編集用に読み込む。
757 /// <param name="site">読込元MediaWiki設定。</param>
758 /// <remarks>一部パラメータには初期値が存在するが、格納時に対処するため全て読み込む。</remarks>
759 private void LoadCurrentValue(MediaWiki site)
761 // Websiteクラス分の読み込みを行う
762 this.LoadCurrentValue((Website)site);
764 // MediaWikiクラス分の読み込み
765 this.textBoxContentApi.Text = StringUtils.DefaultString(site.ContentApi);
766 this.textBoxMetaApi.Text = StringUtils.DefaultString(site.MetaApi);
767 this.textBoxInterlanguageApi.Text = StringUtils.DefaultString(site.InterlanguageApi);
768 this.textBoxTemplateNamespace.Text = site.TemplateNamespace.ToString();
769 this.textBoxCategoryNamespace.Text = site.CategoryNamespace.ToString();
770 this.textBoxFileNamespace.Text = site.FileNamespace.ToString();
771 this.textBoxLinkInterwikiFormat.Text = StringUtils.DefaultString(site.LinkInterwikiFormat);
772 this.textBoxLangFormat.Text = StringUtils.DefaultString(site.LangFormat);
773 this.checkBoxHasLanguagePage.Checked = site.HasLanguagePage;
777 /// 指定されたLanguage設定に画面上で変更された値の格納を行う。
779 /// <param name="lang">格納先Language設定。</param>
780 /// <remarks>一部パラメータには初期値が存在するため、変更がある場合のみ格納する。</remarks>
781 private void SaveChangedValue(Language lang)
783 // Bracketは初期値を持つパラメータのため、変更された場合のみ格納する。
784 // ※ この値は前後の空白に意味があるため、Trimしてはいけない
785 string str = StringUtils.DefaultString(this.textBoxBracket.Text);
786 if (str != lang.Bracket)
793 for (int y = 0; y < this.dataGridViewLanguageName.RowCount - 1; y++)
795 // 値が入ってないとかはガードしているはずだが、一応チェック
796 string code = FormUtils.ToString(this.dataGridViewLanguageName["ColumnCode", y]).Trim();
797 if (!string.IsNullOrEmpty(code))
799 Language.LanguageName name = new Language.LanguageName();
800 name.Name = FormUtils.ToString(this.dataGridViewLanguageName["ColumnName", y]).Trim();
801 name.ShortName = FormUtils.ToString(this.dataGridViewLanguageName["ColumnShortName", y]).Trim();
802 lang.Names[code] = name;
808 /// 指定されたWebsite設定に画面上で変更された値の格納を行う。
810 /// <param name="site">格納先Website設定。</param>
811 /// <remarks>Websiteについては特に特殊な処理は無いため全て上書きする。</remarks>
812 private void SaveChangedValue(Website site)
814 // Languageクラス分の設定を行う
815 this.SaveChangedValue(site.Language);
818 site.Location = StringUtils.DefaultString(this.textBoxLocation.Text).Trim();
822 /// 指定されたMediaWiki設定に画面上で変更された値の格納を行う。
824 /// <param name="site">格納先MediaWiki設定。</param>
825 /// <remarks>一部パラメータには初期値が存在するため、変更がある場合のみ格納する。</remarks>
826 private void SaveChangedValue(MediaWiki site)
829 this.SaveChangedValue((Website)site);
831 // 初期値を持つパラメータがあるため、全て変更された場合のみ格納する。
832 // ※ もうちょっと綺麗に書きたかったが、うまい手が思いつかなかったので力技
833 // MediaWikiクラス側で行わないのは、場合によっては意図的に初期値と同じ値を設定すること
834 // もありえるから(初期値が変わる可能性がある場合など)。
835 string str = StringUtils.DefaultString(this.textBoxContentApi.Text).Trim();
836 if (str != site.ContentApi)
838 site.ContentApi = str;
841 str = StringUtils.DefaultString(this.textBoxMetaApi.Text).Trim();
842 if (str != site.MetaApi)
847 str = StringUtils.DefaultString(this.textBoxInterlanguageApi.Text).Trim();
848 if (str != site.InterlanguageApi)
850 site.InterlanguageApi = str;
853 str = StringUtils.DefaultString(this.textBoxLinkInterwikiFormat.Text).Trim();
854 if (str != site.LinkInterwikiFormat)
856 site.LinkInterwikiFormat = str;
859 str = StringUtils.DefaultString(this.textBoxLangFormat.Text).Trim();
860 if (str != site.LangFormat)
862 site.LangFormat = str;
865 site.HasLanguagePage = this.checkBoxHasLanguagePage.Checked;
867 // 以下、数値へのparseは事前にチェックしてあるので、ここではチェックしない
868 if (!string.IsNullOrWhiteSpace(this.textBoxTemplateNamespace.Text))
870 int num = int.Parse(this.textBoxTemplateNamespace.Text);
871 if (site.TemplateNamespace != num)
873 site.TemplateNamespace = num;
877 if (!string.IsNullOrWhiteSpace(this.textBoxCategoryNamespace.Text))
879 int num = int.Parse(this.textBoxCategoryNamespace.Text);
880 if (site.CategoryNamespace != num)
882 site.CategoryNamespace = num;
886 if (!string.IsNullOrWhiteSpace(this.textBoxFileNamespace.Text))
888 int num = int.Parse(this.textBoxFileNamespace.Text);
889 if (site.FileNamespace != num)
891 site.FileNamespace = num;
900 #region その他タブのイベントのメソッド
903 /// キャッシュ有効期限ボックスバリデート処理。
905 /// <param name="sender">イベント発生オブジェクト。</param>
906 /// <param name="e">発生したイベント。</param>
907 private void TextBoxCacheExpire_Validating(object sender, CancelEventArgs e)
910 this.TextBoxGreaterThanValidating((TextBox)sender, e, 0, Resources.WarningMessageIgnoreCacheExpire);
914 /// リトライ回数ボックスバリデート処理。
916 /// <param name="sender">イベント発生オブジェクト。</param>
917 /// <param name="e">発生したイベント。</param>
918 private void TextBoxMaxConnectRetries_Validating(object sender, CancelEventArgs e)
921 this.TextBoxGreaterThanValidating((TextBox)sender, e, 0, Resources.WarningMessageIgnoreMaxConnectRetries);
925 /// ウェイト時間ボックスバリデート処理。
927 /// <param name="sender">イベント発生オブジェクト。</param>
928 /// <param name="e">発生したイベント。</param>
929 private void TextBoxConnectRetryTime_Validating(object sender, CancelEventArgs e)
932 this.TextBoxGreaterThanValidating((TextBox)sender, e, 0, Resources.WarningMessageIgnoreConnectRetryTime);
936 /// ウェブサイトURLクリック時の処理。
938 /// <param name="sender">イベント発生オブジェクト。</param>
939 /// <param name="e">発生したイベント。</param>
940 private void LinkLabelWebsite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
943 System.Diagnostics.Process.Start(((LinkLabel)sender).Text);
946 #region イベント実装支援用メソッド
949 /// メッセージのみ差し替え可能なテキストボックス用の値がxx以上の数値か、のバリデート処理。
951 /// <param name="box">イベント発生テキストボックス。</param>
952 /// <param name="e">発生したイベント。</param>
953 /// <param name="num">比較対象の数値。</param>
954 /// <param name="message">バリデートメッセージ。</param>
955 private void TextBoxGreaterThanValidating(TextBox box, CancelEventArgs e, int num, string message)
957 box.Text = StringUtils.DefaultString(box.Text).Trim();
959 if (!int.TryParse(box.Text, out value) || value < num)
961 this.errorProvider.SetError(box, message);
973 /// 汎用のエラープロバイダ初期化処理。
975 /// <param name="sender">イベント発生オブジェクト。</param>
976 /// <param name="e">発生したイベント。</param>
977 private void ResetErrorProvider_Validated(object sender, EventArgs e)
979 this.errorProvider.SetError((Control)sender, null);
983 /// 汎用の行編集時のエラーテキスト初期化処理。
985 /// <param name="sender">イベント発生オブジェクト。</param>
986 /// <param name="e">発生したイベント。</param>
987 private void ResetErrorText_RowValidated(object sender, DataGridViewCellEventArgs e)
989 ((DataGridView)sender).Rows[e.RowIndex].ErrorText = string.Empty;
993 /// 汎用のテーブルエラーテキスト初期化処理。
995 /// <param name="sender">イベント発生オブジェクト。</param>
996 /// <param name="e">発生したイベント。</param>
997 private void ResetErrorText_Validated(object sender, EventArgs e)
1000 foreach (DataGridViewRow row in ((DataGridView)sender).Rows)
1002 row.ErrorText = string.Empty;
1011 /// 記事の置き換え対訳表の日付並び替え用クラスです。
1014 /// 取得日時の降順でソート、空の列は先頭にします。
1015 /// 取得日時が同じ場合、先頭の列から順に昇順でソート。
1017 public class TranslationDictionaryViewComparer : System.Collections.IComparer
1020 /// 取得日時が同じ場合にソートに用いる列名。
1022 private static readonly string[] SortOrder = new string[] { "ColumnFromCode", "ColumnToCode", "ColumnFromTitle" };
1025 /// 2行を比較し、一方が他方より小さいか、等しいか、大きいかを示す値を返します。
1027 /// <param name="x">比較する最初の行です。</param>
1028 /// <param name="y">比較する2番目の行。</param>
1029 /// <returns>0未満:xはyより小さい, 0:xとyは等しい, 0より大きい:xはyより大きい。</returns>
1030 public int Compare(object x, object y)
1032 DataGridViewRow xrow = (DataGridViewRow)x;
1033 DataGridViewRow yrow = (DataGridViewRow)y;
1035 // 取得日時列の降順でソート、ただし空の列は先頭にする
1036 int compare = StringUtils.CompareNullsLast(
1037 FormUtils.ToString(xrow.Cells["ColumnTimestamp"]),
1038 FormUtils.ToString(yrow.Cells["ColumnTimestamp"]));
1041 return compare * -1;
1044 // 取得日時列が同じ場合、残りの列の昇順でソート
1045 foreach (string column in SortOrder)
1047 compare = string.Compare(
1048 FormUtils.ToString(xrow.Cells[column]),
1049 FormUtils.ToString(yrow.Cells[column]));