# 機能設計書 73-コードエディタ

## 概要

本ドキュメントは、StaxRipアプリケーションの「コードエディタ」機能について、処理内容、入出力仕様、およびコードリーディングガイドを記載する設計書である。

### 本機能の処理概要

コードエディタ機能は、AviSynth/VapourSynthスクリプトを直接編集するためのエディタ機能である。シンタックスハイライト対応のリッチテキストエディタを提供し、フィルタの追加・削除・並べ替えなどの操作をサポートする。

**業務上の目的・背景**：ビデオエンコードにおいて、AviSynth/VapourSynthスクリプトはフィルタ処理の中核を担う。GUI上のフィルタ設定だけでなく、スクリプトを直接編集することで、より柔軟で高度なビデオ処理が可能となる。本機能により、ユーザーはスクリプトの詳細なカスタマイズや、プロファイルに含まれない独自フィルタの適用が可能となる。

**機能の利用シーン**：
- フィルタスクリプトの直接編集・カスタマイズ
- 複数フィルタの結合・整理
- スクリプトのプレビューとデバッグ
- フィルタプロファイルの作成・編集
- mpv.netやMPC-HCでのスクリプト再生

**主要な処理内容**：
1. VideoScriptからフィルタリストをFilterTableとして表示
2. フィルタの追加・挿入・置換・削除
3. フィルタの並べ替え（上下移動）
4. フィルタの有効/無効切り替え
5. スクリプトのコードプレビュー（マクロ展開後）
6. ビデオプレビューとの連携
7. フィルタの結合（アクティブ/非アクティブ/全フィルタ）

**関連システム・外部連携**：
- AviSynth+エンジン
- VapourSynthエンジン
- PreviewForm（ビデオプレビュー）
- mpv.net / MPC-HC（外部プレイヤー）

**権限による制御**：特にロールや権限による制御はなく、すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | CodeForm | 補助画面 | コードビューア（読み取り専用表示） |
| - | CodeEditor | 主画面 | スクリプトコードの編集ダイアログ |

## 機能種別

UI操作 / スクリプト編集 / プレビュー連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| doc | VideoScript | Yes | 編集対象のビデオスクリプト | - |
| Engine | ScriptEngine | Yes | スクリプトエンジン（AviSynth/VapourSynth） | Enum値 |
| Filters | List(Of VideoFilter) | Yes | フィルタリスト | - |

### 入力データソース

- VideoScript（現在のプロジェクトスクリプト）
- FilterProfile（s.AviSynthProfiles, s.VapourSynthProfiles）
- CustomMenu設定（s.CustomMenuCodeEditor）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Filters | List(Of VideoFilter) | 編集後のフィルタリスト |
| DialogResult | DialogResult | OK/Cancel |

### 出力先

- VideoScript.Filters（プロジェクトスクリプト）
- PreviewScript（プレビュー用一時スクリプト）

## 処理フロー

### 処理シーケンス

```
1. CodeEditor インスタンス生成
   └─ InitializeComponent、CommandManager設定、CustomMenu構築
2. FilterTableの初期化
   └─ 各VideoFilterに対応するFilterTableを生成
3. ユーザー操作
   └─ フィルタの編集、追加、削除、並べ替え
4. フィルタ適用（Ctrl+S）
   └─ GetFiltersでFilterTableからフィルタリスト取得
   └─ PreviewScript.Filtersに反映
5. プレビュー表示（F6）
   └─ PreviewFormを開いてスクリプト実行結果を表示
6. OK/Cancel
   └─ DialogResultに応じてフィルタリストを返却
```

### フローチャート

