# 画面設計書 41-ロケールダイアログ

## 概要

本ドキュメントは、Godot Engineエディタにおけるロケールダイアログ（EditorLocaleDialog）の画面設計書である。ロケール（言語・地域設定）を選択するためのダイアログウィンドウの仕様を定義する。

### 本画面の処理概要

ロケールダイアログは、プロジェクトの国際化（i18n）設定において、言語・スクリプト（文字体系）・国/地域を選択するためのモーダルダイアログである。翻訳リソースの追加時やローカライズ設定時に使用される。

**業務上の目的・背景**：ゲームやアプリケーションの多言語対応において、対応するロケール（言語・地域の組み合わせ）を正確に指定する必要がある。本ダイアログは、ISO 639（言語コード）、ISO 15924（スクリプトコード）、ISO 3166（国コード）に準拠したロケール識別子の選択を支援し、開発者が正しいロケールコードを容易に選択できるようにする。フィルタ機能により、プロジェクトで使用するロケールを絞り込むことも可能。

**画面へのアクセス方法**：プロジェクト設定のローカライゼーション（Localization）セクション、または翻訳リソースの編集画面から、ロケール選択が必要な場面で呼び出される。具体的には「Add Locale」ボタンや類似のUI操作によりポップアップ表示される。

**主要な操作・処理内容**：
1. 言語リストから対象言語を選択（例：Japanese [ja]）
2. 必要に応じてスクリプト（文字体系）を選択（例：Latin [Latn]）- Advancedモード
3. 国/地域リストから対象国を選択（例：Japan [JP]）
4. 必要に応じてバリアント（方言等）を入力 - Advancedモード
5. Selectボタンで選択を確定し、ロケールコードを返却
6. フィルタ編集モードでプロジェクト固有のロケールフィルタを設定

**画面遷移**：本ダイアログはモーダルウィンドウとして表示され、選択完了またはキャンセル時に呼び出し元画面に戻る。遷移元となる画面はプロジェクト設定画面、翻訳設定画面など複数存在する。

**権限による表示制御**：エディタ機能のため、特定の権限制御は存在しない。ただし、フィルタ編集モードでの変更はプロジェクト設定に保存されるため、プロジェクトの書き込み権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| F-041 | 翻訳管理 | 主機能 | ロケール選択時に本ダイアログを呼び出し |
| - | TranslationServer | API連携 | 言語・スクリプト・国リストの取得、ロケールの標準化 |
| - | ProjectSettings | API連携 | フィルタ設定の読み書き |
| - | EditorUndoRedoManager | 補助機能 | フィルタ変更のUndo/Redo対応 |

## 画面種別

選択ダイアログ（Modal Dialog）

## URL/ルーティング

該当なし（ネイティブGUIダイアログとして実装）

## 入出力項目

### 入力項目

| 項目名 | 項目ID | データ型 | 必須 | 入力形式 | バリデーション | 説明 |
|--------|--------|----------|------|----------|----------------|------|
| 言語コード | lang_code | String | 必須 | テキスト入力/リスト選択 | 最大3文字、ISO 639準拠 | 言語識別コード（例：ja, en） |
| スクリプトコード | script_code | String | 任意 | テキスト入力/リスト選択 | 最大4文字、ISO 15924準拠 | 文字体系コード（例：Latn, Jpan） |
| 国コード | country_code | String | 任意 | テキスト入力/リスト選択 | 最大2文字、ISO 3166準拠 | 国/地域コード（例：JP, US） |
| バリアントコード | variant_code | String | 任意 | テキスト入力 | 小文字変換 | 方言・バリアント識別子 |

### 出力項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| 選択ロケール | String | 標準化されたロケール識別子（例：ja_JP, en_US） |

## 表示項目

### フィルタ・オプションエリア

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| フィルタモード | filter_mode | OptionButton | Show All Locales / Show Selected Locales Only |
| フィルタ編集 | edit_filters | CheckButton | フィルタ編集モードの切替 |
| 詳細オプション | advanced | CheckButton | スクリプト・バリアント入力の表示切替 |

### リストエリア

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| 言語リスト | lang_list | Tree | 利用可能な言語の一覧 |
| スクリプトリスト | script_list | Tree | 利用可能なスクリプト（文字体系）の一覧 |
| 国リスト | cnt_list | Tree | 利用可能な国/地域の一覧 |

