# 通知設計書 10-CloseAllDialog

## 概要

本ドキュメントは、Windows Terminal における全タブ閉じ確認ダイアログ（CloseAllDialog）の設計仕様を定義する。ユーザーがウィンドウを閉じる際に複数タブが開いている場合に表示される確認用モーダルダイアログである。

### 本通知の処理概要

CloseAllDialog は、ユーザーがウィンドウを閉じる操作（`closeWindow` アクション等）を実行した際に、複数のタブが開いている場合に全タブを閉じてよいかの確認をモーダルダイアログで行う通知機能である。

**業務上の目的・背景**：Windows Terminal では1つのウィンドウに複数のタブを開くことができる。ウィンドウを閉じると全タブが一括で閉じられるため、意図しないタブの消失を防止する目的で確認ダイアログを表示する。これはブラウザ等で一般的な「複数タブを閉じますか?」の確認パターンに準じた UX である。

**通知の送信タイミング**：ユーザーが `closeWindow` アクション（ウィンドウ閉じ操作、キーバインド等）を実行した時に、`CloseWindow()` メソッド内で以下の条件が全て満たされた場合に `_ShowCloseWarningDialog()` が呼び出される。(1) 複数タブが開いている（`_HasMultipleTabs()`）。(2) `ConfirmCloseAllTabs` 設定が有効。(3) `_displayingCloseDialog` が false。

**通知の受信者**：ウィンドウ閉じ操作を実行したユーザー自身。モーダルダイアログとして表示される。

**通知内容の概要**：`x:Uid="CloseAllDialog"` で指定されたローカライズ文字列により、複数タブを閉じる旨の確認メッセージが表示される。DefaultButton は Primary（OK/はい）。

**期待されるアクション**：ユーザーは Primary ボタンで全タブ閉じを確定するか、Secondary/Close ボタンでキャンセルする。Primary が選択された場合、`CloseWindowRequested` イベントが raise され、ウィンドウの閉じ処理が続行される。

## 通知種別

アプリ内通知（ContentDialog ベースのモーダルダイアログ）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（`co_await` によるダイアログ結果待機） |
| 優先度 | 高（データ損失防止の確認） |
| リトライ | 無し |

### 送信先決定ロジック

closeWindow アクションを実行したウィンドウの TerminalPage に表示される。

## 通知テンプレート

### モーダルダイアログ（ContentDialog）の場合

| 項目 | 内容 |
|-----|------|
| UIコントロール | `ContentDialog` |
| 名前 | `CloseAllDialog` |
| x:Uid | `CloseAllDialog`（ローカライズキー） |
| DefaultButton | Primary |

### 本文テンプレート

