# 機能設計書 81-設定を開く

## 概要

本ドキュメントは、Windows Terminal の「設定を開く」機能について、ソースコードに基づいた機能設計を記述するものである。OpenSettings アクションのハンドリングから、設定UIまたは設定ファイルを開くまでの処理フローを解説する。

### 本機能の処理概要

**業務上の目的・背景**：ユーザーが Windows Terminal の動作をカスタマイズするためには、settings.json ファイルの直接編集、またはGUIベースの設定UIを利用する必要がある。本機能は、ユーザーがキーバインドやメニューから素早く設定にアクセスするための入口を提供し、設定変更のワークフローを効率化する。

**機能の利用シーン**：ユーザーがターミナルの外観やプロファイル、キーバインドなどを変更したい場合に、Ctrl+, などのキーバインドやメニューの「設定」ボタンから本機能を呼び出す。設定UI を開く場合と、settings.json や defaults.json をテキストエディタで開く場合がある。

**主要な処理内容**：
1. OpenSettings アクションの受信と SettingsTarget パラメータの解析
2. SettingsTarget に応じた分岐処理（SettingsUI / SettingsFile / DefaultsFile / AllFiles）
3. SettingsUI の場合は SettingsPaneContent を生成し、設定タブとして表示
4. SettingsFile / DefaultsFile の場合は ShellExecute でファイルをデフォルトエディタで開く
5. AllFiles の場合は設定ディレクトリをエクスプローラーで開く

**関連システム・外部連携**：ShellExecute API を使用して外部テキストエディタ（既定は notepad）と連携する。設定UIは TerminalSettingsEditor プロジェクトの MainPage を利用する。

**権限による制御**：特別な権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleOpenSettingsにより設定UIまたはsettings.jsonを開く |
| 21 | MainPage（設定ナビゲーション） | 遷移先画面 | 設定画面のメインコンテナ。ナビゲーションとコンテンツフレームを管理 |

## 機能種別

画面遷移 / 外部アプリケーション起動

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Target | SettingsTarget (enum) | Yes | 開く設定のターゲット種別 | SettingsFile=0, DefaultsFile=1, AllFiles=2, SettingsUI=3 のいずれか |

### 入力データソース

ユーザーのキーバインド操作またはメニュー操作から OpenSettingsArgs が生成される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 設定タブ | SettingsPaneContent | SettingsUI の場合に生成される設定ペインコンテンツ |
| 外部エディタ | HINSTANCE | SettingsFile/DefaultsFile の場合に ShellExecute の戻り値 |

### 出力先

- SettingsUI: TerminalPage 内の新規タブ（設定タブ）
- SettingsFile/DefaultsFile: 外部テキストエディタ
- AllFiles: エクスプローラー

## 処理フロー

### 処理シーケンス

```
1. _HandleOpenSettings がアクションを受信
   └─ ActionEventArgs から OpenSettingsArgs を取得
2. OpenSettingsArgs.Target() で SettingsTarget を判定
   └─ SettingsTarget::SettingsUI の場合 → ステップ 3a
   └─ SettingsFile / DefaultsFile / AllFiles の場合 → ステップ 3b
3a. OpenSettingsUI() を呼び出す
   └─ 既存の設定タブがあればそのタブにフォーカス
   └─ なければ SettingsPaneContent を生成し、設定タブを追加
4a. SettingsPaneContent が MainPage を初期化
   └─ _settingsClone に設定のコピーを作成
   └─ NavigationView でページ遷移を管理
3b. バックグラウンドスレッドに切り替え
   └─ co_await winrt::resume_background()
4b. ShellExecute で設定ファイルを開く
   └─ ShellExecute が失敗した場合は notepad にフォールバック
   └─ AllFiles の場合はフォルダを開く
```

### フローチャート