### 入力エリア（Advancedモード時）

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| 言語コード入力 | lang_code | LineEdit | 選択または直接入力された言語コード |
| スクリプトコード入力 | script_code | LineEdit | 選択または直接入力されたスクリプトコード |
| 国コード入力 | country_code | LineEdit | 選択または直接入力された国コード |
| バリアントコード入力 | variant_code | LineEdit | 直接入力されたバリアントコード |

## イベント仕様

### 1-言語選択イベント

**トリガー**: lang_list のアイテム選択

**処理内容**:
1. 選択されたTreeItemのメタデータ（言語コード）を取得
2. lang_code LineEditに言語コードを設定
3. フィルタ編集モードの場合は処理をスキップ

**関連メソッド**: `_item_selected()` (L83-106)

### 2-スクリプト選択イベント

**トリガー**: script_list のアイテム選択

**処理内容**:
1. 選択されたTreeItemのメタデータ（スクリプトコード）を取得
2. script_code LineEditにスクリプトコードを設定

**関連メソッド**: `_item_selected()` (L83-106)

### 3-国選択イベント

**トリガー**: cnt_list のアイテム選択

**処理内容**:
1. 選択されたTreeItemのメタデータ（国コード）を取得
2. country_code LineEditに国コードを設定

**関連メソッド**: `_item_selected()` (L83-106)

### 4-Selectボタン押下イベント

**トリガー**: OKボタン（Selectボタン）押下

**処理内容**:
1. フィルタ編集モードの場合は処理を中断
2. 言語コードが空の場合は処理を中断
3. 言語コード + スクリプトコード + 国コード + バリアントコードを連結してロケール文字列を構築
4. TranslationServerでロケールを標準化
5. `locale_selected` シグナルを発行
6. ダイアログを閉じる

**関連メソッド**: `ok_pressed()` (L58-81)

### 5-フィルタモード変更イベント

**トリガー**: filter_mode OptionButtonの選択変更

**処理内容**:
1. 選択されたフィルタモードを取得
2. Undo/Redoアクションを作成
3. ProjectSettingsの `internationalization/locale/locale_filter_mode` を更新
4. ツリー表示を更新

**関連メソッド**: `_filter_mode_changed()` (L231-246)

### 6-フィルタ編集モード切替イベント

**トリガー**: edit_filters CheckButtonのトグル

**処理内容**:
1. フィルタ編集モードを切り替え
2. リストをチェックボックス付き表示に変更
3. 詳細入力エリアを非表示化
4. OKボタンを無効化

**関連メソッド**: `_edit_filters()` (L248-250), `_update_tree()` (L252-358)

### 7-言語フィルタ変更イベント

**トリガー**: lang_list のチェックボックス変更（フィルタ編集モード時）

**処理内容**:
1. チェック状態と言語コードを取得
2. ProjectSettingsの `internationalization/locale/language_filter` 配列を更新
3. Undo/Redoアクションとして記録

**関連メソッド**: `_filter_lang_option_changed()` (L129-161)

### 8-Advancedモード切替イベント

**トリガー**: advanced CheckButtonのトグル

**処理内容**:
1. OFF時はスクリプトコード・バリアントコードをクリア
2. スクリプトリストとロケール入力エリアの表示を更新

**関連メソッド**: `_toggle_advanced()` (L108-114)

## データベース更新仕様

### 操作別データベース影響一覧

本ダイアログはデータベースを使用せず、プロジェクト設定（project.godot）への書き込みを行う。

| 操作（イベント） | 対象設定 | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| フィルタモード変更 | internationalization/locale/locale_filter_mode | UPDATE | フィルタ表示モードの変更 |
| 言語フィルタ変更 | internationalization/locale/language_filter | UPDATE | フィルタ対象言語リストの変更 |
| スクリプトフィルタ変更 | internationalization/locale/script_filter | UPDATE | フィルタ対象スクリプトリストの変更 |
| 国フィルタ変更 | internationalization/locale/country_filter | UPDATE | フィルタ対象国リストの変更 |

### 設定別更新項目詳細

