# 機能設計書 108-小節編集

## 概要

本ドキュメントは、K-Shoot Editor(譜面エディタ)における小節削除/空白小節追加の小節単位編集機能の設計を記述する。

### 本機能の処理概要

本機能は、譜面の小節単位での編集操作として、選択範囲の小節削除(CMD_EDIT_REMOVEMEASURE)とカーソル位置への空白小節挿入(CMD_EDIT_ADDBLANK)の2つのコマンドを提供する。小節削除は選択範囲内のすべてのオブジェクトを削除し、後続のオブジェクト位置を前にシフトする。空白挿入はカーソル位置以降のすべてのオブジェクト位置を指定長分だけ後方にシフトする。

**業務上の目的・背景**: 譜面構成の変更(小節の追加・削除)は譜面制作において基本的な操作である。曲の構成変更に伴う小節数の増減に対応するために必要な機能である。

**機能の利用シーン**: 編集メニューの「選択範囲の領域を削除」/「カーソル位置に空白を挿入」から実行する。小節削除は事前に範囲選択(cnowflen!=0)が必要。空白挿入は範囲選択なしの場合はダイアログで挿入長を選択し、範囲選択ありの場合は選択範囲と同じ長さの空白を挿入する。

**主要な処理内容**:
1. CMD_EDIT_REMOVEMEASURE: 選択範囲内のオブジェクト(ノート/アナログ/スピン/STOP/Tilt/Zoom/BPM/拍子/コメント等)を削除し、後続を前にシフト
2. CMD_EDIT_ADDBLANK: 指定長(1/4小節~8小節)の空白をカーソル位置に挿入し、後続オブジェクトをシフト

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

**権限による制御**: なし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 譜面エディタ | 主画面 | 編集メニュー > 選択範囲の領域を削除 / カーソル位置に空白を挿入 |

## 機能種別

データ操作(小節単位のCRUD)

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cmd | 整数 | Yes | CMD_EDIT_REMOVEMEASURE / CMD_EDIT_ADDBLANK | 有効なコマンド値 |
| cnowf | 整数 | Yes | 現在のカーソル位置(カウント値) | - |
| cnowflen | 整数 | 条件付 | 選択範囲長(REMOVEMEASURE時は必須、ADDBLANK時は任意) | REMOVEMEASURE時は0以外 |

### 入力データソース

カーソル位置と選択範囲(cnowf, cnowflen)、ダイアログ入力(ADDBLANK時)

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 全譜面配列 | 各種配列 | 位置がシフトされた全オブジェクトデータ |

### 出力先

メモリ上の各種配列

## 処理フロー

### 処理シーケンス

```
1. CMD_EDIT_REMOVEMEASURE (小節削除)
   ├─ cnowflen=0の場合、lang.10.40のメッセージを表示して中断
   ├─ 範囲内のオブジェクトを選択状態に設定(*selinit2)
   ├─ 確認ダイアログ表示(lang.10.41)
   ├─ CMD_EDIT_DELETEで選択オブジェクトを削除
   ├─ 範囲内の制御データ(chiprate/longrate/analograte/anagain/anafil/anvol/anse/tilt/ztop/zbot/zside/beatl/bpml/comment/userchprm)を削除
   └─ 後続オブジェクトの位置を cnowflen 分だけ前方にシフト

2. CMD_EDIT_ADDBLANK (空白挿入)
   ├─ cnowflen=0の場合:
   │   ├─ ダイアログで挿入長を選択(1/4小節~8小節)
   │   │   └─ 1/4小節=48, 1/2小節=96, 1小節=192, 2小節=384, 4小節=768, 8小節=1536
   │   └─ カーソル位置(cnowf)以降の全オブジェクト位置を選択長分シフト
   └─ cnowflen!=0の場合:
       └─ 選択範囲と同じ長さの空白を挿入(後続をabs(cnowflen)分シフト)
```

### フローチャート