```
Title: {CloseAllDialog.Title ローカライズ文字列}
Content: {CloseAllDialog.Content ローカライズ文字列}
PrimaryButton: {CloseAllDialog.PrimaryButtonText ローカライズ文字列}
SecondaryButton/CloseButton: {CloseAllDialog.CloseButtonText ローカライズ文字列}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| (x:Uid) | ダイアログのタイトル、本文、ボタンテキスト | CloseAllDialog ローカライズリソース | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ユーザーアクション | `closeWindow` アクション | _HasMultipleTabs() かつ ConfirmCloseAllTabs 設定が有効 かつ _displayingCloseDialog が false | 複数タブを閉じる際の確認ダイアログ |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| タブが1つだけ | _HasMultipleTabs() が false の場合、確認なしで閉じる |
| ConfirmCloseAllTabs 設定が無効 | グローバル設定で無効化されている場合、確認なしで閉じる |
| _displayingCloseDialog が true | 別の終了確認ダイアログが既に表示中の場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ユーザーがcloseWindowアクション実行] --> B[_HandleCloseWindow]
    B --> C[CloseWindow]
    C --> D{複数タブあり?}
    D -->|No| E[確認なしでCloseWindowRequested.raise]
    D -->|Yes| F{ConfirmCloseAllTabs有効?}
    F -->|No| E
    F -->|Yes| G{_displayingCloseDialog?}
    G -->|Yes| H[スキップ]
    G -->|No| I[新しいタブボタンのFlyout非表示]
    I --> J[タブコンテキストメニュー非表示]
    J --> K[_displayingCloseDialog = true]
    K --> L[_ShowCloseWarningDialog]
    L --> M[_ShowDialogHelper L:CloseAllDialog]
    M --> N[FindName でContentDialog取得]
    N --> O[presenter.ShowDialog]
    O --> P{ユーザー選択}
    P -->|Primary| Q[_displayingCloseDialog = false]
    Q --> R[CloseWindowRequested.raise]
    P -->|その他| S[_displayingCloseDialog = false]
    S --> T[閉じ操作キャンセル]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 弱参照消失 | co_await 後に TerminalPage が破棄されている場合 | 暗黙のコルーチン終了 |
| ダイアログプレゼンター無効 | presenter が取得できない場合 | ダイアログが表示されない |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限 | 同時に1つのみ（_displayingCloseDialog フラグ制御） |

### 配信時間帯

制限なし

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

特になし。タブ閉じの確認のみのダイアログであり、機密情報は含まれない。

## 備考

- CloseAllDialog は QuitDialog（No.9）と同じ `_ShowDialogHelper` メソッドを使用する。
- `_displayingCloseDialog` フラグは QuitDialog と CloseAllDialog で共有されており、排他制御を実現する。
- ダイアログ表示前に、新しいタブボタンの Flyout とタブコンテキストメニューを非表示にするクリーンアップ処理が行われる（行2313-2317）。
- `ConfirmCloseAllTabs` はグローバル設定であり、ユーザーが settings.json で制御できる。
- Primary ボタンが選択された場合のみ `CloseWindowRequested` イベントが raise される。このイベントはウィンドウの閉じ処理を続行する。
- タブが1つしかない場合は確認なしでウィンドウが閉じられる。
- `x:Load="False"` により遅延ロード対象。Grid.Row="2" に配置される。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | `_displayingCloseDialog` フラグの宣言を確認 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | `_HandleCloseWindow` メソッド（行119-124）。`CloseWindow()` を呼び出す |

**主要処理フロー**:
1. **行122**: `CloseWindow()` を呼び出す
2. **行123**: `args.Handled(true)` でアクション処理済みとマーク

#### Step 3: ダイアログ表示処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `CloseWindow()` メソッド（行2307-2329）。複数タブチェック、ConfirmCloseAllTabs チェック、Flyout 非表示、_ShowCloseWarningDialog 呼び出し、結果処理 |
| 3-2 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `_ShowCloseWarningDialog()` メソッド（行905-908）。_ShowDialogHelper("CloseAllDialog") を呼び出す |
| 3-3 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `_ShowDialogHelper()` メソッド（行878-884）。FindName と presenter.ShowDialog による共通ダイアログ表示 |

**主要処理フロー**:
- **行2309-2311**: `_HasMultipleTabs()` && `ConfirmCloseAllTabs()` && `!_displayingCloseDialog` チェック
- **行2313-2316**: 新しいタブボタン Flyout 非表示 & タブコンテキストメニュー Dismiss
- **行2318**: `_displayingCloseDialog = true`
- **行2319**: `co_await _ShowCloseWarningDialog()` でダイアログ表示と結果待機
- **行2322**: `ContentDialogResult::Primary` でなければ co_return（キャンセル）
- **行2328**: Primary の場合 `CloseWindowRequested.raise` でウィンドウ閉じ要求

#### Step 4: XAML定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TerminalPage.xaml | `src/cascadia/TerminalApp/TerminalPage.xaml` | `CloseAllDialog` ContentDialog の定義（行95-99）。x:Uid, DefaultButton を確認 |

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

```
ユーザーアクション (closeWindow)
    |
    +-- AppActionHandlers::_HandleCloseWindow (行119)
           |
           +-- TerminalPage::CloseWindow() (行2307)
                  |
                  +-- [_HasMultipleTabs() チェック] (行2309)
                  +-- [ConfirmCloseAllTabs() チェック] (行2310)
                  +-- [_displayingCloseDialog チェック] (行2311)
                  +-- _newTabButton.Flyout().Hide() (行2315)
                  +-- _DismissTabContextMenus() (行2317)
                  +-- _displayingCloseDialog = true (行2318)
                  +-- _ShowCloseWarningDialog() (行2319)
                  |      |
                  |      +-- _ShowDialogHelper("CloseAllDialog") (行907)
                  |             |
                  |             +-- FindName("CloseAllDialog") (行882)
                  |             +-- presenter.ShowDialog() (行882)
                  |
                  +-- [ダイアログ結果待機]
                  +-- _displayingCloseDialog = false (行2320)
                  +-- [Primary の場合] CloseWindowRequested.raise() (行2328)
```

### データフロー図

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

closeWindow アクション    CloseWindow()                       ContentDialog 表示
                   --->  条件チェック                    --->  (モーダル確認)
                         _ShowCloseWarningDialog()

ユーザー選択              結果判定                             CloseWindowRequested
(Primary/Cancel)    --> ContentDialogResult チェック    -->  イベント (Primary時のみ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TerminalPage.xaml | `src/cascadia/TerminalApp/TerminalPage.xaml` | XAML | CloseAllDialog のUI定義 |
| TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | ソース | CloseWindow, _ShowCloseWarningDialog, _ShowDialogHelper の実装 |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ソース | _displayingCloseDialog メンバ宣言 |
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleCloseWindow アクションハンドラ |