#### internationalization/locale/locale_filter_mode

| 操作 | 設定値 | 説明 |
|-----|--------|------|
| UPDATE | 0 (SHOW_ALL_LOCALES) | 全ロケールを表示 |
| UPDATE | 1 (SHOW_ONLY_SELECTED_LOCALES) | 選択されたロケールのみ表示 |

#### internationalization/locale/language_filter

| 操作 | データ型 | 説明 |
|-----|----------|------|
| UPDATE | Array[String] | フィルタ対象の言語コード配列 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| - | タイトル | "Select a Locale" | ダイアログ表示時 |
| - | ボタン | "Select" | OKボタンラベル |
| - | ラベル | "Language:" | 言語リストラベル |
| - | ラベル | "Script:" / "Script" | スクリプトリストラベル |
| - | ラベル | "Country:" | 国リストラベル |
| - | オプション | "Show All Locales" | フィルタモード選択肢 |
| - | オプション | "Show Selected Locales Only" | フィルタモード選択肢 |
| - | ボタン | "Edit Filters" | フィルタ編集モードトグル |
| - | ボタン | "Advanced" | 詳細モードトグル |
| - | リスト項目 | "[Default]" | スクリプト・国リストのデフォルト選択肢 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|----------|
| 言語コードが空 | Selectボタン押下時に処理を中断、ダイアログは閉じない |
| フィルタ編集モード中のSelect | 処理を中断、ダイアログは閉じない |
| 無効なロケール形式 | TranslationServer.standardize_locale()で標準化処理 |

## 備考

- ダイアログサイズは 1050x700 ピクセル（エディタスケール適用前）で、画面の80%以内に収まるよう制限される
- フィルタ設定の変更はUndo/Redoに対応しており、EditorUndoRedoManagerを使用
- スクリプトリストとロケール入力エリアはAdvancedモードでのみ表示される
- 各リストの項目は「表示名 [コード]」の形式で表示される（例：「Japanese [ja]」）
- TranslationServerから取得するロケールデータはエンジン内蔵のデータに基づく

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

ロケールダイアログで扱うデータ構造は主にプロジェクト設定とTranslationServerのロケールデータである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | editor_locale_dialog.h | `editor/translations/editor_locale_dialog.h` | LocaleFilter enum（L45-48）でフィルタモードの定義、メンバ変数でUI構成要素を確認 |
| 1-2 | translation_server.h | `core/string/translation_server.h` | ロケールデータの取得メソッド（get_all_languages, get_all_scripts, get_all_countries）を確認 |

**読解のコツ**: EditorLocaleDialogはConfirmationDialogを継承しており、ok_pressed()のオーバーライドでSelectボタン処理を実装している。

#### Step 2: エントリーポイントを理解する

ダイアログの表示開始点と初期化処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | editor_locale_dialog.cpp | `editor/translations/editor_locale_dialog.cpp` | コンストラクタ（L403-576）でUI構築、popup_locale_dialog()（L399-401）で表示 |

**主要処理フロー**:
1. **L403**: EditorLocaleDialog()コンストラクタでUI要素を作成
2. **L410-418**: フィルタモードOptionButton作成、item_selected シグナル接続
3. **L420-426**: Edit Filters CheckButton作成
4. **L428-434**: Advanced CheckButton作成
5. **L449-457**: 言語リストTree作成、cell_selected/item_edited シグナル接続
6. **L469-476**: スクリプトリストTree作成
7. **L488-496**: 国リストTree作成
8. **L514-519**: 言語コードLineEdit作成（最大3文字）
9. **L530-533**: スクリプトコードLineEdit作成（最大4文字）
10. **L545-549**: 国コードLineEdit作成（最大2文字）
11. **L573**: _update_tree()で初期表示を更新

#### Step 3: リスト更新処理を理解する

リスト表示とフィルタ処理の核心部分。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | editor_locale_dialog.cpp | `editor/translations/editor_locale_dialog.cpp` | _update_tree()（L252-358）でリスト構築ロジック全体を確認 |

**主要処理フロー**:
- **L256-270**: ProjectSettingsからフィルタ設定を読み込み
- **L276-279**: フィルタ編集モード時のUI状態制御
- **L282-301**: 言語リストの構築（TranslationServer.get_all_languages使用）
- **L304-329**: スクリプトリストの構築（Advancedモード時のみ表示）
- **L332-357**: 国リストの構築

