# 機能設計書 36-ブロック選択切替

## 概要

本ドキュメントは、Windows Terminal における「ブロック選択切替」機能（ToggleBlockSelection アクション）の設計を記述する。テキスト選択の方式を通常の行単位選択と矩形（ブロック）選択の間で切り替える機能である。

### 本機能の処理概要

**業務上の目的・背景**：ターミナル上のテキストを矩形範囲で選択する機能を提供する。ログファイルやテーブル形式の出力から特定の列を選択してコピーする場合に有用である。Alt キーを押しながらのマウス選択でもブロック選択は可能だが、本機能はキーボードからの切り替えを提供する。

**機能の利用シーン**：テキストを選択中に、通常の行単位選択から矩形選択に切り替えたい場合に使用する。例えば、テーブル形式の出力で特定の列のデータだけを選択してコピーする場合などに利用される。

**主要な処理内容**：
1. _HandleToggleBlockSelection でアクションを受信
2. TermControl.ToggleBlockSelection を呼び出し
3. ControlCore 経由で Terminal の blockSelection フラグを切り替え
4. レンダラーの選択表示をトリガー

**関連システム・外部連携**：なし

**権限による制御**：なし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | TermControl（ターミナル表示） | 主画面 | ToggleBlockSelection により矩形選択モードを切替 |
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleToggleBlockSelection でアクションを処理 |

## 機能種別

テキスト操作 / 選択モード制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| (なし) | - | - | ToggleBlockSelection アクションはパラメータを持たない | - |

### 入力データソース

- 現在の選択状態（IsSelectionActive）
- 現在のブロック選択状態（IsBlockSelection）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | - | 選択モードが切り替わり、選択表示が更新される |

### 出力先

- Terminal の blockSelection フラグ
- レンダラーの選択表示

## 処理フロー

### 処理シーケンス

```
1. _HandleToggleBlockSelection が sender と ActionEventArgs を受信
   └─ _senderOrActiveControl で TermControl を取得
2. TermControl.ToggleBlockSelection → ControlCore.ToggleBlockSelection
   └─ LockForWriting でロック取得
3. ControlCore.ToggleBlockSelection
   └─ 選択がアクティブか確認
   ├─ [選択なし] → false を返す
   └─ [選択あり] → blockSelection フラグを反転
       └─ _renderer->TriggerSelection() で選択表示を再描画
       └─ true を返す
4. 戻り値が handled に設定される
```

### フローチャート

```mermaid
flowchart TD
    A[ToggleBlockSelection アクション受信] --> B[_senderOrActiveControl で TermControl 取得]
    B --> C{TermControl 取得成功?}
    C -->|No| Z[何もしない]
    C -->|Yes| D[ControlCore.ToggleBlockSelection]
    D --> E[LockForWriting でロック取得]
    E --> F{選択がアクティブ?}
    F -->|No| G[false を返す]
    F -->|Yes| H[blockSelection = !blockSelection]
    H --> I[_renderer->TriggerSelection]
    I --> J[true を返す]
    G --> K[handled 設定]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-36-01 | 選択必須 | 選択がアクティブでない場合はブロック選択の切り替えができない（false を返す） | IsSelectionActive が false |
| BR-36-02 | トグル動作 | 現在のブロック選択状態を反転する（ブロック選択 → 行選択、行選択 → ブロック選択） | 常に適用 |
| BR-36-03 | 選択マーカー維持 | 選択マーカーが表示されている場合はその状態を維持する | 常に適用 |

### 計算ロジック

なし

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

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 選択なし | テキストが選択されていない状態で実行 | false を返し、アクションを未処理とする |
| - | コントロール未取得 | アクティブな TermControl がない | 何もしない |

### リトライ仕様

リトライは行わない。

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

ToggleBlockSelection の実行中は LockForWriting でロックを保持する。

## パフォーマンス要件

即座にモード切替と選択表示の更新が完了すること。

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

特になし。

## 備考

- ブロック選択は矩形の範囲でテキストを選択する（各行の同じ列位置が選択される）
- Alt キーを押しながらのマウスドラッグでもブロック選択が可能
- ブロック選択で選択したテキストのコピー時には、各行が個別に扱われる
- 選択マーカーの表示状態は変更しない（表示中なら表示のまま、非表示なら非表示のまま）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | _HandleToggleBlockSelection がエントリーポイント |

**主要処理フロー**:
1. **1427-1435行目**: _senderOrActiveControl で TermControl を取得し、control.ToggleBlockSelection() を呼び出す。戻り値を handled に設定。

#### Step 2: TermControl / ControlCore 層

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | ToggleBlockSelection で ControlCore に委譲 |
| 2-2 | ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | ToggleBlockSelection の実装 |

**主要処理フロー**:
- **2573-2576行目**（TermControl.cpp）: _core.ToggleBlockSelection() を呼び出す
- **1388-1401行目**（ControlCore.cpp）: LockForWriting、選択アクティブ確認、blockSelection フラグ反転、TriggerSelection で再描画

#### Step 3: Terminal コア層

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TerminalSelection.cpp | `src/cascadia/TerminalCore/TerminalSelection.cpp` | SetBlockSelection の実装 |

**主要処理フロー**:
- **344-347行目**: _selection.write()->blockSelection = isEnabled でフラグ設定

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

```
TerminalPage::_HandleToggleBlockSelection (AppActionHandlers.cpp:1427)
    |
    +-- TermControl::ToggleBlockSelection (TermControl.cpp:2573)
           |
           +-- ControlCore::ToggleBlockSelection (ControlCore.cpp:1388)
                  |
                  +-- Terminal::IsSelectionActive (選択チェック)
                  +-- Terminal::IsBlockSelection (現在のブロック選択状態取得)
                  +-- Terminal::SetBlockSelection (フラグ設定)
                  +-- _renderer->TriggerSelection (再描画)
```

### データフロー図

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

現在の選択状態        --> ToggleBlockSelection            --> blockSelection フラグ更新
                          |
                          v
IsBlockSelection     --> !IsBlockSelection               --> TriggerSelection
                                                              (選択表示の再描画)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleToggleBlockSelection アクションハンドラ |
| TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | ソース | ToggleBlockSelection の委譲 |
| TermControl.h | `src/cascadia/TerminalControl/TermControl.h` | ヘッダ | ToggleBlockSelection 宣言 |
| ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | ソース | ToggleBlockSelection の実装 |
| TerminalSelection.cpp | `src/cascadia/TerminalCore/TerminalSelection.cpp` | ソース | SetBlockSelection の実装 |
| Terminal.hpp | `src/cascadia/TerminalCore/Terminal.hpp` | ヘッダ | SetBlockSelection / IsBlockSelection 宣言 |
