# 機能設計書 2-タブの複製

## 概要

本ドキュメントは、Windows Terminal における「タブの複製」機能の設計を記述する。現在フォーカスされているタブを複製し、同じプロファイル設定で新しいタブを作成する機能の詳細を定義する。

### 本機能の処理概要

**業務上の目的・背景**：ユーザーが現在作業中のターミナル環境と同一の設定（プロファイル、作業ディレクトリ等）で新しいセッションを素早く開始したい場合がある。タブの複製機能により、既存のタブの設定を手動で再入力することなく、同一環境の新しいタブを即座に作成できる。

**機能の利用シーン**：同じプロファイル・同じ作業ディレクトリで別のコマンドを実行したい場合や、現在の作業を中断せずに並行作業を開始したい場合に使用される。キーボードショートカットやコマンドパレットから実行される。

**主要な処理内容**：
1. DuplicateTab アクションの受信
2. 現在フォーカスされているタブの取得
3. フォーカスタブのプロファイル設定を基にペインを作成
4. 新しいタブオブジェクトの作成と初期化
5. 元タブのカスタムタブ名の引き継ぎ
6. タブバーへの挿入とフォーカス設定

**関連システム・外部連携**：ConPTY を介した新しいシェルプロセスの起動、プロファイル設定の参照がある。

**権限による制御**：特別な権限制御はない。元タブのプロファイルが昇格設定を持つ場合、複製タブにも同じ設定が適用される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleDuplicateTab により現在のタブを複製する |

## 機能種別

CRUD操作（タブの作成） / プロセス管理（シェルプロセスの起動）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| (なし) | - | - | DuplicateTab アクションは追加のパラメータを受け取らない。現在フォーカスされたタブが暗黙的な入力となる | フォーカスされたタブが存在すること |

### 入力データソース

- 現在フォーカスされたタブ（_GetFocusedTabImpl() により取得）
- フォーカスタブのプロファイル設定
- フォーカスタブのカスタムタブ名（設定されている場合）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 新規タブ | TerminalApp::Tab | 複製された新しいタブオブジェクト |
| タブViewItem | MUX::Controls::TabViewItem | タブバーに表示されるUIエレメント |

### 出力先

- タブバー（TabView）への新規タブアイテムの追加
- タブ管理リスト（_tabs, _mruTabs）への登録

## 処理フロー

### 処理シーケンス

```
1. _HandleDuplicateTab がアクションイベントを受信
   └─ 引数は使用しない
2. _DuplicateFocusedTab の呼び出し
   └─ _GetFocusedTabImpl() で現在のフォーカスタブを取得
   └─ フォーカスタブが存在しない場合は処理を中断
3. _DuplicateTab の呼び出し
   └─ タブ挿入位置の計算
   └─ _MakePane(nullptr, tab, nullptr) でペインを作成（元タブの設定を引き継ぎ）
   └─ _CreateNewTabFromPane で新しいタブを作成
4. カスタムタブ名の引き継ぎ
   └─ 元タブにカスタム名が設定されている場合、新しいタブにも同じ名前を設定
```

### フローチャート

