# 機能設計書 64-カスタムメニュー

## 概要

本ドキュメントは、StaxRipアプリケーションにおける「カスタムメニュー」機能の設計仕様を定義する。この機能は、ユーザーがアプリケーションの各種メニューをカスタマイズして、よく使う機能へのアクセスを効率化する。

### 本機能の処理概要

**業務上の目的・背景**：StaxRipは多機能なエンコードアプリケーションであり、多数のメニュー項目が存在する。ユーザーのワークフローに応じてメニュー構成をカスタマイズできることで、作業効率を向上させ、頻繁に使用する機能への素早いアクセスを可能にする。

**機能の利用シーン**：
- メインフォームのメニューカスタマイズ
- クロップダイアログのメニューカスタマイズ
- プレビューダイアログのメニューカスタマイズ
- コードエディタのメニューカスタマイズ
- サイズメニューのカスタマイズ

**主要な処理内容**：
1. カスタムメニューエディタ（CustomMenuEditor）の表示
2. メニュー項目の追加・削除・並び替え
3. コマンドとメニュー項目の関連付け
4. ApplicationSettingsへの保存
5. アプリケーション再起動時のメニュー復元

**関連システム・外部連携**：特になし（アプリケーション内部機能）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | MainForm | 主画面 | カスタマイズ対象メニューの表示 |
| - | CustomMenuEditor | 設定画面 | メニュー編集UI |
| - | CropForm | 参照画面 | クロップ用カスタムメニュー |
| - | PreviewForm | 参照画面 | プレビュー用カスタムメニュー |
| - | CodeEditor | 参照画面 | コードエディタ用カスタムメニュー |

## 機能種別

設定管理 / UI カスタマイズ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| CustomMenuMainForm | CustomMenuItem | No | メインフォームのカスタムメニュー | - |
| CustomMenuCrop | CustomMenuItem | No | クロップダイアログのカスタムメニュー | - |
| CustomMenuPreview | CustomMenuItem | No | プレビューダイアログのカスタムメニュー | - |
| CustomMenuCodeEditor | CustomMenuItem | No | コードエディタのカスタムメニュー | - |
| CustomMenuSize | CustomMenuItem | No | サイズメニューのカスタムメニュー | - |

### 入力データソース

- ApplicationSettings（s）からの読み込み
- ユーザーによるUI操作

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| CustomMenuItem | Object | 階層化されたメニュー項目の定義 |

### 出力先

- ApplicationSettings（永続化）
- 各フォームのメニューUI

## 処理フロー

### 処理シーケンス

```
1. ApplicationSettings.Init()でカスタムメニューを初期化
   └─ 各種CustomMenuプロパティをCheck()でバージョン確認
2. バージョン不一致時はデフォルトメニューを復元
   └─ GetDefaultMenuXXX()メソッドでデフォルト取得
3. フォーム表示時にカスタムメニューを適用
   └─ CustomMenuItemからMenuStripへ変換
4. ユーザーがメニュー編集を実行
   └─ CustomMenuEditorで編集
5. 編集結果をApplicationSettingsに保存
   └─ g.SaveSettings()で永続化
```

### フローチャート