#### Step 4: 選択確定処理を理解する

ロケール文字列の構築と返却処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | editor_locale_dialog.cpp | `editor/translations/editor_locale_dialog.cpp` | ok_pressed()（L58-81）でロケール構築と返却を確認 |

**主要処理フロー**:
- **L59-61**: フィルタ編集モード時は処理中断
- **L63-67**: 言語コード必須チェック
- **L69-77**: スクリプト・国・バリアントコードを連結（アンダースコア区切り）
- **L79**: TranslationServer.standardize_locale()で標準化
- **L80**: locale_selected シグナル発行

### プログラム呼び出し階層図

```
popup_locale_dialog()
    │
    ├─ popup_centered_clamped() [ConfirmationDialog継承]
    │      └─ _post_popup() [オーバーライド]
    │             └─ _update_tree()
    │                    ├─ TranslationServer::get_all_languages()
    │                    ├─ TranslationServer::get_all_scripts()
    │                    └─ TranslationServer::get_all_countries()
    │
    └─ [ユーザー操作]
           │
           ├─ _item_selected() [リスト選択時]
           │
           ├─ _toggle_advanced() [Advancedトグル時]
           │      └─ _update_tree()
           │
           ├─ _edit_filters() [フィルタ編集トグル時]
           │      └─ _update_tree()
           │
           ├─ _filter_mode_changed() [フィルタモード変更時]
           │      ├─ EditorUndoRedoManager::create_action()
           │      ├─ EditorUndoRedoManager::commit_action()
           │      └─ _update_tree()
           │
           ├─ _filter_lang_option_changed() [言語フィルタ変更時]
           │      └─ EditorUndoRedoManager::create_action/commit_action()
           │
           └─ ok_pressed() [Selectボタン押下時]
                  ├─ TranslationServer::standardize_locale()
                  ├─ emit_signal("locale_selected")
                  └─ hide()
```

### データフロー図

```
[入力]                          [処理]                              [出力]

TranslationServer          ─────▶ _update_tree()                ─────▶ lang_list (Tree)
  - get_all_languages()                                                script_list (Tree)
  - get_all_scripts()                                                  cnt_list (Tree)
  - get_all_countries()

ProjectSettings            ─────▶ _update_tree()                ─────▶ フィルタ適用済みリスト
  - language_filter                                                    表示/非表示制御
  - script_filter
  - country_filter
  - locale_filter_mode

ユーザー選択              ─────▶ _item_selected()              ─────▶ lang_code (LineEdit)
  - lang_list選択                                                      script_code (LineEdit)
  - script_list選択                                                    country_code (LineEdit)
  - cnt_list選択

LineEdit入力値            ─────▶ ok_pressed()                  ─────▶ locale_selected シグナル
  - lang_code                     └─ standardize_locale()              └─ 標準化されたロケール文字列
  - script_code                                                           (例: "ja_JP")
  - country_code
  - variant_code
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| editor_locale_dialog.cpp | `editor/translations/editor_locale_dialog.cpp` | ソース | ロケールダイアログの実装 |
| editor_locale_dialog.h | `editor/translations/editor_locale_dialog.h` | ヘッダ | ロケールダイアログのクラス定義 |
| translation_server.cpp | `core/string/translation_server.cpp` | ソース | ロケールデータの提供元 |
| translation_server.h | `core/string/translation_server.h` | ヘッダ | TranslationServerクラス定義 |
| project_settings.cpp | `core/config/project_settings.cpp` | ソース | プロジェクト設定の読み書き |
| editor_undo_redo_manager.cpp | `editor/editor_undo_redo_manager.cpp` | ソース | Undo/Redo管理 |
| dialogs.h | `scene/gui/dialogs.h` | ヘッダ | ConfirmationDialog基底クラス |
| tree.h | `scene/gui/tree.h` | ヘッダ | Treeウィジェット |
| line_edit.h | `scene/gui/line_edit.h` | ヘッダ | LineEditウィジェット |
| option_button.h | `scene/gui/option_button.h` | ヘッダ | OptionButtonウィジェット |