```mermaid
flowchart TD
    A[CodeEditor起動] --> B[VideoScriptからFilterTable生成]
    B --> C[MainFlowLayoutPanelに配置]
    C --> D{ユーザー操作}

    D -->|フィルタ編集| E[rtbScript.Text更新]
    D -->|フィルタ追加| F[Add/Insert/Replaceメニュー]
    D -->|フィルタ削除| G[RemoveFilter]
    D -->|並べ替え| H[MoveFilterUp/Down]
    D -->|結合| I[JoinFilters]

    E --> J[ApplyFilters]
    F --> J
    G --> J
    H --> J
    I --> J

    J --> K[PreviewScript.Filters更新]
    K --> D

    D -->|プレビュー| L[PreviewForm表示]
    D -->|コードプレビュー| M[GetFullScript表示]
    D -->|OK| N[GetFilters返却]
    D -->|Cancel| O[変更破棄]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-01 | 保護カテゴリ | source, crop, cutting, resize, rotationカテゴリのフィルタは結合対象外 | JoinFilters実行時 |
| BR-73-02 | 単一フィルタ結合不可 | 結合対象が1件以下の場合はメニュー無効化 | JoinFilters実行時 |
| BR-73-03 | マクロ展開 | スクリプト適用時にMacro.ExpandGUIでマクロを展開 | Add/Insert/Replace時 |
| BR-73-04 | フィルタ有効/無効 | cbActive.Checkedでフィルタの有効/無効を制御 | フィルタ適用時 |
| BR-73-05 | コードフォント | FontManager.GetCodeFont()で等幅フォントを使用 | RichTextBox初期化時 |

### 計算ロジック

**テキストサイズの計算**:
```
MaxTextWidth = FontHeight * 100 / s.UIScaleFactor
MaxTextHeight = FontHeight * 15 / s.UIScaleFactor
TrimmedTextSize = Min(TextSize, MaxSize)
```

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

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

本機能ではデータベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Script Error | スクリプト構文エラー | MsgError表示、CreateTempScript中断 |

### リトライ仕様

リトライは実装されていない。エラー修正後に再度操作を行う。

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

トランザクション管理は不要（メモリ上の編集操作のみ）。

## パフォーマンス要件

- フィルタ追加・編集は即時反映
- プレビュースクリプト生成は数ミリ秒
- ビデオプレビューはスクリプトエンジンの処理速度に依存

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

- スクリプト内容はユーザーが自由に編集可能
- 外部プレイヤー（mpv.net, MPC-HC）起動時は一時ファイル経由

## 備考

- CodeFormは読み取り専用のコードビューア（Findによる検索機能付き）
- CodeEditorはダイアログベースの編集エディタ（OK/Cancelボタン付き）
- テーマ対応（ThemeManager.CurrentThemeChanged）

---

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

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

### 推奨読解順序

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

コードエディタではVideoFilter、VideoScript、FilterTableが主要なデータ構造。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | VideoScript.vb | `Source/Video/VideoScript.vb` | VideoFilter, VideoScript, ScriptEngine（1230-1233行目） |
| 1-2 | CodeEditor.vb | `Source/Forms/CodeEditor.vb` | FilterTableクラス（526-842行目） |

**読解のコツ**:
- VideoFilterはActive（有効フラグ）、Category、Name/Path、Scriptの4プロパティを持つ
- ScriptEngineはAviSynthまたはVapourSynthの2値Enum
- FilterTableはTableLayoutPanelを継承し、cbActive（チェックボックス）、tbName（テキストボックス）、rtbScript（リッチテキスト）を保持

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

CodeEditorのコンストラクタと主要プロパティ。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CodeEditor.vb | `Source/Forms/CodeEditor.vb` | コンストラクタ（17-47行目） |
| 2-2 | CodeEditor.Designer.vb | `Source/Forms/CodeEditor.Designer.vb` | UI構成 |

**主要処理フロー**:
1. **17-19行目**: InitializeComponent、MainFlowLayoutPanel設定
2. **23-31行目**: Engine設定、CommandManager初期化、CustomMenu構築
3. **33-37行目**: doc.Filtersを走査してFilterTable生成
4. **42-46行目**: AutoSize設定、テーマ適用

#### Step 3: フィルタ操作を理解する

フィルタの追加・削除・並べ替え処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CodeEditor.vb | `Source/Forms/CodeEditor.vb` | ApplyFilters（107-113行目）、RemoveFilter（115-127行目） |
| 3-2 | CodeEditor.vb | `Source/Forms/CodeEditor.vb` | MoveFilterUp/Down（129-151行目） |
| 3-3 | CodeEditor.vb | `Source/Forms/CodeEditor.vb` | JoinActiveFilters/JoinAllFilters/JoinInactiveFilters（244-289行目） |

**主要処理フロー**:
- **107-113行目**: ApplyFilters - GetFiltersでフィルタリスト取得、PreviewScript.Filtersに反映
- **115-127行目**: RemoveFilter - MsgQuestion確認後、MainFlowLayoutPanel.Controlsから削除
- **129-138行目**: MoveFilterUp - SetChildIndexでインデックス変更
- **244-257行目**: JoinActiveFilters - アクティブなフィルタをマージ

#### Step 4: コンテキストメニューとコマンドを理解する

カスタムメニューとショートカットキー。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CodeEditor.vb | `Source/Forms/CodeEditor.vb` | GetDefaultMenu（371-403行目） |
| 4-2 | CodeEditor.vb | `Source/Forms/CodeEditor.vb` | PopulateDynamicMenu（309-357行目） |

**主要処理フロー**:
- **371-403行目**: GetDefaultMenu - メニュー項目とショートカットキーの定義
- **309-357行目**: PopulateDynamicMenu - フィルタプロファイルからメニュー動的生成

#### Step 5: プレビュー連携を理解する

ビデオプレビューとコードプレビュー。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | CodeEditor.vb | `Source/Forms/CodeEditor.vb` | ShowVideoPreview（223-241行目） |
| 5-2 | CodeEditor.vb | `Source/Forms/CodeEditor.vb` | ShowCodePreview（153-160行目） |
| 5-3 | CodeEditor.vb | `Source/Forms/CodeEditor.vb` | CreateTempScript（434-447行目） |

**主要処理フロー**:
- **223-241行目**: ShowVideoPreview - PreviewForm生成、スクリプト適用
- **153-160行目**: ShowCodePreview - GetFullScriptでマクロ展開後のコード表示
- **434-447行目**: CreateTempScript - 一時スクリプト生成、エラーチェック

#### Step 6: FilterTableの詳細を理解する

個々のフィルタを表示・編集するUI部品。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | CodeEditor.vb | `Source/Forms/CodeEditor.vb` | FilterTable.New（582-669行目） |
| 6-2 | CodeEditor.vb | `Source/Forms/CodeEditor.vb` | FilterTable.Add/Insert/ReplaceFilter（766-841行目） |

**主要処理フロー**:
- **582-669行目**: コンストラクタ - TableLayoutPanel設定、cbActive/tbName/rtbScript配置
- **601-612行目**: イベントハンドラ登録（CheckedChanged、Enter、TextChanged）
- **766-788行目**: Add - マクロ展開、新しいFilterTable生成

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

```
CodeEditor (CodeEditor.vb)
    │
    ├─ コンストラクタ
    │      │
    │      ├─ InitializeComponent (Designer)
    │      │
    │      ├─ CommandManager.AddCommandsFromObject
    │      │
    │      ├─ CustomMenu構築
    │      │
    │      └─ CreateFilterTable (VideoFilter → FilterTable)
    │             └─ FilterTable.New
    │
    ├─ ApplyFilters (Ctrl+S)
    │      │
    │      ├─ GetFilters
    │      │      └─ FilterTable → VideoFilter変換
    │      │
    │      └─ PreviewScript.Filters更新
    │
    ├─ ShowVideoPreview (F6)
    │      │
    │      ├─ CreateTempScript
    │      │      └─ script.GetError（エラーチェック）
    │      │
    │      └─ PreviewForm.Show
    │
    ├─ ShowCodePreview (F4)
    │      │
    │      └─ g.ShowCommandLinePreview
    │             └─ script.GetFullScript
    │
    ├─ PlayWithMpvnet (F9)
    │      │
    │      └─ g.PlayScriptWithMPV
    │
    └─ JoinFilters系
           │
           └─ FilterTable操作
                  └─ MainFlowLayoutPanel.Controls操作
```

### データフロー図

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

VideoScript ──────────▶ CodeEditor ─────────────▶ VideoScript.Filters
    │                      │                           │
    │                      ▼                           │
    │                 FilterTable群                    │
    │                      │                           │
    │                      ▼                           │
    │                 GetFilters()                     │
    │                      │                           │
    └──────────────────────┼───────────────────────────┘
                           │
                           ▼
                    PreviewScript
                           │
                           ▼
                    PreviewForm / mpv.net
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CodeEditor.vb | `Source/Forms/CodeEditor.vb` | ソース | コードエディタ本体（FilterTable含む） |
| CodeEditor.Designer.vb | `Source/Forms/CodeEditor.Designer.vb` | ソース | CodeEditorのUIデザイナー定義 |
| CodeForm.vb | `Source/Forms/CodeForm.vb` | ソース | コードビューア（読み取り専用） |
| CodeForm.Designer.vb | `Source/Forms/CodeForm.Designer.vb` | ソース | CodeFormのUIデザイナー定義 |
| VideoScript.vb | `Source/Video/VideoScript.vb` | ソース | VideoFilter、VideoScript、ScriptEngine定義 |
| PreviewForm.vb | `Source/Forms/PreviewForm.vb` | ソース | ビデオプレビュー画面 |
