# 機能設計書 32-テキストの貼り付け

## 概要

本ドキュメントは、Windows Terminal における「テキストの貼り付け」機能（PasteText アクション）の設計を記述する。Windows システムクリップボードの内容をターミナルに貼り付ける機能であり、ブロードキャスト入力モードへの対応、ブラケットペースト、フィルタリング処理を含む。

### 本機能の処理概要

**業務上の目的・背景**：ターミナルエミュレータにおけるテキスト貼り付けは、コマンドの入力、スクリプトの実行、パスの入力など日常的に使用される基本操作である。Windows Terminal では安全性を考慮し、複数行や大量テキストの貼り付け時に確認ダイアログを表示する機能、およびブラケットペーストモード対応を提供している。

**機能の利用シーン**：ユーザーが Ctrl+V やキーバインドを押下したとき、またはコンテキストメニューから「貼り付け」を選択したとき、マウス右クリック時（設定による）に実行される。コマンドの入力補助、ファイルパスの入力、コピーしたテキストの実行などに利用される。

**主要な処理内容**：
1. _HandlePasteText でアクションを受信し、_PasteText を呼び出す
2. ブロードキャスト入力モードの確認（有効な場合は全ペインに貼り付け）
3. TermControl.PasteTextFromClipboard を呼び出し
4. ControlInteractivity.RequestPasteTextFromClipboard でクリップボード読み取りイベントを発火
5. PasteFromClipboard イベントハンドラ経由で ControlCore.PasteText を呼び出し
6. テキストのフィルタリング（改行変換・制御コード除去）
7. ブラケットペーストシーケンスの付加（対応アプリの場合）
8. SendInput でターミナル接続にテキストを送信
9. 選択状態の解除とスナップ処理