```mermaid
flowchart TD
    A[_HandleDuplicateTab 受信] --> B[_DuplicateFocusedTab]
    B --> C{フォーカスタブが存在?}
    C -->|No| D[処理終了]
    C -->|Yes| E[_DuplicateTab 呼び出し]
    E --> F[挿入位置の計算]
    F --> G[_MakePane で元タブ設定からペイン作成]
    G --> H[_CreateNewTabFromPane]
    H --> I{元タブにカスタム名あり?}
    I -->|Yes| J[新タブにカスタム名を設定]
    I -->|No| K[処理完了]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | フォーカスタブ必須 | フォーカスされたタブが存在しない場合、複製は行わない | _GetFocusedTabImpl() が null を返した場合 |
| BR-02 | タブ挿入位置 | NewTabPosition が AfterCurrentTab の場合、元タブの直後に挿入。それ以外は末尾 | 常時 |
| BR-03 | カスタム名引き継ぎ | 元タブにユーザー設定のカスタムタブ名がある場合、複製先にも同じ名前を設定する | 元タブの GetTabText() が空でない場合 |
| BR-04 | プロファイル設定の複製 | 元タブの完全なプロファイル設定が新しいタブに適用される | 常時 |

### 計算ロジック

タブ挿入位置の算出：
- `NewTabPosition == AfterCurrentTab` の場合: `insertPosition = tab.TabViewIndex() + 1`
- それ以外の場合: `insertPosition = _tabs.Size()`（末尾）

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

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| (なし) | フォーカスタブ不在 | _GetFocusedTabImpl() が null | 処理をスキップ（ログなし） |
| CATCH_LOG | 例外発生 | _DuplicateTab 内で例外が発生 | 例外をログに記録して処理を中断 |

### リトライ仕様

リトライは行わない。

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

トランザクション管理は不要。

## パフォーマンス要件

タブの複製はユーザー操作に応じた同期処理であり、新しいシェルプロセスの起動を含めて迅速に完了する必要がある。

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

複製元タブのプロファイルに昇格設定が含まれる場合、複製先にも同様の権限で起動される。

## 備考

- `_MakePane(nullptr, tab, nullptr)` の第二引数にソースタブを渡すことで、元タブの設定が複製される
- TODO: GH#5047 - プロファイル全体を複製しているが、古い設定への参照が残る可能性がある。将来的には VT 経由で変更されたライブ設定の複製が望ましい

---

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

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

### 推奨読解順序

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

DuplicateTab アクションには専用の引数クラスがなく、暗黙的にフォーカスタブを使用する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | DuplicateTab アクション自体は引数なし。NewTabPosition 等の関連設定を確認 |

**読解のコツ**: DuplicateTab は ActionEventArgs のみを受け取り、追加のアクション引数を持たない点に注意。処理対象は `_GetFocusedTabImpl()` で暗黙的に決定される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | _HandleDuplicateTab（64-69行目）がエントリーポイント |

**主要処理フロー**:
1. **64-65行目**: _HandleDuplicateTab の定義
2. **67行目**: `_DuplicateFocusedTab()` を呼び出し
3. **68行目**: `args.Handled(true)` でアクション処理済みを通知

#### Step 3: タブ複製ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TabManagement.cpp | `src/cascadia/TerminalApp/TabManagement.cpp` | _DuplicateFocusedTab（266-272行目）、_DuplicateTab（278-305行目） |

**主要処理フロー**:
- **266-272行目**: _DuplicateFocusedTab - フォーカスタブを取得して _DuplicateTab に渡す
- **268行目**: `_GetFocusedTabImpl()` でフォーカスタブを取得
- **278-305行目**: _DuplicateTab - 実際の複製処理
- **288-292行目**: 挿入位置の計算。NewTabPosition::AfterCurrentTab なら元タブの直後
- **293行目**: `_MakePane(nullptr, tab, nullptr)` で元タブの設定からペインを作成
- **295-302行目**: 元タブのカスタム名が存在する場合、新しいタブにも設定

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

```
_HandleDuplicateTab (AppActionHandlers.cpp:64)
    |
    +-- _DuplicateFocusedTab (TabManagement.cpp:266)
            |
            +-- _GetFocusedTabImpl() -- フォーカスタブ取得
            |
            +-- _DuplicateTab (TabManagement.cpp:278)
                    |
                    +-- _MakePane(nullptr, tab, nullptr) -- 元タブ設定でペイン作成
                    |
                    +-- _CreateNewTabFromPane() -- タブ作成
                    |       |
                    |       +-- _InitializeTab() -- タブ初期化
                    |
                    +-- tab.GetTabText() -- カスタム名取得
                    |
                    +-- newTab->SetTabText() -- カスタム名設定（条件付き）
```

### データフロー図

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

フォーカスタブ -----------> _DuplicateFocusedTab
  (プロファイル設定)          |
  (カスタムタブ名)         _DuplicateTab
                              |
                           _MakePane ---------> Pane（複製）
                              |
                           _CreateNewTabFromPane --> Tab
                              |                      |
                           SetTabText（条件付き）     +-> _tabs
                                                      +-> _mruTabs
                                                      +-> TabView
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleDuplicateTab エントリーポイント |
| TabManagement.cpp | `src/cascadia/TerminalApp/TabManagement.cpp` | ソース | _DuplicateFocusedTab, _DuplicateTab の実装 |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ヘッダー | TerminalPage クラスのメソッド宣言 |
| TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | ソース | _MakePane 等のユーティリティ |