```mermaid
flowchart TD
    A[コマンド受信] --> B{コマンド種別?}
    B -->|REMOVEMEASURE| C{cnowflen != 0?}
    C -->|No| D[メッセージ表示]
    C -->|Yes| E[範囲内オブジェクト選択]
    E --> F[確認ダイアログ]
    F --> G{OK?}
    G -->|Yes| H[オブジェクト削除]
    H --> I[制御データ削除]
    I --> J[後続位置を前方シフト]
    G -->|No| Z[処理中断]
    B -->|ADDBLANK| K{cnowflen != 0?}
    K -->|No| L[挿入長選択ダイアログ]
    L --> M[後続位置を後方シフト]
    K -->|Yes| N[選択範囲長で後方シフト]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-108-01 | 範囲選択必須 | REMOVEMEASURE実行にはcnowflen!=0(範囲選択)が必須 | CMD_EDIT_REMOVEMEASURE |
| BR-108-02 | 確認ダイアログ | REMOVEMEASUREは実行前に確認ダイアログを表示する | CMD_EDIT_REMOVEMEASURE |
| BR-108-03 | 挿入長選択肢 | ADDBLANKの挿入長は1/4小節(48)/1/2小節(96)/1小節(192)/2小節(384)/4小節(768)/8小節(1536)の6段階 | CMD_EDIT_ADDBLANK(cnowflen=0時) |
| BR-108-04 | BPM/拍子保持 | REMOVEMEASUREで範囲内のBPM変更/拍子変更も削除される(先頭のBPM/拍子は保持) | CMD_EDIT_REMOVEMEASURE |
| BR-108-05 | 全オブジェクト対象 | シフト操作はnote/analog/spin/stp/tilt/ztop/zbot/zside/bpml/beatl/chiprate/longrate/analograte/anagain/anafil/anvol/anse/comment/userchprmのすべてに適用 | 両コマンド |

### 計算ロジック

UNIT_MEASURE(1小節 = 192カウント)に基づく挿入長:
- 1/4小節 = UNIT_MEASURE/4 = 48
- 1/2小節 = UNIT_MEASURE/2 = 96
- 1小節 = UNIT_MEASURE = 192
- 2小節 = UNIT_MEASURE*2 = 384
- 4小節 = UNIT_MEASURE*4 = 768
- 8小節 = UNIT_MEASURE*8 = 1536

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 操作不可 | REMOVEMEASUREでcnowflen=0(範囲未選択) | lang.10.40メッセージ表示 |
| - | ユーザーキャンセル | 確認ダイアログでキャンセル | 処理中断 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

全オブジェクト配列の位置シフトが必要なため、オブジェクト数に比例した処理時間がかかる。

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

特になし。

## 備考

- REMOVEMEASURE実行時、先頭のBPMとBeat(拍子)は削除対象外(index=0のエントリはスキップ)
- ADDBLANK時にcnowflen!=0の場合は、ダイアログを表示せずに選択範囲長をそのまま挿入長として使用する
- ardel/ardel2ヘルパー関数で配列要素の削除処理を行う

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kshooteditor.hsp | `kshooteditor.hsp` | 5722-5959行目: CMD_EDIT_REMOVEMEASURE処理 |
| 1-2 | kshooteditor.hsp | `kshooteditor.hsp` | 6206-6349行目: CMD_EDIT_ADDBLANK処理 |

**主要処理フロー(CMD_EDIT_REMOVEMEASURE)**:
- **5725行目**: `if(cnowflen=0)` で範囲未選択チェック → lang.10.40メッセージ
- **5728行目**: `gosub *selinit2` で範囲内オブジェクトを選択
- **5757行目**: 確認ダイアログ表示
- **5762行目**: `acmd=CMD_EDIT_DELETE` → `gosub *OnCommand` でオブジェクト削除
- **5767-5916行目**: 制御データの削除(ardel/ardel2使用)
- **5918-5959行目**: 後続オブジェクト位置のシフト(`note.cnt.1 -= cnowflen` 等)

**主要処理フロー(CMD_EDIT_ADDBLANK)**:
- **6209行目**: `if(cnowflen=0)` で範囲選択なし判定
- **6215行目**: `_input` でダイアログ表示(挿入長選択)
- **6220-6232行目**: 選択値からカウント値への変換(UNIT_MEASURE基準)
- **6233-6328行目**: 全オブジェクト配列の位置シフト

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

```
*OnCommand
    │
    ├─ CMD_EDIT_REMOVEMEASURE
    │   ├─ *selinit2 (範囲内オブジェクト選択)
    │   ├─ dialog (確認ダイアログ)
    │   ├─ CMD_EDIT_DELETE (オブジェクト削除)
    │   ├─ ardel/ardel2 (制御データ削除)
    │   └─ 位置シフト処理
    │
    └─ CMD_EDIT_ADDBLANK
        ├─ _input (挿入長選択ダイアログ)
        ├─ *undokakuho (Undo保存)
        └─ 位置シフト処理
```

### データフロー図

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

cnowf/cnowflen       ──────▶  REMOVEMEASURE             ───▶  全配列(オブジェクト削除+シフト)
(カーソル位置/範囲)            (削除+前方シフト)

cnowf + 挿入長       ──────▶  ADDBLANK                  ───▶  全配列(後方シフト)
(カーソル位置+選択長)          (後方シフト)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| kshooteditor.hsp | `kshooteditor.hsp` | ソース | 小節削除(5722-5959行目)、空白挿入(6206-6349行目) |