```mermaid
flowchart TD
    A[アプリケーション起動] --> B[ApplicationSettings.Init]
    B --> C{各CustomMenuの\nバージョン確認}
    C -->|最新| D[既存設定を使用]
    C -->|旧| E[デフォルトメニュー復元]
    D --> F[フォーム表示]
    E --> F
    F --> G[カスタムメニュー適用]
    G --> H{メニュー編集?}
    H -->|Yes| I[CustomMenuEditor表示]
    H -->|No| J[通常操作]
    I --> K[メニュー編集]
    K --> L[保存]
    L --> M[設定ファイル更新]
    M --> G
    J --> Z[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-64-01 | バージョン管理 | メニュー構造のバージョンが不一致の場合はデフォルトに戻す | 起動時 |
| BR-64-02 | 階層構造 | メニューは階層構造（親子関係）をサポート | 常時 |
| BR-64-03 | コマンド関連付け | 各メニュー項目はコマンド（メソッド名）と関連付けられる | 常時 |

### 計算ロジック

特になし

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

本機能はデータベースを使用しない。設定はApplicationSettingsとしてファイルに保存。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Deserialization Error | 設定ファイルの読み込み失敗 | デフォルトメニューに復元 |
| - | Command Not Found | 存在しないコマンドが指定された | メニュー項目を無効化 |

### リトライ仕様

自動リトライは行わない。エラー時はデフォルト設定に復元。

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

該当なし

## パフォーマンス要件

- メニュー読み込み：起動時に1回のみ
- メニュー保存：即時反映

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

- ローカル設定ファイルのみ使用
- カスタムコマンドの実行はアプリケーション内で定義されたメソッドのみ

## 備考

- CustomMenuItemはSerializableでシリアライズ対応
- 各フォームにGetDefaultMenu系メソッドが定義されている

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ApplicationSettings.vb | `Source/General/ApplicationSettings.vb` | CustomMenuXXXプロパティの定義 |

**読解のコツ**: CustomMenuMainForm、CustomMenuCrop、CustomMenuPreview、CustomMenuCodeEditor、CustomMenuSizeの各プロパティを確認。

**主要処理フロー**:
- **34-38行目**: カスタムメニュープロパティの定義
- **307-325行目**: Init()でのバージョンチェックとデフォルト復元

#### Step 2: カスタムメニューエディタを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CustomMenuEditor.vb | `Source/UI/CustomMenuEditor.vb` | メニュー編集UIの実装 |

**主要処理フロー**:
- メニュー項目の追加・削除・並び替え機能
- TreeViewによる階層表示
- コマンド選択ダイアログ

#### Step 3: デフォルトメニュー定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MainForm.vb | `Source/Forms/MainForm.vb` | GetDefaultMainMenuの実装 |
| 3-2 | CropForm.vb | `Source/Forms/CropForm.vb` | GetDefaultMenuCropの実装 |
| 3-3 | PreviewForm.vb | `Source/Forms/PreviewForm.vb` | GetDefaultMenuの実装 |
| 3-4 | CodeEditor.vb | `Source/UI/CodeEditor.vb` | GetDefaultMenuの実装 |

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

```
ApplicationSettings.Init()
    │
    ├─ Check(CustomMenuMainForm, "Menu in main window", version)
    │      └─ MainForm.GetDefaultMainMenu() [バージョン不一致時]
    │
    ├─ Check(CustomMenuCrop, "Menu in crop dialog", version)
    │      └─ CropForm.GetDefaultMenuCrop() [バージョン不一致時]
    │
    ├─ Check(CustomMenuPreview, "Menu in preview dialog", version)
    │      └─ PreviewForm.GetDefaultMenu() [バージョン不一致時]
    │
    ├─ Check(CustomMenuCodeEditor, "Menu in code editor", version)
    │      └─ CodeEditor.GetDefaultMenu() [バージョン不一致時]
    │
    └─ Check(CustomMenuSize, "Target size menu in main dialog", version)
           └─ MainForm.GetDefaultMenuSize() [バージョン不一致時]
```

### データフロー図

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

設定ファイル ───────────▶ ApplicationSettings.Init()
                                │
                                ▼
                         バージョンチェック
                                │
                    ┌───────────┴───────────┐
                    ▼                       ▼
              最新バージョン           旧バージョン
                    │                       │
                    ▼                       ▼
              既存設定使用           デフォルト復元
                    │                       │
                    └───────────┬───────────┘
                                ▼
                         CustomMenuItem
                                │
                                ▼
                         MenuStrip変換 ───▶ UI表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ApplicationSettings.vb | `Source/General/ApplicationSettings.vb` | ソース | カスタムメニュープロパティ定義 |
| CustomMenuEditor.vb | `Source/UI/CustomMenuEditor.vb` | ソース | メニュー編集UI |
| MainForm.vb | `Source/Forms/MainForm.vb` | ソース | メインメニューデフォルト定義 |
| CropForm.vb | `Source/Forms/CropForm.vb` | ソース | クロップメニューデフォルト定義 |
| PreviewForm.vb | `Source/Forms/PreviewForm.vb` | ソース | プレビューメニューデフォルト定義 |
| CodeEditor.vb | `Source/UI/CodeEditor.vb` | ソース | コードエディタメニューデフォルト定義 |