```mermaid
flowchart TD
    A[OpenSettings アクション受信] --> B{SettingsTarget?}
    B -->|SettingsUI| C{既存の設定タブあり?}
    C -->|Yes| D[既存タブにフォーカス]
    C -->|No| E[SettingsPaneContent 生成]
    E --> F[設定タブを追加・表示]
    B -->|SettingsFile| G[バックグラウンドスレッドへ]
    G --> H[ShellExecute で settings.json を開く]
    H --> I{成功?}
    I -->|No| J[notepad にフォールバック]
    I -->|Yes| K[終了]
    J --> K
    B -->|DefaultsFile| L[バックグラウンドスレッドへ]
    L --> M[ShellExecute で defaults.json を開く]
    B -->|AllFiles| N[バックグラウンドスレッドへ]
    N --> O[設定フォルダを開く]
    D --> K
    F --> K
    M --> K
    O --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-81-01 | 設定タブの一意性 | 設定UIタブは同時に1つだけ存在する | SettingsUI ターゲットの場合 |
| BR-81-02 | バックグラウンドスレッド実行 | ファイルを開く操作はUIスレッドをブロックしないようバックグラウンドで実行 | SettingsFile / DefaultsFile の場合 |
| BR-81-03 | エディタのフォールバック | ShellExecute が失敗した場合、notepad にフォールバックする | SettingsFile / DefaultsFile の場合 |

### 計算ロジック

該当なし。

## データベース操作仕様

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

該当なし（本機能はファイルベースの操作）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ShellExecute失敗 | デフォルトの .json エディタが見つからない場合 | notepad にフォールバック |
| - | ファイル不存在 | settings.json が存在しない場合 | 新規作成またはデフォルト設定を使用 |

### リトライ仕様

リトライ不要。ShellExecute の失敗時は notepad にフォールバック。

## トランザクション仕様

該当なし。

## パフォーマンス要件

ファイルを開く操作は co_await winrt::resume_background() によりバックグラウンドスレッドで実行されるため、UIスレッドのブロッキングは発生しない。

## セキュリティ考慮事項

settings.json はユーザープロファイルディレクトリに保存されており、ユーザー権限の範囲でアクセスされる。

## 備考

- テレメトリ：TraceLoggingWrite により「NewTabMenuItemClicked」イベントが送信され、SettingsTarget の種別が記録される。
- 設定タブのアイコンは歯車アイコン（\xE713）が使用される。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | SettingsTarget enum（86-91行目）と OpenSettingsArgs クラス（275-279行目）の定義を確認 |

**読解のコツ**: IDL ファイルは WinRT のインターフェース定義言語であり、C++/WinRT のランタイムクラス定義を記述する。enum と runtimeclass の関係に注目。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | _HandleOpenSettings メソッド（442-450行目）がアクションのエントリーポイント |

**主要処理フロー**:
1. **442-443行目**: _HandleOpenSettings メソッドの宣言
2. **445行目**: ActionArgs を OpenSettingsArgs にキャスト
3. **447行目**: _LaunchSettings(realArgs.Target()) を呼び出し

#### Step 3: 設定起動処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | _LaunchSettings メソッド（3389-3414行目）で SettingsTarget に応じた分岐処理 |

**主要処理フロー**:
- **3389行目**: _LaunchSettings コルーチンの開始
- **3391-3393行目**: SettingsUI の場合は OpenSettingsUI() を呼び出し
- **3404行目**: ファイルを開く場合はバックグラウンドスレッドに切り替え
- **3406-3412行目**: ShellExecute のラムダ定義。失敗時は notepad にフォールバック

#### Step 4: 設定UIペインを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SettingsPaneContent.h | `src/cascadia/TerminalApp/SettingsPaneContent.h` | 設定ペインの IPaneContent 実装。MainPage をラップ |
| 4-2 | SettingsPaneContent.cpp | `src/cascadia/TerminalApp/SettingsPaneContent.cpp` | コンストラクタ（16-23行目）で MainPage を生成 |

**主要処理フロー**:
- **16-18行目**: SettingsPaneContent コンストラクタで MainPage を初期化
- **54行目**: GetNewTerminalArgs で "settings" 識別子を返す

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

```
TerminalPage::_HandleOpenSettings (AppActionHandlers.cpp:442)
    │
    └─ TerminalPage::_LaunchSettings (TerminalPage.cpp:3389)
           │
           ├─[SettingsUI] TerminalPage::OpenSettingsUI (TerminalPage.cpp:4360)
           │      │
           │      ├─ App::PrepareForSettingsUI
           │      │
           │      └─ SettingsPaneContent::SettingsPaneContent (SettingsPaneContent.cpp:16)
           │             └─ MainPage::MainPage (MainPage.cpp:61)
           │
           ├─[SettingsFile] ShellExecute(settings.json)
           │      └─ [失敗時] ShellExecute(notepad, settings.json)
           │
           ├─[DefaultsFile] ShellExecute(defaults.json)
           │
           └─[AllFiles] ShellExecute(設定ディレクトリ)
```

### データフロー図

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

OpenSettingsArgs ───▶ _HandleOpenSettings ───▶ _LaunchSettings
  (Target)                                          │
                                                    ├──▶ [SettingsUI] 設定タブ表示
                                                    │     SettingsPaneContent → MainPage
                                                    │
                                                    └──▶ [File] ShellExecute
                                                          外部エディタ起動
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | アクションハンドラ（エントリーポイント） |
| TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | ソース | _LaunchSettings / OpenSettingsUI メソッド |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ヘッダ | TerminalPage クラス定義 |
| SettingsPaneContent.h | `src/cascadia/TerminalApp/SettingsPaneContent.h` | ヘッダ | 設定ペインコンテンツクラス定義 |
| SettingsPaneContent.cpp | `src/cascadia/TerminalApp/SettingsPaneContent.cpp` | ソース | 設定ペインコンテンツ実装 |
| ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | IDL | OpenSettingsArgs / SettingsTarget 定義 |
| MainPage.cpp | `src/cascadia/TerminalSettingsEditor/MainPage.cpp` | ソース | 設定UI メインページ実装 |