**関連システム・外部連携**：Windows システムクリップボード API からテキストを読み取る。ブラケットペーストモード（ESC[200~ / ESC[201~）対応のシェルやエディタと連携する。

**権限による制御**：読み取り専用モード（_isReadOnly）の場合、貼り付けは拒否され読み取り専用警告が表示される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandlePasteText / _PasteText でアクションを処理 |
| 6 | TermControl（ターミナル表示） | 主画面 | PasteCommandButtonによりテキストを貼り付け |
| 17 | MultiLinePasteDialog（複数行貼り付け確認） | 確認画面 | 複数行テキスト貼り付け時の確認ダイアログ |
| 18 | LargePasteDialog（大量貼り付け確認） | 確認画面 | 大量テキスト貼り付け時の確認ダイアログ |

## 機能種別

テキスト操作 / クリップボード操作

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- Windows システムクリップボードのテキストデータ
- ブロードキャスト入力モード状態（タブの TabStatus.IsInputBroadcastActive）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | - | クリップボードテキストがターミナル接続に送信される |

### 出力先

- ターミナル接続（ConPTY等）を経由してシェルプロセスの標準入力

## 処理フロー

### 処理シーケンス

```
1. _HandlePasteText が ActionEventArgs を受信
   └─ _PasteText() を呼び出し、handled を true に設定
2. _PasteText でブロードキャスト入力モードを確認
   ├─ ブロードキャスト有効: 全ペインの TermControl に PasteTextFromClipboard を実行
   └─ ブロードキャスト無効: アクティブコントロールのみに PasteTextFromClipboard を実行
3. TermControl.PasteTextFromClipboard
   └─ ControlInteractivity.RequestPasteTextFromClipboard を呼び出し
4. ControlInteractivity.RequestPasteTextFromClipboard
   └─ PasteFromClipboardEventArgs を作成（コールバック関数とブラケットペーストフラグを含む）
   └─ PasteFromClipboard イベントを発火
5. イベントハンドラ（TermApp側）がクリップボードからテキストを取得
   └─ コールバック経由で ControlCore.PasteText を呼び出し
6. ControlCore.PasteText
   └─ FilterStringForPaste でテキストをフィルタリング（改行変換・制御コード除去）
   └─ ブラケットペーストモード有効時: ESC[200~ と ESC[201~ でテキストを囲む
   └─ SendInput でターミナル接続にテキストを送信
7. 後処理
   └─ 選択状態をクリア
   └─ TrySnapOnInput でスクロール位置を末尾に移動
```

### フローチャート

```mermaid
flowchart TD
    A[PasteText アクション受信] --> B[_PasteText 呼び出し]
    B --> C{ブロードキャスト入力モード?}
    C -->|Yes| D[全ペインに PasteTextFromClipboard]
    C -->|No| E[アクティブコントロールに PasteTextFromClipboard]
    D --> F[ControlInteractivity.RequestPasteTextFromClipboard]
    E --> F
    F --> G[PasteFromClipboard イベント発火]
    G --> H[クリップボードからテキスト取得]
    H --> I[ControlCore.PasteText]
    I --> J[FilterStringForPaste でフィルタリング]
    J --> K{ブラケットペーストモード有効?}
    K -->|Yes| L["ESC[200~ + テキスト + ESC[201~"]
    K -->|No| M[フィルタ済みテキストそのまま]
    L --> N[SendInput でターミナルに送信]
    M --> N
    N --> O[選択クリア + スクロールスナップ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-32-01 | ブロードキャスト入力モード | ブロードキャスト入力が有効なタブでは、全ペインに同時に貼り付けが行われる | IsInputBroadcastActive が true |
| BR-32-02 | 読み取り専用チェック | 読み取り専用モードのペインでは貼り付けが拒否され、警告が表示される | _isReadOnly が true |
| BR-32-03 | テキストフィルタリング | 貼り付けテキストから CRLF 変換と制御コードが除去される | 常に適用 |
| BR-32-04 | ブラケットペースト | ブラケットペーストモード対応アプリの場合、テキストを ESC[200~ と ESC[201~ で囲む | BracketedPasteEnabled が true |

### 計算ロジック

なし

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 読み取り専用 | 読み取り専用モードで貼り付けを実行 | 読み取り専用警告を表示し、貼り付けを拒否 |
| - | クリップボード空 | クリップボードにテキストが存在しない | 何も送信しない（wstr が空の場合 SendInput が早期リターン） |
| - | 接続切断 | ターミナル接続が切断されている | 接続状態に応じた処理（Ctrl+D で閉じ、Enter で再起動） |

### リトライ仕様

リトライは行わない。

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

ControlCore.PasteText ではテキスト送信時にはロックを保持しない（ブロック回避のため）。送信後に LockForWriting を取得して選択クリアとスナップ処理を行う。

## パフォーマンス要件

大量テキストの貼り付け時にUIスレッドをブロックしないこと。テキスト送信は接続経由で行われるため、WriteFile がブロックする可能性がある。

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

- 複数行テキストの貼り付け時に確認ダイアログを表示する設定がある（MultiLinePasteDialog）
- 大量テキストの貼り付け時に確認ダイアログを表示する設定がある（LargePasteDialog）
- 制御コードのフィルタリングにより、悪意あるクリップボードコンテンツからの保護を提供

## 備考

- PasteText アクションにはパラメータがなく、常にシステムクリップボードからテキストを取得する
- ブラケットペーストモードは vim や readline などの対応アプリケーションで、貼り付けテキストと手入力テキストを区別するために使用される
- フィルタリングでは CarriageReturnNewline フラグと ControlCodes フラグを使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | PasteText はパラメータなしのアクション |

**読解のコツ**: PasteText は ActionArgs を持たない単純なアクションであり、クリップボードから直接テキストを取得する設計となっている。

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

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

**主要処理フロー**:
1. **452-457行目**: _PasteText() を呼び出し、handled を true に設定

#### Step 3: TerminalPage のペースト処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | _PasteText メソッドでブロードキャスト入力対応 |

**主要処理フロー**:
- **3359-3383行目**: ブロードキャスト入力モードの場合は全ペインの WalkTree で貼り付け、それ以外はアクティブコントロールのみ
- **3365行目**: TabStatus().IsInputBroadcastActive() でブロードキャスト確認
- **3367-3372行目**: WalkTree で全ペインに PasteTextFromClipboard 呼び出し

#### Step 4: ControlInteractivity 層

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ControlInteractivity.cpp | `src/cascadia/TerminalControl/ControlInteractivity.cpp` | RequestPasteTextFromClipboard でイベント発火 |

**主要処理フロー**:
- **225-235行目**: PasteFromClipboardEventArgs を作成し、コールバック関数（core->PasteText）とブラケットペーストフラグを含めてイベント発火

#### Step 5: ControlCore のテキスト送信

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | PasteText でフィルタリングとブラケットペースト処理 |

**主要処理フロー**:
- **1442-1459行目**: FilterStringForPaste でフィルタリング、ブラケットペーストシーケンスの付加、SendInput での送信、選択クリアとスナップ

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

```
TerminalPage::_HandlePasteText (AppActionHandlers.cpp:452)
    |
    +-- TerminalPage::_PasteText (TerminalPage.cpp:3359)
           |
           +-- [ブロードキャスト時] WalkTree -> TermControl::PasteTextFromClipboard
           +-- [通常時] TermControl::PasteTextFromClipboard (TermControl.cpp:2563)
                  |
                  +-- ControlInteractivity::RequestPasteTextFromClipboard (ControlInteractivity.cpp:225)
                         |
                         +-- PasteFromClipboard イベント発火
                                |
                                +-- [コールバック] ControlCore::PasteText (ControlCore.cpp:1442)
                                       |
                                       +-- FilterStringForPaste
                                       +-- SendInput (ControlCore.cpp:489)
                                       |      |
                                       |      +-- _sendInputToConnection
                                       +-- Terminal::ClearSelection
                                       +-- Terminal::TrySnapOnInput
```

### データフロー図

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

システムクリップ     --> PasteFromClipboard イベント       --> テキスト取得
ボードテキスト          |
                        v
                    FilterStringForPaste                  --> フィルタ済みテキスト
                        |
                        v
                    ブラケットペースト付加（条件付き）      --> 最終テキスト
                        |                                      |
                        v                                      v
                    SendInput                             --> ターミナル接続
                                                              (シェルの標準入力)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandlePasteText アクションハンドラ |
| TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | ソース | _PasteText 実装（ブロードキャスト対応） |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ヘッダ | _PasteText メソッド宣言 |
| TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | ソース | PasteTextFromClipboard の実装 |
| TermControl.h | `src/cascadia/TerminalControl/TermControl.h` | ヘッダ | PasteTextFromClipboard 宣言 |
| ControlInteractivity.cpp | `src/cascadia/TerminalControl/ControlInteractivity.cpp` | ソース | RequestPasteTextFromClipboard のイベント発火 |
| ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | ソース | PasteText のフィルタリング・送信処理 |
