Logo Search packages:      
Sourcecode: cadencii version File versions  Download package

FormMain.cs

/*
 * FormMainUiImpl.cs
 * Copyright © 2008-2011 kbinani
 *
 * This file is part of org.kbinani.cadencii.
 *
 * org.kbinani.cadencii is free software; you can redistribute it and/or
 * modify it under the terms of the GPLv3 License.
 *
 * org.kbinani.cadencii is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
#if JAVA
package org.kbinani.cadencii;

//INCLUDE-SECTION IMPORT ../BuildJavaUI/src/org/kbinani/cadencii/FormMain.java

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Transmitter;
import javax.sound.midi.Receiver;
import javax.sound.midi.MidiDevice;
import org.kbinani.*;
import org.kbinani.apputil.*;
import org.kbinani.componentmodel.*;
import org.kbinani.media.*;
import org.kbinani.vsq.*;
import org.kbinani.windows.forms.*;
import org.kbinani.xml.*;

#else

//#define USE_BGWORK_SCREEN
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Media;
using System.Text;
using System.Threading;
using org.kbinani.apputil;
using org.kbinani.componentmodel;
using org.kbinani.java.awt;
using org.kbinani.java.awt.event_;
using org.kbinani.java.io;
using org.kbinani.java.util;
using org.kbinani.javax.swing;
using org.kbinani.javax.sound.midi;
using org.kbinani.media;
using org.kbinani.vsq;
using org.kbinani.windows.forms;
using org.kbinani.xml;

namespace org.kbinani.cadencii
{
    using BCancelEventArgs = System.ComponentModel.CancelEventArgs;
    using BDoWorkEventArgs = System.ComponentModel.DoWorkEventArgs;
    using BFormClosedEventArgs = System.Windows.Forms.FormClosedEventArgs;
    using BFormClosingEventArgs = System.Windows.Forms.FormClosingEventArgs;
    using BKeyEventArgs = System.Windows.Forms.KeyEventArgs;
    using BKeyPressEventArgs = System.Windows.Forms.KeyPressEventArgs;
    using BMouseButtons = System.Windows.Forms.MouseButtons;
    using BMouseEventArgs = System.Windows.Forms.MouseEventArgs;
    using boolean = System.Boolean;
    using BPaintEventArgs = System.Windows.Forms.PaintEventArgs;
    using BPreviewKeyDownEventArgs = System.Windows.Forms.PreviewKeyDownEventArgs;
    using BEventArgs = System.EventArgs;

    using BEventHandler = System.EventHandler;
    using BMouseEventHandler = System.Windows.Forms.MouseEventHandler;
    using BKeyEventHandler = System.Windows.Forms.KeyEventHandler;
    using BPreviewKeyDownEventHandler = System.Windows.Forms.PreviewKeyDownEventHandler;
    using BDoWorkEventHandler = System.ComponentModel.DoWorkEventHandler;
    using BPaintEventHandler = System.Windows.Forms.PaintEventHandler;
    using BFormClosedEventHandler = System.Windows.Forms.FormClosedEventHandler;
    using BFormClosingEventHandler = System.Windows.Forms.FormClosingEventHandler;
    using BCancelEventHandler = System.ComponentModel.CancelEventHandler;
    
    using Integer = System.Int32;
    using Long = System.Int64;
#endif

    /// <summary>
    /// エディタのメイン画面クラス
    /// </summary>
#if JAVA
    public class FormMain extends BForm implements FormMainUi
#else
    public class FormMain : BForm, FormMainUi
#endif
    {
        /// <summary>
        /// 特殊なキーの組み合わせのショートカットと、メニューアイテムとの紐付けを保持するクラスです。
        /// </summary>
00099         private class SpecialShortcutHolder
        {
            /// <summary>
            /// ショートカットキーを表すKeyStrokeクラスのインスタンス
            /// </summary>
00104             public KeyStroke shortcut;
            /// <summary>
            /// ショートカットキーとの紐付けを行う相手先のメニューアイテム
            /// </summary>
00108             public BMenuItem menu;

            /// <summary>
            /// ショートカットキーとメニューアイテムを指定したコンストラクタ
            /// </summary>
            /// <param name="shortcut">ショートカットキー</param>
            /// <param name="menu">ショートカットキーとの紐付けを行うメニューアイテム</param>
00115             public SpecialShortcutHolder( KeyStroke shortcut, BMenuItem menu )
            {
                this.shortcut = shortcut;
                this.menu = menu;
            }
        }

#if !JAVA
        /// <summary>
        /// refreshScreenを呼び出す時に使うデリゲート
        /// </summary>
        /// <param name="value"></param>
        delegate void DelegateRefreshScreen( boolean value );
#endif

        #region static readonly field
        /// <summary>
        /// ピアノロールでの,音符の塗りつぶし色
        /// </summary>
00134         public static readonly Color mColorNoteFill = new Color( 181, 220, 86 );
        private readonly Color mColorR105G105B105 = new Color( 105, 105, 105 );
        private readonly Color mColorR187G187B255 = new Color( 187, 187, 255 );
        private readonly Color mColorR007G007B151 = new Color( 7, 7, 151 );
        private readonly Color mColorR065G065B065 = new Color( 65, 65, 65 );
        private readonly Color mColorTextboxBackcolor = new Color( 128, 128, 128 );
        private readonly Color mColorR214G214B214 = new Color( 214, 214, 214 );
        private readonly AuthorListEntry[] _CREDIT = new AuthorListEntry[]{
            new AuthorListEntry( "is developped by:", 2 ),
            new AuthorListEntry( "kbinani", "@kbinani" ),
            new AuthorListEntry( "修羅場P", "@shurabaP" ),
            new AuthorListEntry( "もみじぱん", "@momijipan" ),
            new AuthorListEntry( "結晶", "@gondam" ),
            new AuthorListEntry( "" ),
            new AuthorListEntry(),
            new AuthorListEntry(),
            new AuthorListEntry( "Special Thanks to", 3 ),
            new AuthorListEntry(),
            new AuthorListEntry( "tool icons designer:", 2 ),
            new AuthorListEntry( "Yusuke KAMIYAMANE", "@ykamiyamane" ),
            new AuthorListEntry(),
            new AuthorListEntry( "developper of WORLD:", 2 ),
            new AuthorListEntry( "Masanori MORISE", "@m_morise" ),
            new AuthorListEntry(),
            new AuthorListEntry( "developper of v.Connect-STAND:", 2 ),
            new AuthorListEntry( "修羅場P", "@shurabaP" ),
            new AuthorListEntry(),
            new AuthorListEntry( "developper of UTAU:", 2 ),
            new AuthorListEntry( "飴屋/菖蒲", "@ameyaP_" ),
            new AuthorListEntry(),
            new AuthorListEntry( "developper of RebarDotNet:", 2 ),
            new AuthorListEntry( "Anthony Baraff" ),
            new AuthorListEntry(),
            new AuthorListEntry( "promoter:", 2 ),
            new AuthorListEntry( "zhuo", "@zhuop" ),
            new AuthorListEntry(),
            new AuthorListEntry( "library tester:", 2 ),
            new AuthorListEntry( "evm" ),
            new AuthorListEntry( "そろそろP" ),
            new AuthorListEntry( "めがね110" ),
            new AuthorListEntry( "上総" ),
            new AuthorListEntry( "NOIKE", "@knoike" ),
            new AuthorListEntry( "逃亡者" ),
            new AuthorListEntry(),
            new AuthorListEntry( "translator:", 2 ),
            new AuthorListEntry( "Eji (zh-TW translation)", "@ejiwarp" ),
            new AuthorListEntry( "kankan (zh-TW translation)" ),
            new AuthorListEntry( "yxmline (zh-CN translation)" ),
            new AuthorListEntry( "BubblyYoru (en translation)", "@BubblyYoru" ),
            new AuthorListEntry( "BeForU (kr translation)", "@BeForU" ),
            new AuthorListEntry(),
            new AuthorListEntry(),
            new AuthorListEntry( "Thanks to", 3 ),
            new AuthorListEntry(),
            new AuthorListEntry( "ないしょの人" ),
            new AuthorListEntry( "naquadah" ),
            new AuthorListEntry( "1zo" ),
            new AuthorListEntry( "Amby" ),
            new AuthorListEntry( "ケロッグ" ),
            new AuthorListEntry( "beginner" ),
            new AuthorListEntry( "b2ox", "@b2ox" ),
            new AuthorListEntry( "麻太郎" ),
            new AuthorListEntry( "PEX", "@pex_zeo" ),
            new AuthorListEntry( "やなぎがうら" ),
            new AuthorListEntry( "cocoonP", "@cocoonP" ),
            new AuthorListEntry( "かつ" ),
            new AuthorListEntry( "ちゃそ", "@marimarikerori" ),
            new AuthorListEntry( "ちょむ" ),
            new AuthorListEntry( "whimsoft" ),
            new AuthorListEntry( "kitiketao", "@okoktaokokta" ),
            new AuthorListEntry( "カプチ2" ),
            new AuthorListEntry( "あにぃ" ),
            new AuthorListEntry( "tomo" ),
            new AuthorListEntry( "ナウ□マP", "@now_romaP" ),
            new AuthorListEntry( "内藤 魅亜", "@mianaito" ),
            new AuthorListEntry( "空茶", "@maizeziam" ),
            new AuthorListEntry( "いぬくま" ),
            new AuthorListEntry( "shu-t", "@shu_sonicwave" ),
            new AuthorListEntry( "さささ", "@sasasa3396" ),
            new AuthorListEntry( "あろも~ら", "@aromora" ),
            new AuthorListEntry( "空耳P", "@soramiku" ),
            new AuthorListEntry( "kotoi" ),
            new AuthorListEntry( "げっぺータロー", "@geppeitaro" ),
            new AuthorListEntry( "みけCAT", "@mikecat_mixc" ),
            new AuthorListEntry( "ぎんじ" ),
            new AuthorListEntry( "BeForU", "@BeForU" ),
            new AuthorListEntry( "all members of Cadencii bbs", 2 ),
            new AuthorListEntry(),
            new AuthorListEntry( "     ... and you !", 3 ),
        };
        #endregion

        #region constants and internal enums
        /// <summary>
        /// カーブエディタ画面の編集モード
        /// </summary>
00230         enum CurveEditMode
        {
            /// <summary>
            /// 何もしていない
            /// </summary>
            NONE,
            /// <summary>
            /// 鉛筆ツールで編集するモード
            /// </summary>
            EDIT,
            /// <summary>
            /// ラインツールで編集するモード
            /// </summary>
            LINE,
            /// <summary>
            /// 鉛筆ツールでVELを編集するモード
            /// </summary>
            EDIT_VEL,
            /// <summary>
            /// ラインツールでVELを編集するモード
            /// </summary>
            LINE_VEL,
            /// <summary>
            /// 真ん中ボタンでドラッグ中
            /// </summary>
            MIDDLE_DRAG,
        }

        enum ExtDragXMode
        {
            RIGHT,
            LEFT,
            NONE,
        }

        enum ExtDragYMode
        {
            UP,
            DOWN,
            NONE,
        }

        enum GameControlMode
        {
            DISABLED,
            NORMAL,
            KEYBOARD,
            CURSOR,
        }

        enum PositionIndicatorMouseDownMode
        {
            NONE,
            MARK_START,
            MARK_END,
            TEMPO,
            TIMESIG,
        }

        /// <summary>
        /// スクロールバーの最小サイズ(ピクセル)
        /// </summary>
00292         public const int MIN_BAR_ACTUAL_LENGTH = 17;
        /// <summary>
        /// エントリの端を移動する時の、ハンドル許容範囲の幅
        /// </summary>
00296         public const int _EDIT_HANDLE_WIDTH = 7;
        public const int _TOOL_BAR_HEIGHT = 46;
        /// <summary>
        /// 単音プレビュー時に、wave生成完了を待つ最大の秒数
        /// </summary>
00301         public const double _WAIT_LIMIT = 5.0;
        public const String _APP_NAME = "Cadencii";
        /// <summary>
        /// 表情線の先頭部分のピクセル幅
        /// </summary>
00306         public const int _PX_ACCENT_HEADER = 21;
        public const String _VERSION_HISTORY_URL = "http://www.ne.jp/asahi/kbinani/home/cadencii/version_history.xml";
        /// <summary>
        /// splitContainer2.Panel2の最小サイズ
        /// </summary>
00311         public const int _SPL2_PANEL2_MIN_HEIGHT = 25;
        /// <summary>
        /// splitContainer*で使用するSplitterWidthプロパティの値
        /// </summary>
#if JAVA
        public const int _SPL_SPLITTER_WIDTH = 9;
#else
00318         public const int _SPL_SPLITTER_WIDTH = 4;
#endif
        const int _PICT_POSITION_INDICATOR_HEIGHT = 48;
        const int _SCROLL_WIDTH = 16;
        /// <summary>
        /// Overviewペインの高さ
        /// </summary>
00325         public const int _OVERVIEW_HEIGHT = 50;
        /// <summary>
        /// splitContainerPropertyの最小幅
        /// </summary>
00329         const int _PROPERTY_DOCK_MIN_WIDTH = 50;
        /// <summary>
        /// WAVE再生時のバッファーサイズの最大値
        /// </summary>
00333         const int MAX_WAVE_MSEC_RESOLUTION = 1000;
        /// <summary>
        /// WAVE再生時のバッファーサイズの最小値
        /// </summary>
00337         const int MIN_WAVE_MSEC_RESOLUTION = 100;
        #endregion

        #region static field
        /// <summary>
        /// refreshScreenが呼ばれている最中かどうか
        /// </summary>
00344         private static boolean mIsRefreshing = false;
        /// <summary>
        /// CTRLキー。MacOSXの場合はMenu
        /// </summary>
00348         public int s_modifier_key = InputEvent.CTRL_MASK;
        #endregion

        #region fields
        /// <summary>
        /// コントローラ
        /// </summary>
00355         private FormMainController controller = null;
        public VersionInfo mVersionInfo = null;
#if !JAVA
        public System.Windows.Forms.Cursor HAND;
#endif
        /// <summary>
        /// ボタンがDownされた位置。(座標はpictureBox基準)
        /// </summary>
00363         public Point mButtonInitial = new Point();
        /// <summary>
        /// 真ん中ボタンがダウンされたときのvscrollのvalue値
        /// </summary>
00367         public int mMiddleButtonVScroll;
        /// <summary>
        /// 真ん中ボタンがダウンされたときのhscrollのvalue値
        /// </summary>
00371         public int mMiddleButtonHScroll;
        public boolean mEdited = false;
        /// <summary>
        /// 最後にメイン画面が更新された時刻(秒単位)
        /// </summary>
00376         private double mLastScreenRefreshedSec;
        /// <summary>
        /// カーブエディタの編集モード
        /// </summary>
00380         private CurveEditMode mEditCurveMode = CurveEditMode.NONE;
        /// <summary>
        /// ピアノロールの右クリックが表示される直前のマウスの位置
        /// </summary>
00384         public Point mContextMenuOpenedPosition = new Point();
        /// <summary>
        /// ピアノロールの画面外へのドラッグ時、前回自動スクロール操作を行った時刻
        /// </summary>
00388         public double mTimerDragLastIgnitted;
        /// <summary>
        /// 画面外への自動スクロールモード
        /// </summary>
00392         private ExtDragXMode mExtDragX = ExtDragXMode.NONE;
        private ExtDragYMode mExtDragY = ExtDragYMode.NONE;
        /// <summary>
        /// EditMode=MoveEntryで,移動を開始する直前のマウスの仮想スクリーン上の位置
        /// </summary>
00397         public Point mMouseMoveInit = new Point();
        /// <summary>
        /// EditMode=MoveEntryで,移動を開始する直前のマウスの位置と,音符の先頭との距離(ピクセル)
        /// </summary>
00401         public int mMouseMoveOffset;
        /// <summary>
        /// マウスが降りているかどうかを表すフラグ.AppManager.isPointerDownedとは別なので注意
        /// </summary>
00405         public boolean mMouseDowned = false;
        public int mTempoDraggingDeltaClock = 0;
        public int mTimesigDraggingDeltaClock = 0;
        public boolean mMouseDownedTrackSelector = false;
        private ExtDragXMode mExtDragXTrackSelector = ExtDragXMode.NONE;
        public boolean mMouseMoved = false;
#if ENABLE_MOUSEHOVER
        /// <summary>
        /// マウスホバーを発生させるスレッド
        /// </summary>
        public Thread mMouseHoverThread = null;
#endif
        public boolean mLastIsImeModeOn = true;
        public boolean mLastSymbolEditMode = false;
        /// <summary>
        /// 鉛筆のモード
        /// </summary>
00422         public PencilMode mPencilMode = new PencilMode();
        /// <summary>
        /// ビブラート範囲を編集中の音符のInternalID
        /// </summary>
00426         public int mVibratoEditingId = -1;
        /// <summary>
        /// このフォームがアクティブ化されているかどうか
        /// </summary>
00430         public boolean mFormActivated = true;
        private GameControlMode mGameMode = GameControlMode.DISABLED;
        public BTimer mTimer;
        public boolean mLastPovR = false;
        public boolean mLastPovL = false;
        public boolean mLastPovU = false;
        public boolean mLastPovD = false;
        public boolean mLastBtnX = false;
        public boolean mLastBtnO = false;
        public boolean mLastBtnRe = false;
        public boolean mLastBtnTr = false;
        public boolean mLastBtnSelect = false;
        /// <summary>
        /// 前回ゲームコントローラのイベントを処理した時刻
        /// </summary>
00445         public double mLastEventProcessed;
        public boolean mSpacekeyDowned = false;
#if ENABLE_MIDI
        public MidiInDevice mMidiIn = null;
#endif
#if ENABLE_MTC
        public MidiInDevice m_midi_in_mtc = null;
#endif
        public FormMidiImExport mDialogMidiImportAndExport = null;
        public TreeMap<EditTool, Cursor> mCursor = new TreeMap<EditTool, Cursor>();
        private Preference mDialogPreference;
#if ENABLE_PROPERTY
        public PropertyPanelContainer mPropertyPanelContainer;
#endif
#if ENABLE_SCRIPT
        public Vector<System.Windows.Forms.ToolBarButton> mPaletteTools = new Vector<System.Windows.Forms.ToolBarButton>();
#endif

        /// <summary>
        /// PositionIndicatorのマウスモード
        /// </summary>
00466         private PositionIndicatorMouseDownMode mPositionIndicatorMouseDownMode = PositionIndicatorMouseDownMode.NONE;
        /// <summary>
        /// AppManager.keyWidthを調節するモードに入ったかどうか
        /// </summary>
00470         public boolean mKeyLengthSplitterMouseDowned = false;
        /// <summary>
        /// AppManager.keyWidthを調節するモードに入る直前での、マウスのスクリーン座標
        /// </summary>
00474         public Point mKeyLengthSplitterInitialMouse = new Point();
        /// <summary>
        /// AppManager.keyWidthを調節するモードに入る直前での、keyWidthの値
        /// </summary>
00478         public int mKeyLengthInitValue = 68;
        /// <summary>
        /// AppManager.keyWidthを調節するモードに入る直前での、trackSelectorのgetRowsPerColumn()の値
        /// </summary>
00482         public int mKeyLengthTrackSelectorRowsPerColumn = 1;
        /// <summary>
        /// AppManager.keyWidthを調節するモードに入る直前での、splitContainer1のSplitterLocationの値
        /// </summary>
00486         public int mKeyLengthSplitterDistance = 0;
        public BFileChooser openXmlVsqDialog;
        public BFileChooser saveXmlVsqDialog;
        public BFileChooser openUstDialog;
        public BFileChooser openMidiDialog;
        public BFileChooser saveMidiDialog;
        public BFileChooser openWaveDialog;
        public BTimer timer;
        public BBackgroundWorker bgWorkScreen;
        /// <summary>
        /// アイコンパレットのドラッグ&ドロップ処理中,一度でもpictPianoRoll内にマウスが入ったかどうか
        /// </summary>
00498         private boolean mIconPaletteOnceDragEntered = false;
        private byte mMtcFrameLsb;
        private byte mMtcFrameMsb;
        private byte mMtcSecLsb;
        private byte mMtcSecMsb;
        private byte mMtcMinLsb;
        private byte mMtcMinMsb;
        private byte mMtcHourLsb;
        private byte mMtcHourMsb;
        /// <summary>
        /// MTCを最後に受信した時刻
        /// </summary>
00510         private double mMtcLastReceived = 0.0;
        /// <summary>
        /// 特殊な取り扱いが必要なショートカットのキー列と、対応するメニューアイテムを保存しておくリスト。
        /// </summary>
00514         private Vector<SpecialShortcutHolder> mSpecialShortcutHolders = new Vector<SpecialShortcutHolder>();
        /// <summary>
        /// 歌詞流し込み用のダイアログ
        /// </summary>
00518         private FormImportLyric mDialogImportLyric = null;
        /// <summary>
        /// デフォルトのストローク
        /// </summary>
00522         private BasicStroke mStrokeDefault = null;
        /// <summary>
        /// 描画幅2pxのストローク
        /// </summary>
00526         private BasicStroke mStroke2px = null;
        /// <summary>
        /// pictureBox2の描画ループで使うグラフィックス
        /// </summary>
00530         private Graphics2D mGraphicsPictureBox2 = null;
#if !JAVA
        /// <summary>
        /// ピアノロールの縦方向の拡大率を変更するパネル上でのマウスの状態。
        /// 0がデフォルト、&gt;0は+ボタンにマウスが降りた状態、&lt;0は-ボタンにマウスが降りた状態
        /// </summary>
00536         private int mPianoRollScaleYMouseStatus = 0;
#endif
        /// <summary>
        /// 再生中にソングポジションが前進だけしてほしいので,逆行を防ぐために前回のソングポジションを覚えておく
        /// </summary>
00541         private int mLastClock = 0;
        /// <summary>
        /// PositionIndicatorに表示しているポップアップのクロック位置
        /// </summary>
00545         private int mPositionIndicatorPopupShownClock;
#if MONITOR_FPS
        /// <summary>
        /// パフォーマンスカウンタ
        /// </summary>
        private double[] mFpsDrawTime = new double[128];
        private int mFpsDrawTimeIndex = 0;
        /// <summary>
        /// パフォーマンスカウンタから算出される画面の更新速度
        /// </summary>
        private float mFps = 0f;
        private double[] mFpsDrawTime2 = new double[128];
        private float mFps2 = 0f;
#endif
        #endregion

        #region constructor
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="file">最初に開くxvsq,vsqファイルのパス</param>
00566         public FormMain( FormMainController controller, String file )
        {
#if JAVA
                super();
#endif
            this.controller = controller;
            this.controller.setupUi( this );

            // 言語設定を反映させる
            Messaging.setLanguage( AppManager.editorConfig.Language );

#if ENABLE_PROPERTY
            AppManager.propertyPanel = new PropertyPanel();
            AppManager.propertyWindow = new FormNoteProperty();
            AppManager.propertyWindow.addComponent( AppManager.propertyPanel );
#endif

#if DEBUG
            AppManager.debugWriteLine( "FormMain..ctor()" );
#endif
            AppManager.baseFont10Bold = new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.BOLD, AppManager.FONT_SIZE10 );
            AppManager.baseFont8 = new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.PLAIN, AppManager.FONT_SIZE8 );
            AppManager.baseFont10 = new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.PLAIN, AppManager.FONT_SIZE10 );
            AppManager.baseFont9 = new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.PLAIN, AppManager.FONT_SIZE9 );
            AppManager.baseFont50Bold = new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.BOLD, AppManager.FONT_SIZE50 );

            s_modifier_key = 
#if JAVA_MAC
                InputEvent.META_MASK;
#else
                InputEvent.CTRL_MASK;
#endif
            VsqFileEx tvsq = 
                new VsqFileEx( 
                    AppManager.editorConfig.DefaultSingerName,
                    1,
                    4,
                    4,
                    500000 );
            RendererKind kind = AppManager.editorConfig.DefaultSynthesizer;
            String renderer = AppManager.getVersionStringFromRendererKind( kind );
            Vector<VsqID> singers = AppManager.getSingerListFromRendererKind( kind );
            tvsq.Track.get( 1 ).changeRenderer( renderer, singers );
            AppManager.setVsqFile( tvsq );

            trackSelector = new TrackSelector( this ); // initializeで引数なしのコンストラクタが呼ばれるのを予防
#if !JAVA
            //TODO: javaのwaveViewはどこで作られるんだっけ?
            waveView = new WaveView();
#endif
            //TODO: これはひどい
            panelWaveformZoom = (WaveformZoomUiImpl)(new WaveformZoomController( this, waveView )).getUi();

#if JAVA
            initialize();
            timer = new BTimer();
            getCMenuPiano();
            getCMenuTrackTab();
            getCMenuTrackSelector();
// MIDIステップ入力は使えないことにする
//            toolStripTool.remove( getStripBtnStepSequencer() );
#else
            InitializeComponent();
            timer = new BTimer( this.components );
#endif

            panelOverview.setMainForm( this );
            pictPianoRoll.setMainForm( this );
            bgWorkScreen = new BBackgroundWorker();

#if JAVA
#else
            this.panelWaveformZoom.Controls.Add( this.waveView );
            this.waveView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.waveView.BackColor = System.Drawing.Color.FromArgb( ((int)(((byte)(212)))), ((int)(((byte)(212)))), ((int)(((byte)(212)))) );
            this.waveView.Location = new System.Drawing.Point( 66, 0 );
            this.waveView.Margin = new System.Windows.Forms.Padding( 0 );
            this.waveView.Name = "waveView";
            this.waveView.Size = new System.Drawing.Size( 355, 59 );
            this.waveView.TabIndex = 17;
#endif
            openXmlVsqDialog = new BFileChooser();
            openXmlVsqDialog.addFileFilter( "VSQ Format(*.vsq)|*.vsq" );
            openXmlVsqDialog.addFileFilter( "XML-VSQ Format(*.xvsq)|*.xvsq" );

            saveXmlVsqDialog = new BFileChooser();
            saveXmlVsqDialog.addFileFilter( "VSQ Format(*.vsq)|*.vsq" );
            saveXmlVsqDialog.addFileFilter( "XML-VSQ Format(*.xvsq)|*.xvsq" );
            saveXmlVsqDialog.addFileFilter( "All files(*.*)|*.*" );

            openUstDialog = new BFileChooser();
            openUstDialog.addFileFilter( "UTAU Project File(*.ust)|*.ust" );
            openUstDialog.addFileFilter( "All Files(*.*)|*.*" );

            openMidiDialog = new BFileChooser();
            saveMidiDialog = new BFileChooser();
            openWaveDialog = new BFileChooser();

            /*mOverviewScaleCount = AppManager.editorConfig.OverviewScaleCount;
            mOverviewPixelPerClock = getOverviewScaleX( mOverviewScaleCount );*/

            menuVisualOverview.setSelected( AppManager.editorConfig.OverviewEnabled );
#if ENABLE_PROPERTY
            mPropertyPanelContainer = new PropertyPanelContainer();
#endif

            registerEventHandlers();
            setResources();

#if !ENABLE_SCRIPT
            menuSettingPaletteTool.setVisible( false );
            menuScript.setVisible( false );
#endif
            trackSelector.updateVisibleCurves();
            trackSelector.setBackground( new Color( 108, 108, 108 ) );
            trackSelector.setCurveVisible( true );
            trackSelector.setSelectedCurve( CurveType.VEL );
#if !JAVA
            trackSelector.setLocation( new Point( 0, 242 ) );
            trackSelector.Margin = new System.Windows.Forms.Padding( 0 );
            trackSelector.Name = "trackSelector";
            trackSelector.setSize( 446, 250 );
            trackSelector.TabIndex = 0;
#endif
            trackSelector.MouseClick += new BMouseEventHandler( trackSelector_MouseClick );
            trackSelector.MouseUp += new BMouseEventHandler( trackSelector_MouseUp );
            trackSelector.MouseDown += new BMouseEventHandler( trackSelector_MouseDown );
            trackSelector.MouseMove += new BMouseEventHandler( trackSelector_MouseMove );
            trackSelector.KeyDown += new BKeyEventHandler( handleSpaceKeyDown );
            trackSelector.KeyUp += new BKeyEventHandler( handleSpaceKeyUp );
            trackSelector.PreviewKeyDown += new BPreviewKeyDownEventHandler( trackSelector_PreviewKeyDown );
            trackSelector.SelectedTrackChanged += new SelectedTrackChangedEventHandler( trackSelector_SelectedTrackChanged );
            trackSelector.SelectedCurveChanged += new SelectedCurveChangedEventHandler( trackSelector_SelectedCurveChanged );
            trackSelector.RenderRequired += new RenderRequiredEventHandler( trackSelector_RenderRequired );
            trackSelector.PreferredMinHeightChanged += new BEventHandler( trackSelector_PreferredMinHeightChanged );
            trackSelector.MouseDoubleClick += new BMouseEventHandler( trackSelector_MouseDoubleClick );

#if !JAVA
            splitContainer1.Panel2MinSize = trackSelector.getPreferredMinSize();
            this.setMinimumSize( getWindowMinimumSize() );
#endif
#if JAVA
            stripBtnScroll.setSelected( AppManager.mAutoScroll );
#else
            stripBtnScroll.Pushed = AppManager.mAutoScroll;
#endif

            applySelectedTool();
            applyQuantizeMode();

            // Palette Toolの読み込み
#if ENABLE_SCRIPT
            updatePaletteTool();
#endif

#if !JAVA
            splitContainer1.Panel1.BorderStyle = System.Windows.Forms.BorderStyle.None;
            splitContainer1.Panel2.BorderStyle = System.Windows.Forms.BorderStyle.None;
            splitContainer1.BackColor = System.Drawing.Color.FromArgb( 212, 212, 212 );
            splitContainer2.Panel1.Controls.Add( panel1 );
            panel1.Dock = System.Windows.Forms.DockStyle.Fill;
            splitContainer2.Panel2.Controls.Add( panelWaveformZoom );
            //splitContainer2.Panel2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            splitContainer2.Panel2.BorderColor = System.Drawing.Color.FromArgb( 112, 112, 112 );
            splitContainer1.Panel1.Controls.Add( splitContainer2 );
            panelWaveformZoom.Dock = System.Windows.Forms.DockStyle.Fill;
            splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
            splitContainer1.Panel2.Controls.Add( trackSelector );
            trackSelector.Dock = System.Windows.Forms.DockStyle.Fill;
            splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
            splitContainer1.Panel2MinSize = trackSelector.getPreferredMinSize();
            splitContainerProperty.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
#endif

#if ENABLE_PROPERTY
#if JAVA
            splitContainerProperty.setLeftComponent( mPropertyPanelContainer );
            mPropertyPanelContainer.setMinimumSize( new Dimension( 0, 0 ) );
#else
            splitContainerProperty.Panel1.Controls.Add( mPropertyPanelContainer );
            mPropertyPanelContainer.Dock = System.Windows.Forms.DockStyle.Fill;
#endif
#else
            splitContainerProperty.setDividerLocation( 0 );
            splitContainerProperty.setEnabled( false );
            menuVisualProperty.setVisible( false );
#endif

#if !JAVA
            splitContainerProperty.Panel2.Controls.Add( splitContainer1 );
            splitContainerProperty.Dock = System.Windows.Forms.DockStyle.Fill;

            // コントロールの位置・サイズを調節
            splitContainer2.Panel1.SuspendLayout();
            panel1.SuspendLayout();
            pictPianoRoll.SuspendLayout();
            vScroll.SuspendLayout();
            // panel1の中身は
            // picturePositionIndicator
            picturePositionIndicator.Left = 0;
            picturePositionIndicator.Top = 0;
            picturePositionIndicator.Width = panel1.Width;
            // pictPianoRoll
            pictPianoRoll.setBounds( 0, picturePositionIndicator.Height, panel1.Width - vScroll.Width, panel1.Height - picturePositionIndicator.Height - hScroll.Height );
            // vScroll
            vScroll.Left = pictPianoRoll.getWidth();
            vScroll.Top = picturePositionIndicator.Height;
            vScroll.Height = pictPianoRoll.getHeight();
            // pictureBox3
            pictureBox3.Left = 0;
            pictureBox3.Top = panel1.Height - hScroll.getHeight();
            pictureBox3.Height = hScroll.Height;
            // hScroll
            hScroll.Left = pictureBox3.Width;
            hScroll.Top = panel1.Height - hScroll.Height;
            hScroll.Width = panel1.Width - pictureBox3.Width - trackBar.getWidth() - pictureBox2.Width;
            // trackBar
            trackBar.Left = pictureBox3.Width + hScroll.Width;
            trackBar.Top = panel1.Height - hScroll.Height;
            // pictureBox2
            pictureBox2.Left = panel1.Width - vScroll.Width;
            pictureBox2.Top = panel1.Height - hScroll.Height;

            vScroll.ResumeLayout();
            pictPianoRoll.ResumeLayout();
            panel1.ResumeLayout();
            splitContainer2.Panel1.ResumeLayout();
#endif

            updatePropertyPanelState( AppManager.editorConfig.PropertyWindowStatus.State );

            pictPianoRoll.MouseWheel += new BMouseEventHandler( pictPianoRoll_MouseWheel );
            trackSelector.MouseWheel += new BMouseEventHandler( trackSelector_MouseWheel );
            picturePositionIndicator.MouseWheel += new BMouseEventHandler( picturePositionIndicator_MouseWheel );

            menuVisualOverview.CheckedChanged += new BEventHandler( menuVisualOverview_CheckedChanged );

            hScroll.setMaximum( AppManager.getVsqFile().TotalClocks + 240 );
            hScroll.setVisibleAmount( 240 * 4 );

            vScroll.setMaximum( (int)(controller.getScaleY() * 100 * 128) );
            vScroll.setVisibleAmount( 24 * 4 );
#if !JAVA
            hScroll.SmallChange = 240;
            vScroll.SmallChange = 24;
#endif

            trackSelector.setCurveVisible( true );

            // inputTextBoxの初期化
#if JAVA
            AppManager.mInputTextBox = new LyricTextBox( this );
            AppManager.mInputTextBox.setVisible( false );
            AppManager.mInputTextBox.setSize( 80, 22 );
            AppManager.mInputTextBox.setBackground( Color.white );
            AppManager.mInputTextBox.setFont( new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.PLAIN, 9 ) );
            AppManager.mInputTextBox.setEnabled( false );
            AppManager.mInputTextBox.keyPressEvent.add( new BKeyPressEventHandler( this, "mInputTextBox_KeyPress" ) );
#else
            AppManager.mInputTextBox = new LyricTextBox();
            AppManager.mInputTextBox.setVisible( false );
            AppManager.mInputTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            AppManager.mInputTextBox.Width = 80;
            AppManager.mInputTextBox.AcceptsReturn = true;
            AppManager.mInputTextBox.setBackground( Color.white );
            AppManager.mInputTextBox.setFont( new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.PLAIN, AppManager.FONT_SIZE9 ) );
            AppManager.mInputTextBox.setEnabled( false );
            AppManager.mInputTextBox.KeyPress += mInputTextBox_KeyPress;
            AppManager.mInputTextBox.Parent = pictPianoRoll;
            panel1.Controls.Add( AppManager.mInputTextBox );
#endif

            int fps = 1000 / AppManager.editorConfig.MaximumFrameRate;
            timer.setDelay( (fps <= 0) ? 1 : fps );

#if JAVA
#if !DEBUG
            menuHelp.remove( menuHelpDebug );
#endif // !DEBUG
#else // JAVA
#if DEBUG
            menuHelpDebug.setVisible( true );
#endif // DEBUG
#endif // else JAVA

#if !JAVA
            String _HAND = "AAACAAEAICAAABAAEADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAAAAAAAAAA" +
                "AAAgAAAAACAAACAgAAAAACAAIAAgAAAgIAAwMDAAICAgAD/AAAAAP8AAP//AAAAAP8A/wD/AAD//wD///8AAAAAAAAAAAAAAAAAAAA" +
                "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
                "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD" +
                "//wAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAA/wAAAAAAAAAAA" +
                "A//AAAAAP/wAAAAAAAAAAAP/wAAAAD/8AAAAAAAAAAAAP8AAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
                "AAAAAAAAA//8AAAAAAAAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
                "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
                "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////////////////////////////////////////+f////" +
                "D////gf///4H////D///8/z//+H4f//B+D//wfg//+H4f//z/P///w////4H///+B////w////+f//////////////////////////" +
                "//////////////////w==";
            System.IO.MemoryStream ms = null;
            try {
                ms = new System.IO.MemoryStream( Base64.decode( _HAND ) );
                HAND = new System.Windows.Forms.Cursor( ms );
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".ctor; ex=" + ex + "\n" );
            } finally {
                if ( ms != null ) {
                    try {
                        ms.Close();
                    } catch ( Exception ex2 ) {
                        Logger.write( typeof( FormMain ) + ".ctor; ex=" + ex2 + "\n" );
                    }
                }
            }
#endif

            menuHelpLogSwitch.setSelected( Logger.isEnabled() );
            applyShortcut();

            AppManager.mMixerWindow = new FormMixer( this );
            AppManager.iconPalette = new FormIconPalette( this );

            // ファイルを開く
            if ( !str.compare( file, "" ) ) {
                if ( fsys.isFileExists( file ) ) {
                    String low_file = file.ToLower();
                    if ( low_file.EndsWith( ".xvsq" ) ) {
                        openVsqCor( low_file );
                        //AppManager.readVsq( file );
                    } else if ( low_file.EndsWith( ".vsq" ) ) {
                        VsqFileEx vsq = null;
                        try {
                            vsq = new VsqFileEx( file, "Shift_JIS" );
                            AppManager.setVsqFile( vsq );
                            updateBgmMenuState();
                        } catch ( Exception ex ) {
                            Logger.write( typeof( FormMain ) + ".ctor; ex=" + ex + "\n" );
                            serr.println( "FormMain#.ctor; ex=" + ex );
                        }
                    }
                }
            }

            trackBar.setValue( AppManager.editorConfig.DefaultXScale );
            AppManager.setCurrentClock( 0 );
            setEdited( false );

            AppManager.PreviewStarted += new BEventHandler( AppManager_PreviewStarted );
            AppManager.PreviewAborted += new BEventHandler( AppManager_PreviewAborted );
            AppManager.GridVisibleChanged += new BEventHandler( AppManager_GridVisibleChanged );
            AppManager.itemSelection.SelectedEventChanged += new SelectedEventChangedEventHandler( ItemSelectionModel_SelectedEventChanged );
            AppManager.SelectedToolChanged += new BEventHandler( AppManager_SelectedToolChanged );
            AppManager.UpdateBgmStatusRequired += new BEventHandler( AppManager_UpdateBgmStatusRequired );
            AppManager.MainWindowFocusRequired += new BEventHandler( AppManager_MainWindowFocusRequired );
            AppManager.EditedStateChanged += new EditedStateChangedEventHandler( AppManager_EditedStateChanged );
            AppManager.WaveViewReloadRequired += new WaveViewRealoadRequiredEventHandler( AppManager_WaveViewRealoadRequired );
            EditorConfig.QuantizeModeChanged += new BEventHandler( handleEditorConfig_QuantizeModeChanged );

#if ENABLE_PROPERTY
            mPropertyPanelContainer.StateChangeRequired += new StateChangeRequiredEventHandler( mPropertyPanelContainer_StateChangeRequired );
#endif

            updateRecentFileMenu();

            // C3が画面中央に来るように調整
            int draft_start_to_draw_y = 68 * (int)(100 * controller.getScaleY()) - pictPianoRoll.getHeight() / 2;
            int draft_vscroll_value = (int)((draft_start_to_draw_y * (double)vScroll.getMaximum()) / (128 * (int)(100 * controller.getScaleY()) - vScroll.getHeight()));
            try {
                vScroll.setValue( draft_vscroll_value );
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".FormMain_Load; ex=" + ex + "\n" );
            }

            // x=97がプリメジャークロックになるように調整
            int cp = AppManager.getVsqFile().getPreMeasureClocks();
            int draft_hscroll_value = (int)(cp - 24.0 * controller.getScaleXInv());
            try {
                hScroll.setValue( draft_hscroll_value );
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".FormMain_Load; ex=" + ex + "\n" );
            }

            //s_pen_dashed_171_171_171.DashPattern = new float[] { 3, 3 };
            //s_pen_dashed_209_204_172.DashPattern = new float[] { 3, 3 };

            menuVisualNoteProperty.setSelected( AppManager.editorConfig.ShowExpLine );
            menuVisualLyrics.setSelected( AppManager.editorConfig.ShowLyric );
            menuVisualMixer.setSelected( AppManager.editorConfig.MixerVisible );
            menuVisualPitchLine.setSelected( AppManager.editorConfig.ViewAtcualPitch );

            updateMenuFonts();

            AppManager.mMixerWindow.FederChanged += new FederChangedEventHandler( mixerWindow_FederChanged );
            AppManager.mMixerWindow.PanpotChanged += new PanpotChangedEventHandler( mixerWindow_PanpotChanged );
            AppManager.mMixerWindow.MuteChanged += new MuteChangedEventHandler( mixerWindow_MuteChanged );
            AppManager.mMixerWindow.SoloChanged += new SoloChangedEventHandler( mixerWindow_SoloChanged );
            AppManager.mMixerWindow.updateStatus();
            if ( AppManager.editorConfig.MixerVisible ) {
                AppManager.mMixerWindow.setVisible( true );
            }
            AppManager.mMixerWindow.FormClosing += new BFormClosingEventHandler( mixerWindow_FormClosing );

            Point p1 = AppManager.editorConfig.FormIconPaletteLocation.toPoint();
            if ( !PortUtil.isPointInScreens( p1 ) ) {
                Rectangle workingArea = PortUtil.getWorkingArea( this );
                p1 = new Point( workingArea.x, workingArea.y );
            }
            AppManager.iconPalette.setLocation( p1 );
            if ( AppManager.editorConfig.IconPaletteVisible ) {
                AppManager.iconPalette.setVisible( true );
            }
            AppManager.iconPalette.FormClosing += new BFormClosingEventHandler( iconPalette_FormClosing );
            AppManager.iconPalette.LocationChanged += new BEventHandler( iconPalette_LocationChanged );

            trackSelector.CommandExecuted += new BEventHandler( trackSelector_CommandExecuted );

#if ENABLE_SCRIPT
            updateScriptShortcut();
            // RunOnceという名前のスクリプトがあれば,そいつを実行
            for ( Iterator<String> itr = ScriptServer.getScriptIdIterator(); itr.hasNext(); ) {
                String id = itr.next();
                if ( str.compare( PortUtil.getFileNameWithoutExtension( id ).ToLower(), "runonce" ) ) {
                    ScriptServer.invokeScript( id, AppManager.getVsqFile() );
                    break;
                }
            }
#endif

            clearTempWave();
            updateVibratoPresetMenu();
            mPencilMode.setMode( PencilModeEnum.Off );
            updateCMenuPianoFixed();
            loadGameControler();
#if ENABLE_MIDI
            reloadMidiIn();
#endif
            menuVisualWaveform.setSelected( AppManager.editorConfig.ViewWaveform );

            updateRendererMenu();

            // ウィンドウの位置・サイズを再現
            if ( AppManager.editorConfig.WindowMaximized ) {
                setExtendedState( BForm.MAXIMIZED_BOTH );
            } else {
                setExtendedState( BForm.NORMAL );
            }
            Rectangle bounds = AppManager.editorConfig.WindowRect;
            this.setBounds( bounds );
            // ウィンドウ位置・サイズの設定値が、使えるディスプレイのどれにも被っていない場合
            Rectangle rc2 = PortUtil.getScreenBounds( this );
            if ( bounds.x < rc2.x ||
                 rc2.x + rc2.width < bounds.x + bounds.width ||
                 bounds.y < rc2.y ||
                 rc2.y + rc2.height < bounds.y + bounds.height ) {
                bounds.x = rc2.x;
                bounds.y = rc2.y;
                this.setBounds( bounds );
                AppManager.editorConfig.WindowRect = bounds;
            }
            this.WindowStateChanged += new BEventHandler( FormMain_WindowStateChanged );
            this.LocationChanged += new BEventHandler( FormMain_LocationChanged );

            updateScrollRangeHorizontal();
            updateScrollRangeVertical();

            // プロパティウィンドウの位置を復元
            Rectangle rc1 = PortUtil.getScreenBounds( this );
            Rectangle rcScreen = new Rectangle( rc1.x, rc1.y, rc1.width, rc1.height );
            Point p = this.getLocation();
            XmlRectangle xr = AppManager.editorConfig.PropertyWindowStatus.Bounds;
            Point p0 = new Point( xr.x, xr.y );
            Point a = new Point( p.x + p0.x, p.y + p0.y );
            Rectangle rc = new Rectangle( a.x,
                                          a.y,
                                          AppManager.editorConfig.PropertyWindowStatus.Bounds.getWidth(),
                                          AppManager.editorConfig.PropertyWindowStatus.Bounds.getHeight() );

            if ( a.y > rcScreen.y + rcScreen.height ) {
                a = new Point( a.x, rcScreen.y + rcScreen.height - rc.height );
            }
            if ( a.y < rcScreen.y ) {
                a = new Point( a.x, rcScreen.y );
            }
            if ( a.x > rcScreen.x + rcScreen.width ) {
                a = new Point( rcScreen.x + rcScreen.width - rc.width, a.y );
            }
            if ( a.x < rcScreen.x ) {
                a = new Point( rcScreen.x, a.y );
            }
#if DEBUG
            AppManager.debugWriteLine( "FormMain_Load; a=" + a );
#endif

#if ENABLE_PROPERTY
            AppManager.propertyWindow.setBounds( a.x, a.y, rc.width, rc.height );
            AppManager.propertyWindow.WindowStateChanged += new BEventHandler( propertyWindow_WindowStateChanged );
            AppManager.propertyWindow.LocationChanged += new BEventHandler( propertyWindow_LocationOrSizeChanged );
            AppManager.propertyWindow.SizeChanged += new BEventHandler( propertyWindow_LocationOrSizeChanged );
            AppManager.propertyWindow.FormClosing += new BFormClosingEventHandler( propertyWindow_FormClosing );
            AppManager.propertyPanel.CommandExecuteRequired += new CommandExecuteRequiredEventHandler( propertyPanel_CommandExecuteRequired );
#endif
            updateBgmMenuState();
            AppManager.mLastTrackSelectorHeight = trackSelector.getPreferredMinSize();
            flipControlCurveVisible( true );

            repaint();
            updateLayout();
#if DEBUG
            menuHidden.setVisible( true );
#else
            menuHidden.setVisible( false );
#endif

#if !ENABLE_VOCALOID
            menuTrackRenderer.remove( menuTrackRendererVOCALOID2 );
            menuTrackRenderer.remove( menuTrackRendererVOCALOID1 );
            cMenuTrackTabRenderer.remove( cMenuTrackTabRendererVOCALOID2 );
            cMenuTrackTabRenderer.remove( cMenuTrackTabRendererVOCALOID1 );
#endif

#if !ENABLE_AQUESTONE
            menuTrackRenderer.remove( menuTrackRendererAquesTone );
            cMenuTrackTabRenderer.remove( cMenuTrackTabRendererAquesTone );
#endif

#if JAVA
            menuVisual.remove( menuVisualPluginUi );
            menuSetting.remove( menuSettingGameControler );
#endif

#if JAVA_MAC
            // Macの一般的なメニュー編成にあわせる
            com.apple.eawt.Application app = com.apple.eawt.Application.getApplication();
#if JAVA_1_5
            // 「Cadenciiについて」
            app.setAboutHandler( new com.apple.eawt.AboutHandler(){
                public void handleAbout( com.apple.eawt.AppEvent.AboutEvent arg0 ) {
                    menuHelpAbout_Click( null, null );
                }
            } );

            // 「Cadenciiを終了」
            app.setQuitHandler( new com.apple.eawt.QuitHandler(){
                public void handleQuitRequestWith( com.apple.eawt.AppEvent.QuitEvent arg0, com.apple.eawt.QuitResponse arg1 ) {
                    if( handleFormClosing() ){
                        arg1.cancelQuit();
                    }else{
                        dispose();
                    }
                }
            } );

            // 「環境設定」
            app.setPreferencesHandler( new com.apple.eawt.PreferencesHandler(){
                public void handlePreferences( com.apple.eawt.AppEvent.PreferencesEvent arg0 ){
                    menuSettingPreference_Click( null, null );
                }
            });
#else // JAVA_1_5
              app.setEnabledPreferencesMenu( true );
              app.setEnabledAboutMenu( true );
              app.addApplicationListener( new com.apple.eawt.ApplicationListener(){
                        public void handleAbout(ApplicationEvent arg0) {
                      arg0.setHandled( true );
                      menuHelpAbout_Click( null, null );
                        }
      
                        public void handleOpenApplication(ApplicationEvent arg0) {
                        }
      
                        public void handleOpenFile(ApplicationEvent arg0) {
                        }
      
                        public void handlePreferences(ApplicationEvent arg0) {
                              menuSettingPreference_Click( null, null );
                        }
      
                        public void handlePrintFile(ApplicationEvent arg0) {
                        }
      
                        public void handleQuit(ApplicationEvent arg0) {
                              arg0.setHandled( !handleFormClosing() );
                        }
      
                        public void handleReOpenApplication(ApplicationEvent arg0) {
                        }
              });
#endif
              menuHelp.remove( menuHelpAbout );
              menuFile.remove( menuFileSeparator3 );
              menuFile.remove( menuFileQuit );
              menuSetting.remove( menuSettingPreference );
#endif // JAVA_MAC

#if !JAVA
#if DEBUG
            System.Collections.Generic.List<ValuePair<String, String>> list = new System.Collections.Generic.List<ValuePair<String, String>>();
            foreach ( System.Reflection.FieldInfo fi in typeof( EditorConfig ).GetFields() ) {
                if ( fi.IsPublic && !fi.IsStatic ) {
                    list.Add( new ValuePair<String, String>( fi.Name, fi.FieldType.ToString() ) );
                }
            }

            foreach ( System.Reflection.PropertyInfo pi in typeof( EditorConfig ).GetProperties() ) {
                if ( !pi.CanRead || !pi.CanWrite ) {
                    continue;
                }
                System.Reflection.MethodInfo getmethod = pi.GetGetMethod();
                System.Reflection.MethodInfo setmethod = pi.GetSetMethod();
                if ( !setmethod.IsPublic || setmethod.IsStatic ) {
                    continue;
                }
                if ( !getmethod.IsPublic || getmethod.IsStatic ) {
                    continue;
                }
                list.Add( new ValuePair<String, String>( pi.Name, pi.PropertyType.ToString() ) );
            }

            list.Sort();

            System.IO.StreamWriter sw = null;
            try {
                sw = new System.IO.StreamWriter( "EditorConfig.txt" );
                foreach ( ValuePair<String, String> s in list ) {
                    sw.WriteLine( s.Key );
                }
                sw.WriteLine( "--------------------------------------------" );
                foreach ( ValuePair<String, String> s in list ) {
                    sw.WriteLine( s.Value + "\t" + s.Key + ";" );
                }
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".ctor; ex=" + ex + "\n" );
            } finally {
                if ( sw != null ) {
                    try {
                        sw.Close();
                    } catch ( Exception ex2 ) {
                        Logger.write( typeof( FormMain ) + ".ctor; ex=" + ex2 + "\n" );
                    }
                }
            }
#endif
#endif
        }
        #endregion

        #region FormMainUiの実装

01214         public void focusPianoRoll()
        {
#if JAVA
            pictPianoRoll.requestFocus();
#else
            pictPianoRoll.Focus();
#endif
        }

        #endregion

        #region helper methods
        /// <summary>
        /// 指定した歌手とリサンプラーについて,設定値に登録されていないものだったら登録する.
        /// </summary>
        /// <param name="resampler_path"></param>
        /// <param name="singer_path"></param>
01231         private void checkUnknownResamplerAndSinger( ByRef<String> resampler_path, ByRef<String> singer_path )
        {
            String utau = Utility.getExecutingUtau();
            String utau_dir = "";
            if ( !str.compare( utau, "" ) ) {
                utau_dir = PortUtil.getDirectoryName( utau );
            }

            // 可能なら,VOICEの文字列を置換する
            String search = "%VOICE%";
            if ( str.startsWith( singer_path.value, search ) && str.length( singer_path.value ) > str.length( search ) ) {
                singer_path.value = str.sub( singer_path.value, str.length( search ) );
                singer_path.value = fsys.combine( fsys.combine( utau_dir, "voice" ), singer_path.value );
            }

            // 歌手はknownかunknownか?
            // 歌手指定が知らない歌手だった場合に,ダイアログを出すかどうか
            boolean check_unknown_singer = false;
            if ( fsys.isFileExists( fsys.combine( singer_path.value, "oto.ini" ) ) ) {
                // oto.iniが存在する場合
                // editorConfigに入っていない場合に,ダイアログを出す
                boolean found = false;
                for ( int i = 0; i < vec.size( AppManager.editorConfig.UtauSingers ); i++ ) {
                    SingerConfig sc = vec.get( AppManager.editorConfig.UtauSingers, i );
                    if ( sc == null ) {
                        continue;
                    }
                    if ( str.compare( sc.VOICEIDSTR, singer_path.value ) ) {
                        found = true;
                        break;
                    }
                }
                check_unknown_singer = !found;
            }

            // リサンプラーが知っているやつかどうか
            boolean check_unknwon_resampler = false;
#if DEBUG
            sout.println( "FormMain#checkUnknownResamplerAndSinger; resampler_path.value=" + resampler_path.value );
#endif
            String resampler_dir = PortUtil.getDirectoryName( resampler_path.value );
            if ( str.compare( resampler_dir, "" ) ) {
                // ディレクトリが空欄なので,UTAUのデフォルトのリサンプラー指定である
                resampler_path.value = fsys.combine( utau_dir, resampler_path.value );
                resampler_dir = PortUtil.getDirectoryName( resampler_path.value );
            }
            if ( !str.compare( resampler_dir, "" ) &&  fsys.isFileExists( resampler_path.value ) ) {
                boolean found = false;
                for ( int i = 0; i < AppManager.editorConfig.getResamplerCount(); i++ ) {
                    String resampler = AppManager.editorConfig.getResamplerAt( i );
                    if ( str.compare( resampler, resampler_path.value ) ) {
                        found = true;
                        break;
                    }
                }
                check_unknwon_resampler = !found;
            }

            // unknownな歌手やリサンプラーが発見された場合.
            // 登録するかどうか問い合わせるダイアログを出す
            FormCheckUnknownSingerAndResampler dialog = null;
            try {
                if ( check_unknown_singer || check_unknwon_resampler ) {
                    dialog = new FormCheckUnknownSingerAndResampler( singer_path.value, check_unknown_singer, resampler_path.value, check_unknwon_resampler );
                    dialog.setLocation( getFormPreferedLocation( dialog ) );
                    BDialogResult dr = AppManager.showModalDialog( dialog, this );
                    if ( dr != BDialogResult.OK ) {
                        return;
                    }

                    // 登録する
                    // リサンプラー
                    if ( dialog.isResamplerChecked() ) {
                        String path = dialog.getResamplerPath();
                        if ( fsys.isFileExists( path ) ) {
                            AppManager.editorConfig.addResampler( path, false );
                        }
                    }
                    // 歌手
                    if ( dialog.isSingerChecked() ) {
                        String path = dialog.getSingerPath();
                        if ( fsys.isDirectoryExists( path ) ) {
                            SingerConfig sc = new SingerConfig();
                            Utility.readUtauSingerConfig( path, sc );
                            vec.add( AppManager.editorConfig.UtauSingers, sc );
                        }
                        AppManager.reloadUtauVoiceDB();
                    }
                }
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".checkUnknownResamplerAndSinger; ex=" + ex + "\n" );
            } finally {
                if ( dialog != null ) {
                    try {
                        dialog.close();
                    } catch ( Exception ex2 ) {
                    }
                }
            }
        }

        /// <summary>
        /// ピアノロールの縦軸の拡大率をdelta段階上げます
        /// </summary>
        /// <param name="delta"></param>
01336         private void zoomY( int delta )
        {
            int scaley = AppManager.editorConfig.PianoRollScaleY;
            int draft = scaley + delta;
            if ( draft < EditorConfig.MIN_PIANOROLL_SCALEY ) {
                draft = EditorConfig.MIN_PIANOROLL_SCALEY;
            }
            if ( EditorConfig.MAX_PIANOROLL_SCALEY < draft ) {
                draft = EditorConfig.MAX_PIANOROLL_SCALEY;
            }
            if ( scaley != draft ) {
                AppManager.editorConfig.PianoRollScaleY = draft;
                updateScrollRangeVertical();
                controller.setStartToDrawY( calculateStartToDrawY( vScroll.getValue() ) );
                updateDrawObjectList();
            }
        }

        /// <summary>
        /// ズームスライダの現在の値から,横方向の拡大率を計算します
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
01359         private float getScaleXFromTrackBarValue( int value )
        {
            return value / 480.0f;
        }

        /// <summary>
        /// ユーザー定義のビブラートのプリセット関係のメニューの表示状態を更新します
        /// </summary>
01367         private void updateVibratoPresetMenu()
        {
#if JAVA
            menuLyricCopyVibratoToPreset.removeAll();
            int size = AppManager.editorConfig.AutoVibratoCustom.size();
            for ( int i = 0; i < size; i++ ) {
                VibratoHandle handle = AppManager.editorConfig.AutoVibratoCustom.get( i );
                BMenuItem item = new BMenuItem();
                item.setText( handle.getCaption() );
                item.clickEvent.add( new BEventHandler( this, "handleVibratoPresetSubelementClick" ) );
                menuLyricCopyVibratoToPreset.add( item );
            }
#else
            // 現在の項目数に過不足があれば調節する
            int size = AppManager.editorConfig.AutoVibratoCustom.size();
            int delta = size - menuLyricCopyVibratoToPreset.DropDownItems.Count;
            if ( delta > 0 ) {
                // 項目を増やさないといけない
                for ( int i = 0; i < delta; i++ ) {
                    System.Windows.Forms.ToolStripMenuItem item =
                        new System.Windows.Forms.ToolStripMenuItem(
                            "", null, new BEventHandler( handleVibratoPresetSubelementClick ) );
                    menuLyricCopyVibratoToPreset.DropDownItems.Add( item );
                }
            } else if ( delta < 0 ) {
                // 項目を減らさないといけない
                for ( int i = 0; i < -delta; i++ ) {
                    System.Windows.Forms.ToolStripItem item = menuLyricCopyVibratoToPreset.DropDownItems[0];
                    menuLyricCopyVibratoToPreset.DropDownItems.RemoveAt( 0 );
                    item.Dispose();
                }
            }

            // 表示状態を更新
            for ( int i = 0; i < size; i++ ) {
                VibratoHandle handle = AppManager.editorConfig.AutoVibratoCustom.get( i );
                menuLyricCopyVibratoToPreset.DropDownItems[i].Text = handle.getCaption();
            }
#endif
        }

        /// <summary>
        /// MIDIステップ入力中に,ソングポジションが動いたときの処理を行います
        /// AppManager.mAddingEventが非nullの時,音符の先頭は決まっているので,
        /// ソングポジションと,音符の先頭との距離から音符の長さを算出し,更新する
        /// AppManager.mAddingEventがnullの時は何もしない
        /// </summary>
01414         private void updateNoteLengthStepSequencer()
        {
            if ( !controller.isStepSequencerEnabled() ) {
                return;
            }

            VsqEvent item = AppManager.mAddingEvent;
            if ( item == null ) {
                return;
            }

            int song_position = AppManager.getCurrentClock();
            int start = item.Clock;
            int length = song_position - start;
            if ( length < 0 ) length = 0;
            Utility.editLengthOfVsqEvent(
                item,
                length,
                AppManager.vibratoLengthEditingRule );
        }

        /// <summary>
        /// 現在追加しようとしている音符の内容(AppManager.mAddingEvent)をfixします
        /// </summary>
        /// <returns></returns>
01439         private void fixAddingEvent()
        {
            VsqFileEx vsq = AppManager.getVsqFile();
            int selected = AppManager.getSelected();
            VsqTrack vsq_track = vsq.Track.get( selected );
            LyricHandle lyric = new LyricHandle( "あ", "a" );
            VibratoHandle vibrato = null;
            int vibrato_delay = 0;
            if ( AppManager.editorConfig.EnableAutoVibrato ) {
                int note_length = AppManager.mAddingEvent.ID.getLength();
                // 音符位置での拍子を調べる
                Timesig timesig = vsq.getTimesigAt( AppManager.mAddingEvent.Clock );

                // ビブラートを自動追加するかどうかを決める閾値
                int threshold = AppManager.editorConfig.AutoVibratoThresholdLength;
                if ( note_length >= threshold ) {
                    int vibrato_clocks = 0;
                    if ( AppManager.editorConfig.DefaultVibratoLength == DefaultVibratoLengthEnum.L100 ) {
                        vibrato_clocks = note_length;
                    } else if ( AppManager.editorConfig.DefaultVibratoLength == DefaultVibratoLengthEnum.L50 ) {
                        vibrato_clocks = note_length / 2;
                    } else if ( AppManager.editorConfig.DefaultVibratoLength == DefaultVibratoLengthEnum.L66 ) {
                        vibrato_clocks = note_length * 2 / 3;
                    } else if ( AppManager.editorConfig.DefaultVibratoLength == DefaultVibratoLengthEnum.L75 ) {
                        vibrato_clocks = note_length * 3 / 4;
                    }
                    SynthesizerType type = SynthesizerType.VOCALOID2;
                    RendererKind kind = VsqFileEx.getTrackRendererKind( vsq.Track.get( selected ) );
                    if ( kind == RendererKind.VOCALOID1 ) {
                        type = SynthesizerType.VOCALOID1;
                    }
                    vibrato = AppManager.editorConfig.createAutoVibrato( type, vibrato_clocks );
                    vibrato_delay = note_length - vibrato_clocks;
                }
            }

            // oto.iniの設定を反映
            VsqEvent item = vsq_track.getSingerEventAt( AppManager.mAddingEvent.Clock );
            SingerConfig singerConfig = null;
            if ( item != null && item.ID != null && item.ID.IconHandle != null ) {
                singerConfig = AppManager.getSingerInfoUtau( item.ID.IconHandle.Language, item.ID.IconHandle.Program );
            }

            if ( singerConfig != null && AppManager.mUtauVoiceDB.containsKey( singerConfig.VOICEIDSTR ) ) {
                UtauVoiceDB utauVoiceDb = AppManager.mUtauVoiceDB.get( singerConfig.VOICEIDSTR );
                OtoArgs otoArgs = utauVoiceDb.attachFileNameFromLyric( lyric.L0.Phrase );
                AppManager.mAddingEvent.UstEvent.setPreUtterance( otoArgs.msPreUtterance );
                AppManager.mAddingEvent.UstEvent.setVoiceOverlap( otoArgs.msOverlap );
            }

            // 自動ノーマライズのモードで、処理を分岐
            if ( AppManager.mAutoNormalize ) {
                VsqTrack work = (VsqTrack)vsq_track.clone();
                AppManager.mAddingEvent.ID.type = VsqIDType.Anote;
                AppManager.mAddingEvent.ID.Dynamics = 64;
                AppManager.mAddingEvent.ID.VibratoHandle = vibrato;
                AppManager.mAddingEvent.ID.LyricHandle = lyric;
                AppManager.mAddingEvent.ID.VibratoDelay = vibrato_delay;

                boolean changed = true;
                while ( changed ) {
                    changed = false;
                    for ( int i = 0; i < work.getEventCount(); i++ ) {
                        int start_clock = work.getEvent( i ).Clock;
                        int end_clock = work.getEvent( i ).ID.getLength() + start_clock;
                        if ( start_clock < AppManager.mAddingEvent.Clock && AppManager.mAddingEvent.Clock < end_clock ) {
                            work.getEvent( i ).ID.setLength( AppManager.mAddingEvent.Clock - start_clock );
                            changed = true;
                        } else if ( start_clock == AppManager.mAddingEvent.Clock ) {
                            work.removeEvent( i );
                            changed = true;
                            break;
                        } else if ( AppManager.mAddingEvent.Clock < start_clock && start_clock < AppManager.mAddingEvent.Clock + AppManager.mAddingEvent.ID.getLength() ) {
                            AppManager.mAddingEvent.ID.setLength( start_clock - AppManager.mAddingEvent.Clock );
                            changed = true;
                        }
                    }
                }
                VsqEvent add = (VsqEvent)AppManager.mAddingEvent.clone();
                work.addEvent( add );
                CadenciiCommand run = VsqFileEx.generateCommandTrackReplace( selected,
                                                                             work,
                                                                             AppManager.getVsqFile().AttachedCurves.get( selected - 1 ) );
                AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                setEdited( true );
            } else {
                VsqEvent[] items = new VsqEvent[1];
                AppManager.mAddingEvent.ID.type = VsqIDType.Anote;
                AppManager.mAddingEvent.ID.Dynamics = 64;
                items[0] = (VsqEvent)AppManager.mAddingEvent.clone();// new VsqEvent( 0, AppManager.addingEvent.ID );
                items[0].Clock = AppManager.mAddingEvent.Clock;
                items[0].ID.LyricHandle = lyric;
                items[0].ID.VibratoDelay = vibrato_delay;
                items[0].ID.VibratoHandle = vibrato;

                CadenciiCommand run = new CadenciiCommand( VsqCommand.generateCommandEventAddRange( AppManager.getSelected(), items ) );
                AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                setEdited( true );
            }
        }

        /// <summary>
        /// 現在のツールバーの場所を保存します
        /// </summary>
01543         private void saveToolbarLocation()
        {
#if JAVA
            // TODO:
#else
            if ( this.WindowState == System.Windows.Forms.FormWindowState.Minimized ) return;
            // どのツールバーが一番上かつ左にあるか?
            var list = new System.Collections.Generic.List<RebarBand>();
            list.AddRange( new RebarBand[]{
                bandFile,
                bandMeasure,
                bandPosition,
                bandTool } );
            // ソートする
            boolean changed = true;
            while ( changed ) {
                changed = false;
                for ( int i = 0; i < list.Count - 1; i++ ) {
                    // y座標が大きいか,y座標が同じでもx座標が大きい場合に入れ替える
                    boolean swap =
                        (list[i].Location.Y > list[i + 1].Location.Y) ||
                        (list[i].Location.Y == list[i + 1].Location.Y && list[i].Location.X > list[i + 1].Location.X);
                    if ( swap ) {
                        var a = list[i];
                        list[i] = list[i + 1];
                        list[i + 1] = a;
                        changed = true;
                    }
                }
            }
            // 各ツールバー毎に,ツールバーの状態を検出して保存
            saveToolbarLocationCore(
                list,
                bandFile,
                out AppManager.editorConfig.BandSizeFile,
                out AppManager.editorConfig.BandNewRowFile,
                out AppManager.editorConfig.BandOrderFile );
            saveToolbarLocationCore(
                list,
                bandMeasure,
                out AppManager.editorConfig.BandSizeMeasure,
                out AppManager.editorConfig.BandNewRowMeasure,
                out AppManager.editorConfig.BandOrderMeasure );
            saveToolbarLocationCore(
                list,
                bandPosition,
                out AppManager.editorConfig.BandSizePosition,
                out AppManager.editorConfig.BandNewRowPosition,
                out AppManager.editorConfig.BandOrderPosition );
            saveToolbarLocationCore(
                list,
                bandTool,
                out AppManager.editorConfig.BandSizeTool,
                out AppManager.editorConfig.BandNewRowTool,
                out AppManager.editorConfig.BandOrderTool );
#endif
        }

#if !JAVA
        /// <summary>
        /// ツールバーの位置の順に並べ替えたリストの中の一つのツールバーに対して,その状態を検出して保存
        /// </summary>
        /// <param name="list"></param>
        /// <param name="band"></param>
        /// <param name="band_size"></param>
        /// <param name="new_row"></param>
01609         private void saveToolbarLocationCore(
            System.Collections.Generic.List<RebarBand> list,
            RebarBand band,
            out int band_size,
            out bool new_row,
            out int band_order )
        {
            band_size = 0;
            new_row = true;
            band_order = 0;
            var indx = list.IndexOf( band );
            if ( indx < 0 ) return;
            new_row = (indx == 0) ? false : (list[indx - 1].Location.Y < list[indx].Location.Y);
            band_size = band.BandSize;
            band_order = indx;
        }
#endif

        private static int doQuantize( int clock, int unit )
        {
            int odd = clock % unit;
            int new_clock = clock - odd;
            if ( odd > unit / 2 ) {
                new_clock += unit;
            }
            return new_clock;
        }

        /// <summary>
        /// デフォルトのストロークを取得します
        /// </summary>
        /// <returns></returns>
01641         private BasicStroke getStrokeDefault()
        {
            if ( mStrokeDefault == null ) {
                mStrokeDefault = new BasicStroke();
            }
            return mStrokeDefault;
        }

        /// <summary>
        /// 描画幅が2pxのストロークを取得します
        /// </summary>
        /// <returns></returns>
01653         private BasicStroke getStroke2px()
        {
            if ( mStroke2px == null ) {
                mStroke2px = new BasicStroke( 2.0f );
            }
            return mStroke2px;
        }

        /// <summary>
        /// 選択された音符の長さを、指定したゲートタイム分長くします。
        /// </summary>
        /// <param name="delta_length"></param>
01665         private void lengthenSelectedEvent( int delta_length )
        {
            if ( delta_length == 0 ) {
                return;
            }

            VsqFileEx vsq = AppManager.getVsqFile();
            if ( vsq == null ) {
                return;
            }

            int selected = AppManager.getSelected();

            Vector<VsqEvent> items = new Vector<VsqEvent>();
            for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                SelectedEventEntry item = itr.next();
                if ( item.editing.ID.type != VsqIDType.Anote &&
                     item.editing.ID.type != VsqIDType.Aicon ) {
                    continue;
                }

                // クレッシェンド、デクレッシェンドでないものを省く
                if ( item.editing.ID.type == VsqIDType.Aicon ) {
                    if ( item.editing.ID.IconDynamicsHandle == null ) {
                        continue;
                    }
                    if ( !item.editing.ID.IconDynamicsHandle.isCrescendType() &&
                         !item.editing.ID.IconDynamicsHandle.isDecrescendType() ) {
                        continue;
                    }
                }

                // 長さを変える。0未満になると0に直す
                int length = item.editing.ID.getLength();
                int draft = length + delta_length;
                if ( draft < 0 ) {
                    draft = 0;
                }
                if ( length == draft ) {
                    continue;
                }

                // ビブラートの長さを変更
                VsqEvent add = (VsqEvent)item.editing.clone();
                Utility.editLengthOfVsqEvent( add, draft, AppManager.vibratoLengthEditingRule );
                items.add( add );
            }

            if ( items.size() <= 0 ) {
                return;
            }

            // コマンドを発行
            CadenciiCommand run = new CadenciiCommand(
                VsqCommand.generateCommandEventReplaceRange(
                    selected, items.toArray( new VsqEvent[] { } ) ) );
            AppManager.editHistory.register( vsq.executeCommand( run ) );

            // 編集されたものを再選択する
            for ( Iterator<VsqEvent> itr = items.iterator(); itr.hasNext(); ) {
                VsqEvent item = itr.next();
                AppManager.itemSelection.addEvent( item.InternalID );
            }

            // 編集が施された。
            setEdited( true );
            updateDrawObjectList();

            refreshScreen();
        }

        /// <summary>
        /// 選択された音符の音程とゲートタイムを、指定されたノートナンバーおよびゲートタイム分上下させます。
        /// </summary>
        /// <param name="delta_note"></param>
        /// <param name="delta_clock"></param>
01741         private void moveUpDownLeftRight( int delta_note, int delta_clock )
        {
            VsqFileEx vsq = AppManager.getVsqFile();
            if ( vsq == null ) {
                return;
            }

            Vector<VsqEvent> items = new Vector<VsqEvent>();
            int selected = AppManager.getSelected();
            int note_max = -1;
            int note_min = 129;
            int clock_max = int.MinValue;
            int clock_min = int.MaxValue;
            for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                SelectedEventEntry item = itr.next();
                if ( item.editing.ID.type != VsqIDType.Anote ) {
                    continue;
                }
                VsqEvent add = null;

                // 音程
                int note = item.editing.ID.Note;
                if ( delta_note != 0 && 0 <= note + delta_note && note + delta_note <= 127 ) {
                    add = (VsqEvent)item.editing.clone();
                    add.ID.Note += delta_note;
                    note_max = Math.Max( note_max, add.ID.Note );
                    note_min = Math.Min( note_min, add.ID.Note );
                }

                // ゲートタイム
                int clockstart = item.editing.Clock;
                int clockend = clockstart + item.editing.ID.getLength();
                if ( delta_clock != 0 ) {
                    if ( add == null ) {
                        add = (VsqEvent)item.editing.clone();
                    }
                    add.Clock += delta_clock;
                    clock_max = Math.Max( clock_max, clockend + delta_clock );
                    clock_min = Math.Min( clock_min, clockstart );
                }

                if ( add != null ) {
                    items.add( add );
                }
            }
            if ( items.size() <= 0 ) {
                return;
            }

            // コマンドを発行
            CadenciiCommand run = new CadenciiCommand(
                VsqCommand.generateCommandEventReplaceRange(
                    selected, items.toArray( new VsqEvent[] { } ) ) );
            AppManager.editHistory.register( vsq.executeCommand( run ) );

            // 編集されたものを再選択する
            for ( Iterator<VsqEvent> itr = items.iterator(); itr.hasNext(); ) {
                VsqEvent item = itr.next();
                AppManager.itemSelection.addEvent( item.InternalID );
            }

            // 編集が施された。
            setEdited( true );
            updateDrawObjectList();

            // 音符が見えるようにする。音程方向
            if ( delta_note > 0 ) {
                note_max++;
                if ( 127 < note_max ) {
                    note_max = 127;
                }
                ensureVisibleY( note_max );
            } else if ( delta_note < 0 ) {
                note_min -= 2;
                if ( note_min < 0 ) {
                    note_min = 0;
                }
                ensureVisibleY( note_min );
            }

            // 音符が見えるようにする。時間方向
            if ( delta_clock > 0 ) {
                ensureVisible( clock_max );
            } else if ( delta_clock < 0 ) {
                ensureVisible( clock_min );
            }
            refreshScreen();
        }

        /// <summary>
        /// マウス位置におけるIDを返します。該当するIDが無ければnullを返します
        /// rectには、該当するIDがあればその画面上での形状を、該当するIDがなければ、
        /// 画面上で最も近かったIDの画面上での形状を返します
        /// </summary>
        /// <param name="mouse_position"></param>
        /// <returns></returns>
01837         private VsqEvent getItemAtClickedPosition( Point mouse_position, ByRef<Rectangle> rect )
        {
            rect.value = new Rectangle();
            int width = pictPianoRoll.getWidth();
            int height = pictPianoRoll.getHeight();
            int key_width = AppManager.keyWidth;

            // マウスが可視範囲になければ死ぬ
            if ( mouse_position.x < key_width || width < mouse_position.x )
            {
                return null;
            }
            if ( mouse_position.y < 0 || height < mouse_position.y )
            {
                return null;
            }

            // 表示中のトラック番号が異常だったら死ぬ
            int selected = AppManager.getSelected();
            if ( selected < 1 )
            {
                return null;
            }
            lock ( AppManager.mDrawObjects )
            {
                Vector<DrawObject> dobj_list = AppManager.mDrawObjects.get( selected - 1 );
                int count = dobj_list.size();
                int start_to_draw_x = controller.getStartToDrawX();
                int start_to_draw_y = controller.getStartToDrawY();
                VsqFileEx vsq = AppManager.getVsqFile();
                VsqTrack vsq_track = vsq.Track.get( selected );

                for ( int i = 0; i < count; i++ )
                {
                    DrawObject dobj = dobj_list.get( i );
                    int x = dobj.mRectangleInPixel.x + key_width - start_to_draw_x;
                    int y = dobj.mRectangleInPixel.y - start_to_draw_y;
                    if ( mouse_position.x < x )
                    {
                        continue;
                    }
                    if ( x + dobj.mRectangleInPixel.width < mouse_position.x )
                    {
                        continue;
                    }
                    if ( width < x )
                    {
                        break;
                    }
                    if ( mouse_position.y < y )
                    {
                        continue;
                    }
                    if ( y + dobj.mRectangleInPixel.height < mouse_position.y )
                    {
                        continue;
                    }
                    int internal_id = dobj.mInternalID;
                    for ( Iterator<VsqEvent> itr = vsq_track.getEventIterator(); itr.hasNext(); )
                    {
                        VsqEvent item = itr.next();
                        if ( item.InternalID == internal_id )
                        {
                            rect.value = new Rectangle( x, y, dobj.mRectangleInPixel.width, dobj.mRectangleInPixel.height );
                            return item;
                        }
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 真ん中ボタンで画面を移動させるときの、vScrollの値を計算します。
        /// 計算には、mButtonInitial, mMiddleButtonVScrollの値が使われます。
        /// </summary>
        /// <returns></returns>
01914         private int computeVScrollValueForMiddleDrag( int mouse_y )
        {
            int dy = mouse_y - mButtonInitial.y;
            int max = vScroll.getMaximum() - vScroll.getVisibleAmount();
            int min = vScroll.getMinimum();
            double new_vscroll_value = (double)mMiddleButtonVScroll - dy * max / (128.0 * (int)(100.0 * controller.getScaleY()) - (double)pictPianoRoll.getHeight());
            int value = (int)new_vscroll_value;
            if ( value < min ) {
                value = min;
            } else if ( max < value ) {
                value = max;
            }
            return value;
        }

        /// <summary>
        /// 真ん中ボタンで画面を移動させるときの、hScrollの値を計算します。
        /// 計算には、mButtonInitial, mMiddleButtonHScrollの値が使われます。
        /// </summary>
        /// <returns></returns>
01934         private int computeHScrollValueForMiddleDrag( int mouse_x )
        {
            int dx = mouse_x - mButtonInitial.x;
            int max = hScroll.getMaximum() - hScroll.getVisibleAmount();
            int min = hScroll.getMinimum();
            double new_hscroll_value = (double)mMiddleButtonHScroll - (double)dx * controller.getScaleXInv();
            int value = (int)new_hscroll_value;
            if ( value < min ) {
                value = min;
            } else if ( max < value ) {
                value = max;
            }
            return value;
        }

        /// <summary>
        /// 仮想スクリーン上でみた時の,現在のピアノロール画面の上端のy座標が指定した値とするための,vScrollの値を計算します
        /// calculateStartToDrawYの逆関数です
        /// </summary>
01953         private int calculateVScrollValueFromStartToDrawY( int start_to_draw_y )
        {
            return (int)(start_to_draw_y / controller.getScaleY());
        }

        /// <summary>
        /// 現在表示されているピアノロール画面の右上の、仮想スクリーン上座標で見たときのy座標(pixel)を取得します
        /// </summary>
01961         private int calculateStartToDrawY( int vscroll_value )
        {
            int min = vScroll.getMinimum();
            int max = vScroll.getMaximum() - vScroll.getVisibleAmount();
            int value = vscroll_value;
            if ( value < min ) {
                value = min;
            } else if ( max < value ) {
                value = max;
            }
            return (int)(value * controller.getScaleY());
        }
        #endregion

        #region public methods
        /// <summary>
        /// デフォルトのショートカットキーを格納したリストを取得します
        /// </summary>
01979         public Vector<ValuePairOfStringArrayOfKeys> getDefaultShortcutKeys()
        {
#if JAVA_MAC
            BKeys ctrl = BKeys.Menu;
#else
            BKeys ctrl = BKeys.Control;
#endif
            Vector<ValuePairOfStringArrayOfKeys> ret = new Vector<ValuePairOfStringArrayOfKeys>( Arrays.asList(
                new ValuePairOfStringArrayOfKeys[]{
                new ValuePairOfStringArrayOfKeys( menuFileNew.getName(), new BKeys[]{ ctrl, BKeys.N } ),
                new ValuePairOfStringArrayOfKeys( menuFileOpen.getName(), new BKeys[]{ ctrl, BKeys.O } ),
                new ValuePairOfStringArrayOfKeys( menuFileOpenVsq.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuFileSave.getName(), new BKeys[]{ ctrl, BKeys.S } ),
                new ValuePairOfStringArrayOfKeys( menuFileQuit.getName(), new BKeys[]{ ctrl, BKeys.Q } ),
                new ValuePairOfStringArrayOfKeys( menuFileSaveNamed.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuFileImportVsq.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuFileOpenUst.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuFileImportMidi.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuFileExportWave.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuFileExportMidi.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuEditUndo.getName(), new BKeys[]{ ctrl, BKeys.Z } ),
                new ValuePairOfStringArrayOfKeys( menuEditRedo.getName(), new BKeys[]{ ctrl, BKeys.Shift, BKeys.Z } ),
                new ValuePairOfStringArrayOfKeys( menuEditCut.getName(), new BKeys[]{ ctrl, BKeys.X } ),
                new ValuePairOfStringArrayOfKeys( menuEditCopy.getName(), new BKeys[]{ ctrl, BKeys.C } ),
                new ValuePairOfStringArrayOfKeys( menuEditPaste.getName(), new BKeys[]{ ctrl, BKeys.V } ),
                new ValuePairOfStringArrayOfKeys( menuEditSelectAll.getName(), new BKeys[]{ ctrl, BKeys.A } ),
                new ValuePairOfStringArrayOfKeys( menuEditSelectAllEvents.getName(), new BKeys[]{ ctrl, BKeys.Shift, BKeys.A } ),
                new ValuePairOfStringArrayOfKeys( menuEditDelete.getName(), new BKeys[]{ BKeys.Back } ),
                new ValuePairOfStringArrayOfKeys( menuVisualMixer.getName(), new BKeys[]{ BKeys.F3 } ),
                new ValuePairOfStringArrayOfKeys( menuVisualWaveform.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuVisualProperty.getName(), new BKeys[]{ BKeys.F6 } ),
                new ValuePairOfStringArrayOfKeys( menuVisualGridline.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuVisualStartMarker.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuVisualEndMarker.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuVisualLyrics.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuVisualNoteProperty.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuVisualPitchLine.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuVisualIconPalette.getName(), new BKeys[]{ BKeys.F4 } ),
                new ValuePairOfStringArrayOfKeys( menuJobNormalize.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuJobInsertBar.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuJobDeleteBar.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuJobRandomize.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuJobConnect.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuJobLyric.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuTrackOn.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuTrackAdd.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuTrackCopy.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuTrackChangeName.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuTrackDelete.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuTrackRenderCurrent.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuTrackRenderAll.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuTrackOverlay.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuTrackRendererVOCALOID1.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuTrackRendererVOCALOID2.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuTrackRendererUtau.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuLyricExpressionProperty.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuLyricVibratoProperty.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuLyricDictionary.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuScriptUpdate.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuSettingPreference.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuSettingGameControlerSetting.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuSettingGameControlerLoad.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuSettingPaletteTool.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuSettingShortcut.getName(), new BKeys[]{} ),
                //new ValuePairOfStringArrayOfKeys( menuSettingSingerProperty.getName(), new BKeys[]{} ),
#if JAVA
                new ValuePairOfStringArrayOfKeys( menuWindowMinimize.getName(), new BKeys[]{ ctrl, BKeys.M } ),
#endif
                new ValuePairOfStringArrayOfKeys( menuHelpAbout.getName(), new BKeys[]{} ),
                new ValuePairOfStringArrayOfKeys( menuHiddenEditLyric.getName(), new BKeys[]{ BKeys.F2 } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenEditFlipToolPointerPencil.getName(), new BKeys[]{ ctrl, BKeys.W } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenEditFlipToolPointerEraser.getName(), new BKeys[]{ ctrl, BKeys.E } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenVisualForwardParameter.getName(), new BKeys[]{ ctrl, BKeys.Alt, BKeys.PageDown } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenVisualBackwardParameter.getName(), new BKeys[]{ ctrl, BKeys.Alt, BKeys.PageUp } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenTrackNext.getName(), new BKeys[]{ ctrl, BKeys.PageDown } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenTrackBack.getName(), new BKeys[]{ ctrl, BKeys.PageUp } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenSelectBackward.getName(), new BKeys[]{ BKeys.Alt, BKeys.Left } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenSelectForward.getName(), new BKeys[]{ BKeys.Alt, BKeys.Right } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenMoveUp.getName(), new BKeys[]{ BKeys.Shift, BKeys.Up } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenMoveDown.getName(), new BKeys[]{ BKeys.Shift, BKeys.Down } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenMoveLeft.getName(), new BKeys[]{ BKeys.Shift, BKeys.Left } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenMoveRight.getName(), new BKeys[]{ BKeys.Shift, BKeys.Right } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenLengthen.getName(), new BKeys[]{ ctrl, BKeys.Right } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenShorten.getName(), new BKeys[]{ ctrl, BKeys.Left } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenGoToEndMarker.getName(), new BKeys[]{ ctrl, BKeys.End } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenGoToStartMarker.getName(), new BKeys[]{ ctrl, BKeys.Home } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenPlayFromStartMarker.getName(), new BKeys[]{ ctrl, BKeys.Enter } ),
                new ValuePairOfStringArrayOfKeys( menuHiddenFlipCurveOnPianorollMode.getName(), new BKeys[]{ BKeys.Tab } ),
            } ) );
            return ret;
        }

        /// <summary>
        /// マウスの真ん中ボタンが押されたかどうかを調べます。
        /// スペースキー+左ボタンで真ん中ボタンとみなすかどうか、というオプションも考慮される。
        /// </summary>
        /// <param name="button"></param>
        /// <returns></returns>
02077         public boolean isMouseMiddleButtonDowned( BMouseButtons button )
        {
            boolean ret = false;
            if ( AppManager.editorConfig.UseSpaceKeyAsMiddleButtonModifier ) {
                if ( mSpacekeyDowned && button == BMouseButtons.Left ) {
                    ret = true;
                }
            } else {
                if ( button == BMouseButtons.Middle ) {
                    ret = true;
                }
            }
            return ret;
        }

        /// <summary>
#if USE_BGWORK_SCREEN
        /// 画面をメインスレッドとは別のワーカースレッドを用いて再描画します。
#else
        /// 画面を再描画します。
#endif
        /// 再描画間隔が設定値より短い場合再描画がスキップされます。
        /// </summary>
02100         public void refreshScreen( boolean force )
        {
#if JAVA
            //refreshScreenCore( this, null );
            this.repaint();
            //trackSelector.repaint();
#else
#if USE_BGWORK_SCREEN
            if ( !bgWorkScreen.IsBusy ) {
                double now = PortUtil.getCurrentTime();
                double dt = now - mLastScreenRefreshedSec;
                double mindt = 1.0 / AppManager.editorConfig.MaximumFrameRate;
                if ( dt > mindt ) {
                    mLastScreenRefreshedSec = now;
                    bgWorkScreen.RunWorkerAsync();
                }
            }
#else
            if ( mIsRefreshing ) {
                return;
            } else {
                double now = PortUtil.getCurrentTime();
                double dt = now - mLastScreenRefreshedSec;
                double mindt = 1.0 / AppManager.editorConfig.MaximumFrameRate;
                if ( force || (!force && dt > mindt) ) {
                    mIsRefreshing = true;

                    mLastScreenRefreshedSec = now;
                    refreshScreenCore( this, null );

                    mIsRefreshing = false;
                }
            }
#endif
#endif
        }

        public void refreshScreen()
        {
            refreshScreen( false );
        }

        public void refreshScreenCore( Object sender, EventArgs e )
        {
#if MONITOR_FPS
            double t0 = PortUtil.getCurrentTime();
#endif
            pictPianoRoll.repaint();
            picturePositionIndicator.repaint();
            trackSelector.repaint();
            pictureBox2.repaint();
            if ( menuVisualWaveform.isSelected() ) {
                waveView.repaint();
            }
            if ( AppManager.editorConfig.OverviewEnabled ) {
                panelOverview.repaint();
            }
#if MONITOR_FPS
            double t = PortUtil.getCurrentTime();
            mFpsDrawTime[mFpsDrawTimeIndex] = t;
            mFpsDrawTime2[mFpsDrawTimeIndex] = t - t0;

            mFpsDrawTimeIndex++;
            if ( mFpsDrawTimeIndex >= mFpsDrawTime.Length ) {
                mFpsDrawTimeIndex = 0;
            }
            mFps = (float)(mFpsDrawTime.Length / (t - mFpsDrawTime[mFpsDrawTimeIndex]));

            int cnt = 0;
            double sum = 0.0;
            for ( int i = 0; i < mFpsDrawTime2.Length; i++ ) {
                double v = mFpsDrawTime2[i];
                if ( v > 0.0f ) {
                    cnt++;
                }
                sum += v;
            }
            mFps2 = (float)(cnt / sum);
#endif
        }

        /// <summary>
        /// 現在のゲームコントローラのモードに応じてstripLblGameCtrlModeの表示状態を更新します。
        /// </summary>
02184         public void updateGameControlerStatus( Object sender, EventArgs e )
        {
#if !JAVA
            if ( mGameMode == GameControlMode.DISABLED ) {
                stripLblGameCtrlMode.setText( _( "Disabled" ) );
                stripLblGameCtrlMode.setIcon( new ImageIcon( Resources.get_slash() ) );
            } else if ( mGameMode == GameControlMode.CURSOR ) {
                stripLblGameCtrlMode.setText( _( "Cursor" ) );
                stripLblGameCtrlMode.setIcon( null );
            } else if ( mGameMode == GameControlMode.KEYBOARD ) {
                stripLblGameCtrlMode.setText( _( "Keyboard" ) );
                stripLblGameCtrlMode.setIcon( new ImageIcon( Resources.get_piano() ) );
            } else if ( mGameMode == GameControlMode.NORMAL ) {
                stripLblGameCtrlMode.setText( _( "Normal" ) );
                stripLblGameCtrlMode.setIcon( null );
            }
#endif
        }

        public int calculateStartToDrawX()
        {
            return (int)(hScroll.getValue() * controller.getScaleX());
        }

        /// <summary>
        /// 現在選択されている音符よりも1個前方の音符を選択しなおします。
        /// </summary>
02211         public void selectBackward()
        {
            int count = AppManager.itemSelection.getEventCount();
            if ( count <= 0 ) {
                return;
            }
            VsqFileEx vsq = AppManager.getVsqFile();
            if ( vsq == null ) {
                return;
            }
            int selected = AppManager.getSelected();
            VsqTrack vsq_track = vsq.Track.get( selected );

            // 選択されている音符のうち、最も前方にあるものがどれかを調べる
            int min_clock = int.MaxValue;
            int internal_id = -1;
            VsqIDType type = VsqIDType.Unknown;
            for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                SelectedEventEntry item = itr.next();
                if ( item.editing.Clock <= min_clock ) {
                    min_clock = item.editing.Clock;
                    internal_id = item.original.InternalID;
                    type = item.original.ID.type;
                }
            }
            if ( internal_id == -1 || type == VsqIDType.Unknown ) {
                return;
            }

            // 1個前のアイテムのIDを検索
            int last_id = -1;
            int clock = AppManager.getCurrentClock();
            for ( Iterator<VsqEvent> itr = vsq_track.getEventIterator(); itr.hasNext(); ) {
                VsqEvent item = itr.next();
                if ( item.ID.type != type ) {
                    continue;
                }
                if ( item.InternalID == internal_id ) {
                    break;
                }
                last_id = item.InternalID;
                clock = item.Clock;
            }
            if ( last_id == -1 ) {
                return;
            }

            // 選択しなおす
            AppManager.itemSelection.clearEvent();
            AppManager.itemSelection.addEvent( last_id );
            ensureVisible( clock );
        }

        /// <summary>
        /// 現在選択されている音符よりも1個後方の音符を選択しなおします。
        /// </summary>
02267         public void selectForward()
        {
            int count = AppManager.itemSelection.getEventCount();
            if ( count <= 0 ) {
                return;
            }
            VsqFileEx vsq = AppManager.getVsqFile();
            if ( vsq == null ) {
                return;
            }
            int selected = AppManager.getSelected();
            VsqTrack vsq_track = vsq.Track.get( selected );

            // 選択されている音符のうち、最も後方にあるものがどれかを調べる
            int max_clock = int.MinValue;
            int internal_id = -1;
            VsqIDType type = VsqIDType.Unknown;
            for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                SelectedEventEntry item = itr.next();
                if ( max_clock <= item.editing.Clock ) {
                    max_clock = item.editing.Clock;
                    internal_id = item.original.InternalID;
                    type = item.original.ID.type;
                }
            }
            if ( internal_id == -1 || type == VsqIDType.Unknown ) {
                return;
            }

            // 1個後ろのアイテムのIDを検索
            int last_id = -1;
            int clock = AppManager.getCurrentClock();
            boolean break_next = false;
            for ( Iterator<VsqEvent> itr = vsq_track.getEventIterator(); itr.hasNext(); ) {
                VsqEvent item = itr.next();
                if ( item.ID.type != type ) {
                    continue;
                }
                if ( item.InternalID == internal_id ) {
                    break_next = true;
                    last_id = item.InternalID;
                    clock = item.Clock;
                    continue;
                }
                last_id = item.InternalID;
                clock = item.Clock;
                if ( break_next ) {
                    break;
                }
            }
            if ( last_id == -1 ) {
                return;
            }

            // 選択しなおす
            AppManager.itemSelection.clearEvent();
            AppManager.itemSelection.addEvent( last_id );
            ensureVisible( clock );
        }

        public void invalidatePictOverview( Object sender, EventArgs e )
        {
            panelOverview.invalidate();
        }

        public void updateBgmMenuState()
        {
            menuTrackBgm.removeAll();
            int count = AppManager.getBgmCount();
            if ( count > 0 ) {
                for ( int i = 0; i < count; i++ ) {
                    BgmFile item = AppManager.getBgm( i );
                    BMenu menu = new BMenu();
                    menu.setText( PortUtil.getFileName( item.file ) );
                    menu.setToolTipText( item.file );

                    BgmMenuItem menu_remove = new BgmMenuItem( i );
                    menu_remove.setText( _( "Remove" ) );
                    menu_remove.setToolTipText( item.file );
                    menu_remove.Click += new BEventHandler( handleBgmRemove_Click );
                    menu.add( menu_remove );

                    BgmMenuItem menu_start_after_premeasure = new BgmMenuItem( i );
                    menu_start_after_premeasure.setText( _( "Start After Premeasure" ) );
                    menu_start_after_premeasure.setName( "menu_start_after_premeasure" + i );
                    menu_start_after_premeasure.setCheckOnClick( true );
                    menu_start_after_premeasure.setSelected( item.startAfterPremeasure );
                    menu_start_after_premeasure.CheckedChanged += new BEventHandler( handleBgmStartAfterPremeasure_CheckedChanged );
                    menu.add( menu_start_after_premeasure );

                    BgmMenuItem menu_offset_second = new BgmMenuItem( i );
                    menu_offset_second.setText( _( "Set Offset Seconds" ) );
                    menu_offset_second.setToolTipText( item.readOffsetSeconds + " " + _( "seconds" ) );
                    menu_offset_second.Click += new BEventHandler( handleBgmOffsetSeconds_Click );
                    menu.add( menu_offset_second );

                    menuTrackBgm.add( menu );
                }
                menuTrackBgm.addSeparator();
            }
            BMenuItem menu_add = new BMenuItem();
            menu_add.setText( _( "Add" ) );
            menu_add.Click += new BEventHandler( handleBgmAdd_Click );
            menuTrackBgm.add( menu_add );
        }


#if ENABLE_PROPERTY
        public void updatePropertyPanelState( PanelState state )
        {
#if DEBUG
            sout.println( "FormMain#updatePropertyPanelState; state=" + state );
#endif
            if ( state == PanelState.Docked ) {
                mPropertyPanelContainer.addComponent( AppManager.propertyPanel );
                menuVisualProperty.setSelected( true );
                AppManager.editorConfig.PropertyWindowStatus.State = PanelState.Docked;
                splitContainerProperty.setPanel1Hidden( false );
                splitContainerProperty.setSplitterFixed( false );
                splitContainerProperty.setDividerSize( _SPL_SPLITTER_WIDTH );
#if JAVA
                serr.println( "fixme: FormMain#updatePropertyPanelState; Panel1MinSize not set" );
#else
                splitContainerProperty.Panel1MinSize = _PROPERTY_DOCK_MIN_WIDTH;
#endif
                int w = AppManager.editorConfig.PropertyWindowStatus.DockWidth;
                if( w < _PROPERTY_DOCK_MIN_WIDTH ){
                    w = _PROPERTY_DOCK_MIN_WIDTH;
                }
                splitContainerProperty.setDividerLocation( w );
#if DEBUG
                sout.println( "FormMain#updatePropertyPanelState; state=Docked; w=" + w );
#endif
                AppManager.editorConfig.PropertyWindowStatus.WindowState = BFormWindowState.Minimized;
#if JAVA
                int before = AppManager.propertyWindow.formClosingEvent.size();
                int after = before - 1;
                while( before != after ){
                    before = AppManager.propertyWindow.formClosingEvent.size();
                    AppManager.propertyWindow.formClosingEvent.remove( new BFormClosingEventHandler( this, "propertyWindow_FormClosing" ) );
                    after = AppManager.propertyWindow.formClosingEvent.size();
                }
                AppManager.propertyWindow.close();
                AppManager.propertyWindow.formClosingEvent.add( new BFormClosingEventHandler( this, "propertyWindow_FormClosing" ) );
#else
                AppManager.propertyWindow.setVisible( false );
#endif
            } else if ( state == PanelState.Hidden ) {
                AppManager.propertyWindow.setVisible( false );
                menuVisualProperty.setSelected( false );
                if ( AppManager.editorConfig.PropertyWindowStatus.State == PanelState.Docked ) {
                    AppManager.editorConfig.PropertyWindowStatus.DockWidth = splitContainerProperty.getDividerLocation();
                }
                AppManager.editorConfig.PropertyWindowStatus.State = PanelState.Hidden;
#if JAVA
                serr.println( "fixme: FormMain#updatePropertyPanelState; Panel1MinSize not set" );
#else
                splitContainerProperty.Panel1MinSize = 0;
#endif
                splitContainerProperty.setPanel1Hidden( true );
                splitContainerProperty.setDividerLocation( 0 );
                splitContainerProperty.setDividerSize( 0 );
                splitContainerProperty.setSplitterFixed( true );
            } else if ( state == PanelState.Window ) {
#if JAVA
                AppManager.propertyWindow.addComponent( AppManager.propertyPanel );
#else
                AppManager.propertyWindow.Controls.Add( AppManager.propertyPanel );
#endif
                Point parent = this.getLocation();
                XmlRectangle rc = AppManager.editorConfig.PropertyWindowStatus.Bounds;
                Point property = new Point( rc.x, rc.y );
                AppManager.propertyWindow.setBounds( new Rectangle( parent.x + property.x, parent.y + property.y, rc.width, rc.height ) );
                normalizeFormLocation( AppManager.propertyWindow );
                // setVisible -> NORMALとすると,javaの場合見栄えが悪くなる
#if !JAVA
                AppManager.propertyWindow.setVisible( true );
#endif
                if ( AppManager.propertyWindow.getExtendedState() != BForm.NORMAL ) {
                    AppManager.propertyWindow.setExtendedState( BForm.NORMAL );
                }
#if JAVA
                AppManager.propertyWindow.setVisible( true );
#endif
                menuVisualProperty.setSelected( true );
                if ( AppManager.editorConfig.PropertyWindowStatus.State == PanelState.Docked ) {
                    AppManager.editorConfig.PropertyWindowStatus.DockWidth = splitContainerProperty.getDividerLocation();
                }
                AppManager.editorConfig.PropertyWindowStatus.State = PanelState.Window;
#if JAVA
                serr.println( "fixme: FormMain#updatePropertyPanelState; splitContainerProperty.Panel1MinSize not set" );
#else
                splitContainerProperty.Panel1MinSize = 0;
#endif
                splitContainerProperty.setPanel1Hidden( true );
                splitContainerProperty.setDividerLocation( 0 );
                splitContainerProperty.setDividerSize( 0 );
                splitContainerProperty.setSplitterFixed( true );
                AppManager.editorConfig.PropertyWindowStatus.WindowState = BFormWindowState.Normal;
#if DEBUG
                sout.println( "FormMain#updatePropertyPanelState; propertyWindow.getExtendedState()=" + AppManager.propertyWindow.getExtendedState() );
                sout.println( "    NORMAL=" + BForm.NORMAL );
                sout.println( "    ICONIFIED=" + BForm.ICONIFIED );
                sout.println( "    MAXIMIZED_BOTH=" + BForm.MAXIMIZED_BOTH );
#endif
            }
        }
#endif


        /// <summary>
        /// メインメニュー項目の中から,Nameプロパティがnameであるものを検索します.見つからなければnullを返す.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
02483         public Object searchMenuItemFromName( String name, ByRef<Object> parent )
        {
            int count = menuStripMain.getMenuCount();
            for ( int i = 0; i < count; i++ ) {
                Object tsi = menuStripMain.getMenu( i );
                Object ret = searchMenuItemRecurse( name, tsi, parent );
                if ( ret != null ) {
                    if ( parent.value == null ) {
                        parent.value = tsi;
                    }
                    return ret;
                }
            }
            return null;
        }

        /// <summary>
        /// 指定されたメニューアイテムから,Nameプロパティがnameであるものを再帰的に検索します.見つからなければnullを返す
        /// </summary>
        /// <param name="name"></param>
        /// <param name="tree"></param>
        /// <returns></returns>
02505         public Object searchMenuItemRecurse( String name, Object tree, ByRef<Object> parent )
        {
#if JAVA
            if( tree == null ){
                return null;
            }
            // 子メニューを持つ場合
            if( tree instanceof JMenu ){
                JMenu jm = (JMenu)tree;
                int size = jm.getMenuComponentCount();
                for( int i = 0; i < size; i++ ){
                    Component comp = jm.getMenuComponent( i );
                    if( comp != null && comp instanceof JMenuItem ){
                        JMenuItem jmi = (JMenuItem)comp;
                        Object obj = searchMenuItemRecurse( name, jmi, parent );
                        if ( obj != null ){
                            parent.value = tree;
                            return obj;
                        }
                    }
                }
            }
            // 自分自身が該当しないか?
            if( tree instanceof JMenuItem ){
                JMenuItem jmi = (JMenuItem)tree;
                if( str.compare( name, jmi.getName() ) ){
                    parent.value = null;
                    return tree;
                }
            }
            // 該当しなかった
            return null;
#else
            String tree_name = "";
            System.Windows.Forms.ToolStripMenuItem menu = null;
            if ( tree is System.Windows.Forms.ToolStripItem ) {
                if ( tree is System.Windows.Forms.ToolStripMenuItem ) {
                    menu = (System.Windows.Forms.ToolStripMenuItem)tree;
                }
                tree_name = ((System.Windows.Forms.ToolStripItem)tree).Name;
            } else {
                return null;
            }

            if ( str.compare( tree_name, name ) ) {
                parent.value = null;
                return tree;
            } else {
                if ( menu == null ) {
                    return null;
                }
                int count = menu.DropDownItems.Count;
                for ( int i = 0; i < count; i++ ) {
                    System.Windows.Forms.ToolStripItem tsi = menu.DropDownItems[i];
                    String tsi_name = "";
                    if ( tsi is System.Windows.Forms.ToolStripItem ) {
                        tsi_name = ((System.Windows.Forms.ToolStripItem)tsi).Name;
                    } else {
                        continue;
                    }

                    if ( str.compare( tsi_name, name ) ) {
                        return tsi;
                    }
                    Object ret = searchMenuItemRecurse( name, tsi, parent );
                    if ( ret != null ) {
                        parent.value = tsi;
                        return ret;
                    }
                }
                return null;
            }
#endif
        }

        /// <summary>
        /// フォームをマウス位置に出す場合に推奨されるフォーム位置を計算します
        /// </summary>
        /// <param name="dlg"></param>
        /// <returns></returns>
02585         public Point getFormPreferedLocation( int dialogWidth, int dialogHeight )
        {
            Point mouse = PortUtil.getMousePosition();
            Rectangle rcScreen = PortUtil.getWorkingArea( this );
            int top = mouse.y - dialogHeight / 2;
            if ( top + dialogHeight > rcScreen.y + rcScreen.height )
            {
                // ダイアログの下端が隠れる場合、位置をずらす
                top = rcScreen.y + rcScreen.height - dialogHeight;
            }
            if ( top < rcScreen.y )
            {
                // ダイアログの上端が隠れる場合、位置をずらす
                top = rcScreen.y;
            }
            int left = mouse.x - dialogWidth / 2;
            if ( left + dialogWidth > rcScreen.x + rcScreen.width )
            {
                // ダイアログの右端が隠れる場合,位置をずらす
                left = rcScreen.x + rcScreen.width - dialogWidth;
            }
            if ( left < rcScreen.x )
            {
                // ダイアログの左端が隠れる場合,位置をずらす
                left = rcScreen.x;
            }
            return new Point( left, top );
        }

        /// <summary>
        /// フォームをマウス位置に出す場合に推奨されるフォーム位置を計算します
        /// </summary>
        /// <param name="dlg"></param>
        /// <returns></returns>
02619         public Point getFormPreferedLocation( BDialog dlg )
        {
            return getFormPreferedLocation( dlg.getWidth(), dlg.getHeight() );
        }

        public void updateLayout()
        {
#if JAVA
            int keywidth = AppManager.keyWidth;
            pictureBox3.setPreferredSize( new Dimension( keywidth, 4 ) );
            pictureBox3.setSize( new Dimension( keywidth, pictureBox3.getHeight() ) );
            panelWaveformZoom.setPreferredSize( new Dimension( keywidth, 4 ) );
            panelWaveformZoom.setSize( new Dimension( keywidth, panelWaveformZoom.getHeight() ) );
            
            Dimension overview_pref_size = panelOverview.getPreferredSize();
            if( AppManager.editorConfig.OverviewEnabled ){
                panel3.setPreferredSize( new Dimension( (int)overview_pref_size.getWidth(), _OVERVIEW_HEIGHT ) );
                //panel3.setHeight( _OVERVIEW_HEIGHT );
            }else{
                panel3.setPreferredSize( new Dimension( (int)overview_pref_size.getWidth(), 0 ) );
                //panel3.setHeight( 0 );
            }
            jPanel1.doLayout();
            panel1.doLayout();
            panel21.doLayout();
            int overview_width = this.getWidth();
            panelOverview.updateCachedImage( overview_width );
            refreshScreenCore( null, null );
#else
            int width = panel1.Width;
            int height = panel1.Height;

            if ( AppManager.editorConfig.OverviewEnabled ) {
                panelOverview.Height = _OVERVIEW_HEIGHT;
            } else {
                panelOverview.Height = 0;
            }
            panelOverview.Width = width;
            int key_width = AppManager.keyWidth;

            /*btnMooz.setBounds( 3, 12, 23, 23 );
            btnZoom.setBounds( 26, 12, 23, 23 );*/

            picturePositionIndicator.Width = width;
            picturePositionIndicator.Height = _PICT_POSITION_INDICATOR_HEIGHT;

            hScroll.Top = 0;
            hScroll.Left = key_width;
            hScroll.Width = width - key_width - _SCROLL_WIDTH - trackBar.Width;
            hScroll.Height = _SCROLL_WIDTH;

            vScroll.Width = _SCROLL_WIDTH;
            vScroll.Height = height - _PICT_POSITION_INDICATOR_HEIGHT - _SCROLL_WIDTH * 4 - panelOverview.Height;

            pictPianoRoll.Width = width - _SCROLL_WIDTH;
            pictPianoRoll.Height = height - _PICT_POSITION_INDICATOR_HEIGHT - _SCROLL_WIDTH - panelOverview.Height;

            pictureBox3.Width = key_width - _SCROLL_WIDTH;
            pictKeyLengthSplitter.Width = _SCROLL_WIDTH;
            pictureBox3.Height = _SCROLL_WIDTH;
            pictureBox2.Height = _SCROLL_WIDTH * 4;
            trackBar.Height = _SCROLL_WIDTH;

            panelOverview.Top = 0;
            panelOverview.Left = 0;

            picturePositionIndicator.Top = panelOverview.Height;
            picturePositionIndicator.Left = 0;

            pictPianoRoll.Top = _PICT_POSITION_INDICATOR_HEIGHT + panelOverview.Height;
            pictPianoRoll.Left = 0;

            vScroll.Top = _PICT_POSITION_INDICATOR_HEIGHT + panelOverview.Height;
            vScroll.Left = width - _SCROLL_WIDTH;

            pictureBox3.Top = height - _SCROLL_WIDTH;
            pictureBox3.Left = 0;
            pictKeyLengthSplitter.Top = height - _SCROLL_WIDTH;
            pictKeyLengthSplitter.Left = pictureBox3.Width;

            hScroll.Top = height - _SCROLL_WIDTH;
            hScroll.Left = pictureBox3.Width + pictKeyLengthSplitter.Width;

            trackBar.Top = height - _SCROLL_WIDTH;
            trackBar.Left = width - _SCROLL_WIDTH - trackBar.Width;

            pictureBox2.Top = height - _SCROLL_WIDTH * 4;
            pictureBox2.Left = width - _SCROLL_WIDTH;

            waveView.Top = 0;
            waveView.Left = key_width;
            waveView.Width = width - key_width;
#endif
        }

        public void updateRendererMenu()
        {
            String wine_prefix = AppManager.editorConfig.WinePrefix;
            String wine_top = AppManager.editorConfig.WineTop;
            if ( !VSTiDllManager.isRendererAvailable( RendererKind.VOCALOID1, wine_prefix, wine_top ) ) {
                cMenuTrackTabRendererVOCALOID1.setIcon( new ImageIcon( Resources.get_slash() ) );
                menuTrackRendererVOCALOID1.setIcon( new ImageIcon( Resources.get_slash() ) );
            } else {
                cMenuTrackTabRendererVOCALOID1.setIcon( null );
                menuTrackRendererVOCALOID1.setIcon( null );
            }

            if ( !VSTiDllManager.isRendererAvailable( RendererKind.VOCALOID2, wine_prefix, wine_top ) ) {
                cMenuTrackTabRendererVOCALOID2.setIcon( new ImageIcon( Resources.get_slash() ) );
                menuTrackRendererVOCALOID2.setIcon( new ImageIcon( Resources.get_slash() ) );
            } else {
                cMenuTrackTabRendererVOCALOID2.setIcon( null );
                menuTrackRendererVOCALOID2.setIcon( null );
            }

            if ( !VSTiDllManager.isRendererAvailable( RendererKind.UTAU, wine_prefix, wine_top ) ) {
                cMenuTrackTabRendererUtau.setIcon( new ImageIcon( Resources.get_slash() ) );
                menuTrackRendererUtau.setIcon( new ImageIcon( Resources.get_slash() ) );
            } else {
                cMenuTrackTabRendererUtau.setIcon( null );
                menuTrackRendererUtau.setIcon( null );
            }

            if ( !VSTiDllManager.isRendererAvailable( RendererKind.VCNT, wine_prefix, wine_top ) ) {
                cMenuTrackTabRendererStraight.setIcon( new ImageIcon( Resources.get_slash() ) );
                menuTrackRendererVCNT.setIcon( new ImageIcon( Resources.get_slash() ) );
            } else {
                cMenuTrackTabRendererStraight.setIcon( null );
                menuTrackRendererVCNT.setIcon( null );
            }

            if ( !VSTiDllManager.isRendererAvailable( RendererKind.AQUES_TONE, wine_prefix, wine_top ) ) {
                cMenuTrackTabRendererAquesTone.setIcon( new ImageIcon( Resources.get_slash() ) );
                menuTrackRendererAquesTone.setIcon( new ImageIcon( Resources.get_slash() ) );
            } else {
                cMenuTrackTabRendererAquesTone.setIcon( null );
                menuTrackRendererAquesTone.setIcon( null );
            }

            // UTAU用のサブアイテムを更新
            int count = AppManager.editorConfig.getResamplerCount();
            // サブアイテムの個数を整える
#if JAVA
            menuTrackRendererUtau.removeAll();
            cMenuTrackTabRendererUtau.removeAll();
            for( int i = 0; i < count; i++ ){
                String path = AppManager.editorConfig.getResamplerAt( i );
                String name = PortUtil.getFileNameWithoutExtension( path );

                BMenuItem item0 = new BMenuItem();
                item0.clickEvent.add( new BEventHandler( this, "handleChangeRenderer" ) );
                item0.setText( name );
                item0.setToolTipText( path );
                menuTrackRendererUtau.add( item0 );

                BMenuItem item1 = new BMenuItem();
                item1.clickEvent.add( new BEventHandler( this, "handleChangeRenderer" ) );
                item1.setText( name );
                item1.setToolTipText( path );
                cMenuTrackTabRendererUtau.add( item1 );
            }
#else
            int delta = count - menuTrackRendererUtau.DropDownItems.Count;
            if ( delta > 0 ) {
                // 増やす
                for ( int i = 0; i < delta; i++ ) {
                    cMenuTrackTabRendererUtau.DropDownItems.Add( "", null, new BEventHandler( handleChangeRenderer ) );
                    menuTrackRendererUtau.DropDownItems.Add( "", null, new BEventHandler( handleChangeRenderer ) );
                }
            } else if ( delta < 0 ) {
                // 減らす
                for ( int i = 0; i < -delta; i++ ) {
                    cMenuTrackTabRendererUtau.DropDownItems.RemoveAt( 0 );
                    menuTrackRendererUtau.DropDownItems.RemoveAt( 0 );
                }
            }

            for ( int i = 0; i < count; i++ ) {
                String path = AppManager.editorConfig.getResamplerAt( i );
                String name = PortUtil.getFileNameWithoutExtension( path );
                menuTrackRendererUtau.DropDownItems[i].Text = name;
                cMenuTrackTabRendererUtau.DropDownItems[i].Text = name;

                menuTrackRendererUtau.DropDownItems[i].ToolTipText = path;
                cMenuTrackTabRendererUtau.DropDownItems[i].ToolTipText = path;
            }
#endif
        }

        public void drawUtauVibrato( Graphics2D g, UstVibrato vibrato, int note, int clock_start, int clock_width )
        {
            //SmoothingMode old = g.SmoothingMode;
            //g.SmoothingMode = SmoothingMode.AntiAlias;
            // 魚雷を描いてみる
            int y0 = AppManager.yCoordFromNote( note - 0.5f );
            int x0 = AppManager.xCoordFromClocks( clock_start );
            int px_width = AppManager.xCoordFromClocks( clock_start + clock_width ) - x0;
            int boxheight = (int)(vibrato.Depth * 2 / 100.0 * (int)(100.0 * controller.getScaleY()));
            int px_shift = (int)(vibrato.Shift / 100.0 * vibrato.Depth / 100.0 * (int)(100.0 * controller.getScaleY()));

            // vibrato in
            int cl_vibin_end = clock_start + (int)(clock_width * vibrato.In / 100.0);
            int x_vibin_end = AppManager.xCoordFromClocks( cl_vibin_end );
            Point ul = new Point( x_vibin_end, y0 - boxheight / 2 - px_shift );
            Point dl = new Point( x_vibin_end, y0 + boxheight / 2 - px_shift );
            g.setColor( Color.black );
            g.drawPolyline( new int[] { x0, ul.x, dl.x },
                            new int[] { y0, ul.y, dl.y },
                            3 );

            // vibrato out
            int cl_vibout_start = clock_start + clock_width - (int)(clock_width * vibrato.Out / 100.0);
            int x_vibout_start = AppManager.xCoordFromClocks( cl_vibout_start );
            Point ur = new Point( x_vibout_start, y0 - boxheight / 2 - px_shift );
            Point dr = new Point( x_vibout_start, y0 + boxheight / 2 - px_shift );
            g.drawPolyline( new int[] { x0 + px_width, ur.x, dr.x },
                           new int[] { y0, ur.y, dr.y },
                           3 );

            // box
            int boxwidth = x_vibout_start - x_vibin_end;
            if ( boxwidth > 0 ) {
                g.drawPolyline( new int[] { ul.x, dl.x, dr.x, ur.x },
                               new int[] { ul.y, dl.y, dr.y, ur.y },
                               4 );
            }

            // buf1に、vibrato in/outによる増幅率を代入
            float[] buf1 = new float[clock_width + 1];
            for ( int clock = clock_start; clock <= clock_start + clock_width; clock++ ) {
                buf1[clock - clock_start] = 1.0f;
            }
            // vibin
            if ( cl_vibin_end - clock_start > 0 ) {
                for ( int clock = clock_start; clock <= cl_vibin_end; clock++ ) {
                    int i = clock - clock_start;
                    buf1[i] *= i / (float)(cl_vibin_end - clock_start);
                }
            }
            if ( clock_start + clock_width - cl_vibout_start > 0 ) {
                for ( int clock = clock_start + clock_width; clock >= cl_vibout_start; clock-- ) {
                    int i = clock - clock_start;
                    float v = (clock_start + clock_width - clock) / (float)(clock_start + clock_width - cl_vibout_start);
                    buf1[i] = buf1[i] * v;
                }
            }

            // buf2に、shiftによるy座標のシフト量を代入
            float[] buf2 = new float[clock_width + 1];
            for ( int i = 0; i < clock_width; i++ ) {
                buf2[i] = px_shift * buf1[i];
            }
            try {
                double phase = 2.0 * Math.PI * vibrato.Phase / 100.0;
                double omega = 2.0 * Math.PI / vibrato.Period;   //角速度(rad/msec)
                double msec = AppManager.getVsqFile().getSecFromClock( clock_start - 1 ) * 1000.0;
                float px_track_height = (int)(controller.getScaleY() * 100.0f);
                phase -= (AppManager.getVsqFile().getSecFromClock( clock_start ) * 1000.0 - msec) * omega;
                for ( int clock = clock_start; clock <= clock_start + clock_width; clock++ ) {
                    int i = clock - clock_start;
                    double t_msec = AppManager.getVsqFile().getSecFromClock( clock ) * 1000.0;
                    phase += (t_msec - msec) * omega;
                    msec = t_msec;
                    buf2[i] += (float)(vibrato.Depth * 0.01f * px_track_height * buf1[i] * Math.Sin( phase ));
                }
                int[] listx = new int[clock_width + 1];
                int[] listy = new int[clock_width + 1];
                for ( int clock = clock_start; clock <= clock_start + clock_width; clock++ ) {
                    int i = clock - clock_start;
                    listx[i] = AppManager.xCoordFromClocks( clock );
                    listy[i] = (int)(y0 + buf2[i]);
                }
                if ( listx.Length >= 2 ) {
                    g.setColor( Color.red );
                    g.drawPolyline( listx, listy, listx.Length );
                }
                //g.SmoothingMode = old;
            } catch ( Exception oex ) {
                Logger.write( typeof( FormMain ) + ".drawUtauVibato; ex=" + oex + "\n" );
#if DEBUG
                AppManager.debugWriteLine( "DrawUtauVibrato; oex=" + oex );
#endif
            }
        }

#if ENABLE_SCRIPT
        /// <summary>
        /// Palette Toolの表示を更新します
        /// </summary>
        public void updatePaletteTool()
        {
            int count = 0;
            int num_has_dialog = 0;
            for ( Iterator<System.Windows.Forms.ToolBarButton> itr = mPaletteTools.iterator(); itr.hasNext(); ) {
                System.Windows.Forms.ToolBarButton item = itr.next();
                toolBarTool.Buttons.Add( item );
            }
            String lang = Messaging.getLanguage();
            boolean first = true;
            for ( Iterator<String> itr = PaletteToolServer.loadedTools.keySet().iterator(); itr.hasNext(); ) {
                String id = itr.next();
                count++;
                IPaletteTool ipt = (IPaletteTool)PaletteToolServer.loadedTools.get( id );
#if !JAVA
                System.Drawing.Bitmap icon = ipt.getIcon();
#endif
                String name = ipt.getName( lang );
                String desc = ipt.getDescription( lang );

                // toolStripPaletteTools
                System.Windows.Forms.ToolBarButton tsb = new System.Windows.Forms.ToolBarButton();
                tsb.Style = System.Windows.Forms.ToolBarButtonStyle.ToggleButton;
#if !JAVA
                if ( icon != null ) {
                    imageListTool.Images.Add( icon );
                    tsb.ImageIndex = imageListTool.Images.Count - 1;
                }
#endif
                tsb.Text = name;
                tsb.ToolTipText = desc;
                tsb.Tag = id;
#if JAVA
                tsb.clickEvent.add( new BEventHandler( this, "handleStripPaletteTool_Click" ) );
#endif
                if ( first ) {
                    var sep = new System.Windows.Forms.ToolBarButton();
                    sep.Style = System.Windows.Forms.ToolBarButtonStyle.Separator;
                    toolBarTool.Buttons.Add( sep );
                    first = false;
                }
                mPaletteTools.add( tsb );
                toolBarTool.Buttons.Add( tsb );

                // cMenuTrackSelector
                PaletteToolMenuItem tsmi = new PaletteToolMenuItem( id );
                tsmi.setText( name );
                tsmi.setToolTipText( desc );
                tsmi.Click += new BEventHandler( handleStripPaletteTool_Click );
                cMenuTrackSelectorPaletteTool.add( tsmi );

                // cMenuPiano
                PaletteToolMenuItem tsmi2 = new PaletteToolMenuItem( id );
                tsmi2.setText( name );
                tsmi2.setToolTipText( desc );
                tsmi2.Click += new BEventHandler( handleStripPaletteTool_Click );
                cMenuPianoPaletteTool.add( tsmi2 );

                // menuSettingPaletteTool
                if ( ipt.hasDialog() ) {
                    PaletteToolMenuItem tsmi3 = new PaletteToolMenuItem( id );
                    tsmi3.setText( name );
                    tsmi3.Click += new BEventHandler( handleSettingPaletteTool );
                    menuSettingPaletteTool.add( tsmi3 );
                    num_has_dialog++;
                }
            }
            if ( count == 0 ) {
                cMenuTrackSelectorPaletteTool.setVisible( false );
                cMenuPianoPaletteTool.setVisible( false );
            }
            if ( num_has_dialog == 0 ) {
                menuSettingPaletteTool.setVisible( false );
            }
        }
#endif

        public void updateCopyAndPasteButtonStatus()
        {
            // copy cut deleteの表示状態更新
            boolean selected_is_null = (AppManager.itemSelection.getEventCount() == 0) &&
                                       (AppManager.itemSelection.getTempoCount() == 0) &&
                                       (AppManager.itemSelection.getTimesigCount() == 0) &&
                                       (AppManager.itemSelection.getPointIDCount() == 0);

            int selected_point_id_count = AppManager.itemSelection.getPointIDCount();
            cMenuTrackSelectorCopy.setEnabled( selected_point_id_count > 0 );
            cMenuTrackSelectorCut.setEnabled( selected_point_id_count > 0 );
            cMenuTrackSelectorDeleteBezier.setEnabled( (AppManager.isCurveMode() && AppManager.itemSelection.getLastBezier() != null) );
            if ( selected_point_id_count > 0 ) {
                cMenuTrackSelectorDelete.setEnabled( true );
            } else {
                SelectedEventEntry last = AppManager.itemSelection.getLastEvent();
                if ( last == null ) {
                    cMenuTrackSelectorDelete.setEnabled( false );
                } else {
                    cMenuTrackSelectorDelete.setEnabled( last.original.ID.type == VsqIDType.Singer );
                }
            }

            cMenuPianoCopy.setEnabled( !selected_is_null );
            cMenuPianoCut.setEnabled( !selected_is_null );
            cMenuPianoDelete.setEnabled( !selected_is_null );

            menuEditCopy.setEnabled( !selected_is_null );
            menuEditCut.setEnabled( !selected_is_null );
            menuEditDelete.setEnabled( !selected_is_null );

            ClipboardEntry ce = AppManager.clipboard.getCopiedItems();
            int copy_started_clock = ce.copyStartedClock;
            TreeMap<CurveType, VsqBPList> copied_curve = ce.points;
            TreeMap<CurveType, Vector<BezierChain>> copied_bezier = ce.beziers;
            boolean copied_is_null = (ce.events.size() == 0) &&
                                  (ce.tempo.size() == 0) &&
                                  (ce.timesig.size() == 0) &&
                                  (copied_curve.size() == 0) &&
                                  (copied_bezier.size() == 0);
            boolean enabled = !copied_is_null;
            if ( copied_curve.size() == 1 ) {
                // 1種類のカーブがコピーされている場合→コピーされているカーブの種類と、現在選択されているカーブの種類とで、最大値と最小値が一致している場合のみ、ペースト可能
                CurveType ct = CurveType.Empty;
                for ( Iterator<CurveType> itr = copied_curve.keySet().iterator(); itr.hasNext(); ) {
                    CurveType c = itr.next();
                    ct = c;
                }
                CurveType selected = trackSelector.getSelectedCurve();
                if ( ct.getMaximum() == selected.getMaximum() &&
                     ct.getMinimum() == selected.getMinimum() &&
                     !selected.isScalar() && !selected.isAttachNote() ) {
                    enabled = true;
                } else {
                    enabled = false;
                }
            } else if ( copied_curve.size() >= 2 ) {
                // 複数種類のカーブがコピーされている場合→そのままペーストすればOK
                enabled = true;
            }
            cMenuTrackSelectorPaste.setEnabled( enabled );
            cMenuPianoPaste.setEnabled( enabled );
            menuEditPaste.setEnabled( enabled );

            /*int copy_started_clock;
            boolean copied_is_null = (AppManager.GetCopiedEvent().Count == 0) &&
                                  (AppManager.GetCopiedTempo( out copy_started_clock ).Count == 0) &&
                                  (AppManager.GetCopiedTimesig( out copy_started_clock ).Count == 0) &&
                                  (AppManager.GetCopiedCurve( out copy_started_clock ).Count == 0) &&
                                  (AppManager.GetCopiedBezier( out copy_started_clock ).Count == 0);
            menuEditCut.isEnabled() = !selected_is_null;
            menuEditCopy.isEnabled() = !selected_is_null;
            menuEditDelete.isEnabled() = !selected_is_null;
            //stripBtnCopy.isEnabled() = !selected_is_null;
            //stripBtnCut.isEnabled() = !selected_is_null;

            if ( AppManager.GetCopiedEvent().Count != 0 ) {
                menuEditPaste.isEnabled() = (AppManager.CurrentClock >= AppManager.VsqFile.getPreMeasureClocks());
                //stripBtnPaste.isEnabled() = (AppManager.CurrentClock >= AppManager.VsqFile.getPreMeasureClocks());
            } else {
                menuEditPaste.isEnabled() = !copied_is_null;
                //stripBtnPaste.isEnabled() = !copied_is_null;
            }*/
        }

        /// <summary>
        /// 現在の編集データを全て破棄する。DirtyCheckは行われない。
        /// </summary>
03073         public void clearExistingData()
        {
            AppManager.editHistory.clear();
            AppManager.itemSelection.clearBezier();
            AppManager.itemSelection.clearEvent();
            AppManager.itemSelection.clearTempo();
            AppManager.itemSelection.clearTimesig();
            if ( AppManager.isPlaying() ) {
                AppManager.setPlaying( false, this );
            }
            waveView.unloadAll();
        }

        /// <summary>
        /// 保存されていない編集内容があるかどうかチェックし、必要なら確認ダイアログを出す。
        /// </summary>
        /// <returns>保存されていない保存内容などない場合、または、保存する必要がある場合で(保存しなくてよいと指定された場合または保存が行われた場合)にtrueを返す</returns>
03090         public boolean dirtyCheck()
        {
            if ( mEdited ) {
                String file = AppManager.getFileName();
                if ( str.compare( file, "" ) ) {
                    file = "Untitled";
                } else {
                    file = PortUtil.getFileName( file );
                }
                BDialogResult dr = AppManager.showMessageBox( _( "Save this sequence?" ),
                                                              _( "Affirmation" ),
                                                              org.kbinani.windows.forms.Utility.MSGBOX_YES_NO_CANCEL_OPTION,
                                                              org.kbinani.windows.forms.Utility.MSGBOX_QUESTION_MESSAGE );
                if ( dr == BDialogResult.YES ) {
                    if ( str.compare( AppManager.getFileName(), "" ) ) {
                        int dr2 = AppManager.showModalDialog( saveXmlVsqDialog, false, this );
                        if ( dr2 == BFileChooser.APPROVE_OPTION ) {
                            String sf = saveXmlVsqDialog.getSelectedFile();
                            AppManager.saveTo( sf );
                            return true;
                        } else {
                            return false;
                        }
                    } else {
                        AppManager.saveTo( AppManager.getFileName() );
                        return true;
                    }
                } else if ( dr == BDialogResult.NO ) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return true;
            }
        }

#if JAVA
        /// <summary>
        /// waveView用のwaveファイルを読込むスレッドで使用する
        /// </summary>
        /// <param name="arg"></param>
        public class LoadWaveProc extends Thread {
            public String file = "";
            public int track;

            public LoadWaveProc( int track, String file ){
                this.file = file;
                this.track = track;
            }

            public void run(){
                waveView.load( track, file );
            }
        }
#endif

        public void loadWave( Object arg )
        {
            Object[] argArr = (Object[])arg;
            String file = (String)argArr[0];
            int track = (Integer)argArr[1];
            waveView.load( track, file );
        }

        /// <summary>
        /// AppManager.editorConfig.ViewWaveformの値をもとに、splitterContainer2の表示状態を更新します
        /// </summary>
03158         public void updateSplitContainer2Size( boolean save_to_config )
        {
            if ( AppManager.editorConfig.ViewWaveform ) {
                splitContainer2.setPanel2MinSize( _SPL2_PANEL2_MIN_HEIGHT );
                splitContainer2.setSplitterFixed( false );
                splitContainer2.setPanel2Hidden( false );
                splitContainer2.setDividerSize( _SPL_SPLITTER_WIDTH );
                int lastloc = AppManager.editorConfig.SplitContainer2LastDividerLocation;
                if ( lastloc <= 0 || lastloc > splitContainer2.getHeight() ) {
                    int draft = splitContainer2.getHeight() -  100;
                    if( draft <= 0 ){
                        draft = splitContainer2.getHeight() / 2;
                    }
                    splitContainer2.setDividerLocation( draft );
                } else {
                    splitContainer2.setDividerLocation( lastloc );
                }
            } else {
                if( save_to_config ){
                    AppManager.editorConfig.SplitContainer2LastDividerLocation = splitContainer2.getDividerLocation();
                }
                splitContainer2.setPanel2MinSize( 0 );
                splitContainer2.setPanel2Hidden( true );
                splitContainer2.setDividerSize( 0 );
                splitContainer2.setDividerLocation( splitContainer2.getHeight() );
                splitContainer2.setSplitterFixed( true );
            }
        }

        /// <summary>
        /// ウィンドウの表示内容に応じて、ウィンドウサイズの最小値を計算します
        /// </summary>
        /// <returns></returns>
03191         public Dimension getWindowMinimumSize()
        {
            Dimension current_minsize = new Dimension( getMinimumSize().width, getMinimumSize().height );
#if JAVA
            Dimension client = getContentPane().getSize();
            Dimension current = getSize();
            return new Dimension( current_minsize.width,
                                  splitContainer1.getPanel2MinSize() +
                                  _SCROLL_WIDTH + _PICT_POSITION_INDICATOR_HEIGHT + pictPianoRoll.getMinimumSize().height +
                                  menuStripMain.getHeight() +
                                  (current.height - client.height) +
                                  20 );
#else
            Dimension client = new Dimension( this.ClientSize.Width, this.ClientSize.Height );
            Dimension current = new Dimension( this.Size.Width, this.Size.Height );
            return new Dimension( current_minsize.width,
                                  splitContainer1.getPanel2MinSize() +
                                  _SCROLL_WIDTH + _PICT_POSITION_INDICATOR_HEIGHT + pictPianoRoll.getMinimumSize().height +
                                  rebar.Height +
                                  menuStripMain.getHeight() + statusStrip.Height +
                                  (current.height - client.height) +
                                  20 );
#endif
        }

        /// <summary>
        /// 現在のAppManager.mInputTextBoxの状態を元に、歌詞の変更を反映させるコマンドを実行します
        /// </summary>
03219         public void executeLyricChangeCommand()
        {
#if JAVA
            if ( !AppManager.mInputTextBox.isVisible() ) {
#else
            if ( !AppManager.mInputTextBox.Enabled ) {
#endif
                return;
            }
#if !JAVA
            if ( AppManager.mInputTextBox.IsDisposed ) {
                return;
            }
#endif
            SelectedEventEntry last_selected_event = AppManager.itemSelection.getLastEvent();
            boolean phonetic_symbol_edit_mode = AppManager.mInputTextBox.isPhoneticSymbolEditMode();

            int selected = AppManager.getSelected();
            VsqFileEx vsq = AppManager.getVsqFile();
            VsqTrack vsq_track = vsq.Track.get( selected );

            // 後続に、連続している音符が何個あるか検査
            int maxcount = SymbolTable.getMaxDivisions(); // 音節の分割によって,高々maxcount個までにしか分割されない
            boolean check_started = false;
            int endclock = 0;  // 直前の音符の終了クロック
            int count = 0;     // 後続音符の連続個数
            int start_index = -1;
            int indx = -1;
            for ( Iterator<Integer> itr = vsq_track.indexIterator( IndexIteratorKind.NOTE ); itr.hasNext(); ) {
                indx = itr.next();
                VsqEvent itemi = vsq_track.getEvent( indx );
                if ( itemi.InternalID == last_selected_event.original.InternalID ) {
                    check_started = true;
                    endclock = itemi.Clock + itemi.ID.getLength();
                    count = 1;
                    start_index = indx;
                    continue;
                }
                if ( check_started ) {
                    if ( count + 1 > maxcount ) {
                        break;
                    }
                    if ( itemi.Clock <= endclock ) {
                        count++;
                        endclock = itemi.Clock + itemi.ID.getLength();
                    } else {
                        break;
                    }
                }
            }

            // 後続の音符をリストアップ
            VsqEvent[] items = new VsqEvent[count];
            String[] original_symbol = new String[count];
            String[] original_phrase = new String[count];
            boolean[] symbol_protected = new boolean[count];
            indx = -1;
            for ( Iterator<Integer> itr = vsq_track.indexIterator( IndexIteratorKind.NOTE ); itr.hasNext(); ) {
                int index = itr.next();
                if ( index < start_index ) {
                    continue;
                }
                indx++;
                if ( count <= indx ) {
                    break;
                }
                VsqEvent ve = vsq_track.getEvent( index );
                items[indx] = (VsqEvent)ve.clone();
                original_symbol[indx] = ve.ID.LyricHandle.L0.getPhoneticSymbol();
                original_phrase[indx] = ve.ID.LyricHandle.L0.Phrase;
                symbol_protected[indx] = ve.ID.LyricHandle.L0.PhoneticSymbolProtected;
            }

#if DEBUG
            AppManager.debugWriteLine( "    original_phase,symbol=" + original_phrase + "," + original_symbol[0] );
            AppManager.debugWriteLine( "    phonetic_symbol_edit_mode=" + phonetic_symbol_edit_mode );
            AppManager.debugWriteLine( "    AppManager.mInputTextBox.setText(=" + AppManager.mInputTextBox.getText() );
#endif
            String[] phrase = new String[count];
            String[] phonetic_symbol = new String[count];
            for ( int i = 0; i < count; i++ ) {
                phrase[i] = original_phrase[i];
                phonetic_symbol[i] = original_symbol[i];
            }
            String txt = AppManager.mInputTextBox.getText();
            int txtlen = PortUtil.getStringLength( txt );
            if ( txtlen > 0 ) {
                // 1文字目は,UTAUの連続音入力のハイフンの可能性があるので,無駄に置換されるのを回避
                phrase[0] = str.sub( txt, 0, 1 ) + ((txtlen > 1) ? str.sub( txt, 1 ).Replace( "-", "" ) : "");
            } else {
                phrase[0] = "";
            }
            if ( !phonetic_symbol_edit_mode ) {
                // 歌詞を編集するモードで、
                if ( AppManager.editorConfig.SelfDeRomanization ) {
                    // かつローマ字の入力を自動でひらがなに展開する設定だった場合。
                    // ローマ字をひらがなに展開
                    phrase[0] = KanaDeRomanization.Attach( phrase[0] );
                }
            }

            // 発音記号または歌詞が変更された場合の処理
            if ( (phonetic_symbol_edit_mode && !str.compare( AppManager.mInputTextBox.getText(), original_symbol[0] )) ||
                 (!phonetic_symbol_edit_mode && !str.compare( phrase[0], original_phrase[0] )) ) {
                if ( phonetic_symbol_edit_mode ) {
                    // 発音記号を編集するモード
                    phrase[0] = AppManager.mInputTextBox.getBufferText();
                    phonetic_symbol[0] = AppManager.mInputTextBox.getText();

                    // 入力された発音記号のうち、有効なものだけをピックアップ
                    String[] spl = PortUtil.splitString( phonetic_symbol[0], new char[] { ' ' }, true );
                    Vector<String> list = new Vector<String>();
                    for ( int i = 0; i < spl.Length; i++ ) {
                        String s = spl[i];
                        if ( VsqPhoneticSymbol.isValidSymbol( s ) ) {
                            list.add( s );
                        }
                    }

                    // ピックアップした発音記号をスペース区切りで結合
                    phonetic_symbol[0] = "";
                    boolean first = true;
                    for ( Iterator<String> itr = list.iterator(); itr.hasNext(); ) {
                        String s = itr.next();
                        if ( first ) {
                            phonetic_symbol[0] += s;
                            first = false;
                        } else {
                            phonetic_symbol[0] += " " + s;
                        }
                    }

                    // 発音記号を編集すると、自動で「発音記号をプロテクトする」モードになるよ
                    symbol_protected[0] = true;
                } else {
                    // 歌詞を編集するモード
                    if ( !symbol_protected[0] ) {
                        // 発音記号をプロテクトしない場合、歌詞から発音記号を引当てる
                        SymbolTableEntry entry = SymbolTable.attatch( phrase[0] );
                        if ( entry == null ) {
                            phonetic_symbol[0] = "a";
                        } else {
                            phonetic_symbol[0] = entry.getSymbol();
                            // 分節の分割記号'-'が入っている場合
#if DEBUG
                            sout.println( "FormMain#executeLyricChangeCommand; word=" + entry.Word + "; symbol=" + entry.getSymbol() + "; rawSymbol=" + entry.getRawSymbol() );
#endif
                            if ( entry.Word.IndexOf( '-' ) >= 0 ) {
                                String[] spl_phrase = PortUtil.splitString( entry.Word, '\t' );
                                if ( spl_phrase.Length <= count ) {
                                    // 分節の分割数が,後続の音符数と同じか少ない場合
                                    String[] spl_symbol = PortUtil.splitString( entry.getRawSymbol(), '\t' );
                                    for ( int i = 0; i < spl_phrase.Length; i++ ) {
                                        phrase[i] = spl_phrase[i];
                                        phonetic_symbol[i] = spl_symbol[i];
                                    }
                                } else {
                                    // 後続の音符の個数が足りない
                                    phrase[0] = entry.Word.Replace( "\t", "" );
                                }
                            }
                        }
                    } else {
                        // 発音記号をプロテクトする場合、発音記号は最初のやつを使う
                        phonetic_symbol[0] = original_symbol[0];
                    }
                }
#if DEBUG
                AppManager.debugWriteLine( "    phrase,phonetic_symbol=" + phrase + "," + phonetic_symbol );
#endif

                for ( int j = 0; j < count; j++ ) {
                    if ( phonetic_symbol_edit_mode ) {
                        items[j].ID.LyricHandle.L0.setPhoneticSymbol( phonetic_symbol[j] );
                    } else {
                        items[j].ID.LyricHandle.L0.Phrase = phrase[j];
                        items[j].ID.LyricHandle.L0.setPhoneticSymbol( phonetic_symbol[j] );
                        AppManager.applyUtauParameter( vsq_track, items[j] );
                    }
                    if ( !str.compare( original_symbol[j], phonetic_symbol[j] ) ) {
#if JAVA
                        Vector<String> spl = items[j].ID.LyricHandle.L0.getPhoneticSymbolList();
#else
                        List<String> spl = items[j].ID.LyricHandle.L0.getPhoneticSymbolList();
#endif
                        Vector<Integer> adjustment = new Vector<Integer>();
                        for ( int i = 0; i < vec.size( spl ); i++ ) {
                            String s = vec.get( spl, i );
                            adjustment.add( VsqPhoneticSymbol.isConsonant( s ) ? 64 : 0 );
                        }
                        items[j].ID.LyricHandle.L0.setConsonantAdjustmentList( adjustment );
                    }
                }

                CadenciiCommand run = new CadenciiCommand( VsqCommand.generateCommandEventReplaceRange( selected, items ) );
                AppManager.editHistory.register( vsq.executeCommand( run ) );
                setEdited( true );
            }
        }

        /// <summary>
        /// 識別済みのゲームコントローラを取り外します
        /// </summary>
03422         public void removeGameControler()
        {
#if !JAVA
            if ( mTimer != null ) {
                mTimer.stop();
                mTimer.Dispose();
                mTimer = null;
            }
            mGameMode = GameControlMode.DISABLED;
            updateGameControlerStatus( null, null );
#endif
        }

        /// <summary>
        /// PCに接続されているゲームコントローラを識別・接続します
        /// </summary>
03438         public void loadGameControler()
        {
#if !JAVA
            try {
                boolean init_success = false;
                int num_joydev = winmmhelp.JoyInit();
                if ( num_joydev <= 0 ) {
                    init_success = false;
                } else {
                    init_success = true;
                }
                if ( init_success ) {
                    mGameMode = GameControlMode.NORMAL;
                    stripLblGameCtrlMode.setIcon( null );
                    stripLblGameCtrlMode.setText( mGameMode.ToString() );
                    mTimer = new BTimer();
                    mTimer.setDelay( 10 );
                    mTimer.Tick += new BEventHandler( mTimer_Tick );
                    mTimer.start();
                } else {
                    mGameMode = GameControlMode.DISABLED;
                }
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".loadGameControler; ex=" + ex + "\n" );
                mGameMode = GameControlMode.DISABLED;
#if DEBUG
                AppManager.debugWriteLine( "FormMain+ReloadGameControler" );
                AppManager.debugWriteLine( "    ex=" + ex );
#endif
            }
            updateGameControlerStatus( null, null );
#endif
        }

#if ENABLE_MIDI
        /// <summary>
        /// MIDI入力句デバイスを再読込みします
        /// </summary>
        public void reloadMidiIn()
        {
            if ( mMidiIn != null ) {
                mMidiIn.MidiReceived -= new MidiReceivedEventHandler( mMidiIn_MidiReceived );
                mMidiIn.close();
                mMidiIn = null;
            }
            int portNumber = AppManager.editorConfig.MidiInPort.PortNumber;
            int portNumberMtc = AppManager.editorConfig.MidiInPortMtc.PortNumber;
#if DEBUG
            sout.println( "FormMain#reloadMidiIn; portNumber=" + portNumber + "; portNumberMtc=" + portNumberMtc );
#endif
            try {
                mMidiIn = new MidiInDevice( portNumber );
                mMidiIn.MidiReceived += new MidiReceivedEventHandler( mMidiIn_MidiReceived );
#if ENABLE_MTC
                if ( portNumber == portNumberMtc ) {
                    m_midi_in.setReceiveSystemCommonMessage( true );
                    m_midi_in.setReceiveSystemRealtimeMessage( true );
                    m_midi_in.MidiReceived += handleMtcMidiReceived;
                    m_midi_in.Start();
                } else {
                    m_midi_in.setReceiveSystemCommonMessage( false );
                    m_midi_in.setReceiveSystemRealtimeMessage( false );
                }
#else
                mMidiIn.setReceiveSystemCommonMessage( false );
                mMidiIn.setReceiveSystemRealtimeMessage( false );
#endif
            } catch ( Exception ex ) {
#if JAVA
                ex.printStackTrace();
#endif
                Logger.write( typeof( FormMain ) + ".reloadMidiIn; ex=" + ex + "\n" );
                serr.println( "FormMain#reloadMidiIn; ex=" + ex );
            }

#if ENABLE_MTC
            if ( m_midi_in_mtc != null ) {
                m_midi_in_mtc.MidiReceived -= handleMtcMidiReceived;
                m_midi_in_mtc.Dispose();
                m_midi_in_mtc = null;
            }
            if ( portNumber != portNumberMtc ) {
                try {
                    m_midi_in_mtc = new MidiInDevice( AppManager.editorConfig.MidiInPortMtc.PortNumber );
                    m_midi_in_mtc.MidiReceived += handleMtcMidiReceived;
                    m_midi_in_mtc.setReceiveSystemCommonMessage( true );
                    m_midi_in_mtc.setReceiveSystemRealtimeMessage( true );
                    m_midi_in_mtc.Start();
                } catch ( Exception ex ) {
                    Logger.write( typeof( FormMain ) + ".reloadMidiIn; ex=" + ex + "\n" );
                    serr.println( "FormMain#reloadMidiIn; ex=" + ex );
                }
            }
#endif
            updateMidiInStatus();
        }
#endif

#if ENABLE_MIDI
        public void updateMidiInStatus()
        {
            int midiport = AppManager.editorConfig.MidiInPort.PortNumber;
            Vector<MidiDevice.Info> devices = new Vector<MidiDevice.Info>();
            foreach ( MidiDevice.Info info in MidiSystem.getMidiDeviceInfo() ){
                MidiDevice device = null;
                try{
                    device = MidiSystem.getMidiDevice( info );
                }catch( Exception ex ){
                    device = null;
                }
                if( device == null ) continue;
                int max = device.getMaxTransmitters();
                if( max > 0 || max == -1 ){
                    devices.add( info );
                }
            }
            if ( midiport < 0 || vec.size( devices ) <= 0 ) {
#if JAVA
                stripBtnStepSequencer.setEnabled( false );
#else
                stripLblMidiIn.setText( _( "Disabled" ) );
                stripLblMidiIn.setIcon( new ImageIcon( Resources.get_slash() ) );
#endif
            } else {
                if ( midiport >= vec.size( devices ) ) {
                    midiport = 0;
                    AppManager.editorConfig.MidiInPort.PortNumber = midiport;
                }
#if JAVA
                stripBtnStepSequencer.setEnabled( true );
#else
                stripLblMidiIn.setText( vec.get( devices, midiport ).getName() );
                stripLblMidiIn.setIcon( new ImageIcon( Resources.get_piano() ) );
#endif
            }
        }
#endif

#if ENABLE_SCRIPT
        /// <summary>
        /// スクリプトフォルダ中のスクリプトへのショートカットを作成する
        /// </summary>
        public void updateScriptShortcut()
        {
            // 既存のアイテムを削除
            menuScript.removeAll();
            // スクリプトをリロード
            ScriptServer.reload();

            // スクリプトごとのメニューを追加
            int count = 0;
            for ( Iterator<String> itr = ScriptServer.getScriptIdIterator(); itr.hasNext(); ) {
                String id = itr.next();
                if ( str.compare( PortUtil.getFileNameWithoutExtension( id ).ToLower(), "runonce" ) ) {
                    continue;
                }
                String display = ScriptServer.getDisplayName( id );
                // スクリプトのメニューに共通のヘッダー(menuScript)を付ける.
                // こうしておくと,menuSettingShortcut_Clickで,スクリプトのメニューが
                // menuScriptの子だと自動で認識される
                String name = "menuScript" + id.Replace( '.', '_' );
                PaletteToolMenuItem item = new PaletteToolMenuItem( id );
                item.setText( display );
                item.setName( name );
                item.Click += new BEventHandler( handleScriptMenuItem_Click );
                menuScript.add( item );
                count++;
            }

            // 「スクリプトのリストを更新」を追加
            if ( count > 0 ) {
                menuScript.addSeparator();
            }
            menuScript.add( menuScriptUpdate );
            Util.applyToolStripFontRecurse( menuScript, AppManager.editorConfig.getBaseFont() );
            applyShortcut();
        }
#endif
        /// <summary>
        /// 指定したノートナンバーが可視状態となるよう、縦スクロールバーを移動させます。
        /// </summary>
        /// <param name="note"></param>
03620         public void ensureVisibleY( int note )
        {
            if ( note <= 0 ) {
                vScroll.setValue( vScroll.getMaximum() - vScroll.getVisibleAmount() );
                return;
            } else if ( note >= 127 ) {
                vScroll.setValue( vScroll.getMinimum() );
                return;
            }
            int height = pictPianoRoll.getHeight();
            int noteTop = AppManager.noteFromYCoord( 0 ); //画面上端でのノートナンバー
            int noteBottom = AppManager.noteFromYCoord( height ); // 画面下端でのノートナンバー

            int maximum = vScroll.getMaximum();
            int track_height = (int)(100 * controller.getScaleY());
            // ノートナンバーnoteの現在のy座標がいくらか?
            int note_y = AppManager.yCoordFromNote( note );
            if ( note < noteBottom ) {
                // ノートナンバーnoteBottomの現在のy座標が新しいnoteのy座標と同一になるよう,startToDrawYを変える
                // startToDrawYを次の値にする必要がある
                int new_start_to_draw_y = controller.getStartToDrawY() + (note_y - height);
                int value = calculateVScrollValueFromStartToDrawY( new_start_to_draw_y );
                vScroll.setValue( value );
            } else if ( noteTop < note ) {
                // ノートナンバーnoteTopの現在のy座標が,ノートナンバーnoteの新しいy座標と同一になるよう,startToDrawYを変える
                int new_start_to_draw_y = controller.getStartToDrawY() + (note_y - 0);
                int value = calculateVScrollValueFromStartToDrawY( new_start_to_draw_y );
                vScroll.setValue( value );
            }
        }

        /// <summary>
        /// 指定したゲートタイムがピアノロール上で可視状態となるよう、横スクロールバーを移動させます。
        /// </summary>
        /// <param name="clock"></param>
03655         public void ensureVisible( int clock )
        {
            // カーソルが画面内にあるかどうか検査
            int clock_left = AppManager.clockFromXCoord( AppManager.keyWidth );
            int clock_right = AppManager.clockFromXCoord( pictPianoRoll.getWidth() );
            int uwidth = clock_right - clock_left;
            if ( clock < clock_left || clock_right < clock ) {
                int cl_new_center = (clock / uwidth) * uwidth + uwidth / 2;
                float f_draft = cl_new_center - (pictPianoRoll.getWidth() / 2 + 34 - 70) * controller.getScaleXInv();
                if ( f_draft < 0f ) {
                    f_draft = 0;
                }
                int draft = (int)(f_draft);
                if ( draft < hScroll.getMinimum() ) {
                    draft = hScroll.getMinimum();
                } else if ( hScroll.getMaximum() < draft ) {
                    draft = hScroll.getMaximum();
                }
                if ( hScroll.getValue() != draft ) {
                    AppManager.mDrawStartIndex[AppManager.getSelected() - 1] = 0;
                    hScroll.setValue( draft );
                }
            }
        }

        /// <summary>
        /// プレイカーソルが見えるようスクロールする
        /// </summary>
03683         public void ensureCursorVisible()
        {
            ensureVisible( AppManager.getCurrentClock() );
        }

        /// <summary>
        /// 特殊なショートカットキーを処理します。
        /// </summary>
        /// <param name="e"></param>
        /// <param name="onPreviewKeyDown">PreviewKeyDownイベントから送信されてきた場合、true(送る側が設定する)</param>
03693         public void processSpecialShortcutKey( BKeyEventArgs e, boolean onPreviewKeyDown )
        {
#if DEBUG
            sout.println( "FormMain#processSpecialShortcutKey" );
#endif
            // 歌詞入力用のテキストボックスが表示されていたら,何もしない
#if JAVA
            if ( AppManager.mInputTextBox.isVisible() ) {
#else
            if ( AppManager.mInputTextBox.Enabled ) {
#endif
                AppManager.mInputTextBox.requestFocus();
                return;
            }

            boolean flipPlaying = false; // 再生/停止状態の切り替えが要求されたらtrue

            // 最初に、特殊な取り扱いが必要なショートカット、について、
            // 該当するショートカットがあればそいつらを発動する。
            int modifier = PortUtil.getCurrentModifierKey();
            KeyStroke stroke = KeyStroke.getKeyStroke( e.KeyValue, modifier );
            int keycode = e.KeyValue;
#if DEBUG
            sout.println( "FormMain#processSpecialShortcutKey; stroke=" + stroke );
#endif

            if ( onPreviewKeyDown && keycode != 0 ) {
                foreach ( SpecialShortcutHolder holder in mSpecialShortcutHolders ) {
                    if ( stroke.Equals( holder.shortcut ) ) {
                        try {
#if DEBUG
                            sout.println( "FormMain#processSpecialShortcutKey; perform click: name=" + holder.menu.getName() );
#endif
#if JAVA
                            holder.menu.clickEvent.raise( holder.menu, new BEventArgs() );
#else
                            holder.menu.PerformClick();
#endif
                        } catch ( Exception ex ) {
                            Logger.write( typeof( FormMain ) + ".processSpecialShortcutKey; ex=" + ex + "\n" );
                            serr.println( "FormMain#processSpecialShortcutKey; ex=" + ex );
                        }
#if JAVA
                        if ( e.KeyValue == KeyEvent.VK_TAB ) {
#else
                        if ( e.KeyCode == System.Windows.Forms.Keys.Tab ) {
#endif
                            focusPianoRoll();
                        }
                        return;
                    }
                }
            }

            if ( modifier != KeyEvent.VK_UNDEFINED ) {
#if DEBUG
                sout.println( "FormMain#processSpecialShortcutKey; bailout with (modifier != VK_UNDEFINED)" );
#endif
                return;
            }

            EditMode edit_mode = AppManager.getEditMode();

#if JAVA
            if ( e.KeyValue == KeyEvent.VK_ENTER ) {
#else
            if ( e.KeyCode == System.Windows.Forms.Keys.Return ) {
#endif
                // MIDIステップ入力のときの処理
                if ( controller.isStepSequencerEnabled() ) {
                    if ( AppManager.mAddingEvent != null ) {
                        fixAddingEvent();
                        AppManager.mAddingEvent = null;
                        refreshScreen( true );
                    }
                }
#if JAVA
            } else if ( e.KeyValue == KeyEvent.VK_SPACE ) {
#else
            } else if ( e.KeyCode == System.Windows.Forms.Keys.Space ) {
#endif
                if ( !AppManager.editorConfig.UseSpaceKeyAsMiddleButtonModifier ) {
                    flipPlaying = true;
                }
#if JAVA
            } else if ( e.KeyValue == KeyEvent.VK_PERIOD ) {
#else
            } else if ( e.KeyCode == System.Windows.Forms.Keys.OemPeriod ) {
#endif
                if ( !onPreviewKeyDown ) {

                    if ( AppManager.isPlaying() ) {
                        AppManager.setPlaying( false, this );
                    } else {
                        VsqFileEx vsq = AppManager.getVsqFile();
                        if ( !vsq.config.StartMarkerEnabled ) {
                            AppManager.setCurrentClock( 0 );
                        } else {
                            AppManager.setCurrentClock( vsq.config.StartMarker );
                        }
                        refreshScreen();
                    }
                }
#if JAVA
            } else if( e.KeyValue == KeyEvent.VK_ADD || e.KeyValue == KeyEvent.VK_PLUS || e.KeyValue == KeyEvent.VK_RIGHT ) {
#else
            } else if ( e.KeyCode == System.Windows.Forms.Keys.Add || e.KeyCode == System.Windows.Forms.Keys.Oemplus || e.KeyCode == System.Windows.Forms.Keys.Right ) {
#endif
                if ( onPreviewKeyDown ) {
                    forward();
                }
#if JAVA
            } else if ( e.KeyValue == KeyEvent.VK_MINUS || e.KeyValue == KeyEvent.VK_LEFT ) {
#else
            } else if ( e.KeyCode == System.Windows.Forms.Keys.Subtract || e.KeyCode == System.Windows.Forms.Keys.OemMinus || e.KeyCode == System.Windows.Forms.Keys.Left ) {
#endif
                if ( onPreviewKeyDown ) {
                    rewind();
                }
#if JAVA
            } else if ( e.KeyValue == KeyEvent.VK_ESCAPE ) {
#else
            } else if ( e.KeyCode == System.Windows.Forms.Keys.Escape ) {
#endif
                // ステップ入力中の場合,入力中の音符をクリアする
                VsqEvent item = AppManager.mAddingEvent;
                if ( controller.isStepSequencerEnabled() && item != null ) {
                    // 入力中だった音符の長さを取得し,
                    int length = item.ID.getLength();
                    AppManager.mAddingEvent = null;
                    int clock = AppManager.getCurrentClock();
                    int clock_draft = clock - length;
                    if ( clock_draft < 0 ) {
                        clock_draft = 0;
                    }
                    // その分だけソングポジションを戻す.
                    AppManager.setCurrentClock( clock_draft );
                    refreshScreen( true );
                }
            } else {
                if ( !AppManager.isPlaying() ) {
                    // 最初に戻る、の機能を発動
                    BKeys[] specialGoToFirst = AppManager.editorConfig.SpecialShortcutGoToFirst;
                    if ( specialGoToFirst != null && specialGoToFirst.Length > 0 ) {
                        KeyStroke ks = BKeysUtility.getKeyStrokeFromBKeys( specialGoToFirst );
#if JAVA
                        if( e.KeyCode == ks.getKeyCode() )
#else
                        if ( e.KeyCode == ks.keys )
#endif
                        {
                            AppManager.setCurrentClock( 0 );
                            ensureCursorVisible();
                            refreshScreen();
                        }
                    }
                }
            }
            if ( !onPreviewKeyDown && flipPlaying ) {
                if ( AppManager.isPlaying() ) {
                    double elapsed = PlaySound.getPosition();
                    double threshold = AppManager.mForbidFlipPlayingThresholdSeconds;
                    if ( threshold < 0 ) {
                        threshold = 0.0;
                    }
                    if ( elapsed > threshold ) {
                        timer.stop();
                        AppManager.setPlaying( false, this );
                    }
                } else {
                    AppManager.setPlaying( true, this );
                }
            }
#if JAVA
            if ( e.KeyValue == KeyEvent.VK_TAB ) {
#else
            if ( e.KeyCode == System.Windows.Forms.Keys.Tab ) {
#endif
                focusPianoRoll();
            }
        }

        public void updateScrollRangeHorizontal()
        {
            // コンポーネントの高さが0の場合,スクロールの設定が出来ないので.
            int pwidth = pictPianoRoll.getWidth();
            int hwidth = hScroll.getWidth();
            if ( pwidth <= 0 || hwidth <= 0 ) {
                return;
            }

            VsqFileEx vsq = AppManager.getVsqFile();
            if ( vsq == null ) return;
            int l = vsq.TotalClocks;
            float scalex = controller.getScaleX();
            int key_width = AppManager.keyWidth;
            int pict_piano_roll_width = pwidth - key_width;
            int large_change = (int)(pict_piano_roll_width / scalex);
            int maximum = (int)(l + large_change);

#if JAVA
            int thumb_width = 40;
#else
            int thumb_width = System.Windows.Forms.SystemInformation.HorizontalScrollBarThumbWidth;
#endif
            int box_width = (int)(large_change / (float)maximum * (hwidth - 2 * thumb_width));
            if ( box_width < AppManager.editorConfig.MinimumScrollHandleWidth ) {
                box_width = AppManager.editorConfig.MinimumScrollHandleWidth;
                if ( hwidth - 2 * thumb_width > box_width ) {
                    maximum = l * (hwidth - 2 * thumb_width) / (hwidth - 2 * thumb_width - box_width);
                    large_change = l * box_width / (hwidth - 2 * thumb_width - box_width);
                }
            }

            if ( large_change <= 0 ) large_change = 1;
            if ( maximum <= 0 ) maximum = 1;
            hScroll.setVisibleAmount( large_change );
            hScroll.setMaximum( maximum );
#if JAVA
            int unit_increment = large_change / 10;
            if( unit_increment <= 0 ){
                unit_increment = 1;
            }
            hScroll.setUnitIncrement( unit_increment );
            hScroll.setBlockIncrement( large_change );
#endif

            int old_value = hScroll.getValue();
            if ( old_value > maximum - large_change ) {
                hScroll.setValue( maximum - large_change );
            }
        }

        public void updateScrollRangeVertical()
        {
            // コンポーネントの高さが0の場合,スクロールの設定が出来ないので.
            int pheight = pictPianoRoll.getHeight();
            int vheight = vScroll.getHeight();
            if ( pheight <= 0 || vheight <= 0 ) {
                return;
            }

            float scaley = controller.getScaleY();

            int maximum = (int)(128 * (int)(100 * scaley) / scaley);
            int large_change = (int)(pheight / scaley);

#if JAVA
            int thumb_height = 40;
#else
            int thumb_height = System.Windows.Forms.SystemInformation.VerticalScrollBarThumbHeight;
#endif
            int box_height = (int)(large_change / (float)maximum * (vheight - 2 * thumb_height));
            if ( box_height < AppManager.editorConfig.MinimumScrollHandleWidth ) {
                box_height = AppManager.editorConfig.MinimumScrollHandleWidth;
                maximum = (int)(((128.0 * (int)(100 * scaley) - pheight) / scaley) * (vheight - 2 * thumb_height) / (vheight - 2 * thumb_height - box_height));
                large_change = (int)(((128.0 * (int)(100 * scaley) - pheight) / scaley) * box_height / (vheight - 2 * thumb_height - box_height));
            }

            if ( large_change <= 0 ) large_change = 1;
            if ( maximum <= 0 ) maximum = 1;
            vScroll.setVisibleAmount( large_change );
            vScroll.setMaximum( maximum );
#if !JAVA
            vScroll.SmallChange = 100;
#endif

#if JAVA
            int unit_increment = large_change / 10;
            if( unit_increment <= 0 ){
                unit_increment = 1;
            }
            vScroll.setUnitIncrement( unit_increment );
            vScroll.setBlockIncrement( large_change );
#endif

            int old_value = vScroll.getValue();
            if ( old_value > maximum - large_change ) {
                vScroll.setValue( maximum - large_change );
            }
        }

        /// <summary>
        /// コントロールトラックの表示・非表示状態を更新します
        /// </summary>
03978         public void flipControlCurveVisible( boolean visible )
        {
            trackSelector.setCurveVisible( visible );
            if ( visible ) {
                splitContainer1.setSplitterFixed( false );
                splitContainer1.setDividerSize( _SPL_SPLITTER_WIDTH );
                splitContainer1.setDividerLocation( splitContainer1.getHeight() - AppManager.mLastTrackSelectorHeight - splitContainer1.getDividerSize() );
                splitContainer1.setPanel2MinSize( trackSelector.getPreferredMinSize() );
            } else {
                AppManager.mLastTrackSelectorHeight = splitContainer1.getHeight() - splitContainer1.getDividerLocation() - splitContainer1.getDividerSize();
                splitContainer1.setSplitterFixed( true );
                splitContainer1.setDividerSize( 0 );
                int panel2height = TrackSelector.OFFSET_TRACK_TAB * 2;
                splitContainer1.setDividerLocation( splitContainer1.getHeight() - panel2height - splitContainer1.getDividerSize() );
                splitContainer1.setPanel2MinSize( panel2height );
            }
            refreshScreen();
        }

        /// <summary>
        /// ミキサーダイアログの表示・非表示状態を更新します
        /// </summary>
        /// <param name="visible">表示状態にする場合true,そうでなければfalse</param>
04001         public void flipMixerDialogVisible( boolean visible )
        {
            AppManager.mMixerWindow.setVisible( visible );
            AppManager.editorConfig.MixerVisible = visible;
            if( visible != menuVisualMixer.isSelected() ){
                menuVisualMixer.setSelected( visible );
            }
        }

        /// <summary>
        /// アイコンパレットの表示・非表示状態を更新します
        /// </summary>
04013         public void flipIconPaletteVisible( boolean visible )
        {
            AppManager.iconPalette.setVisible( visible );
            AppManager.editorConfig.IconPaletteVisible = visible;
            if( visible != menuVisualIconPalette.isSelected() ){
                menuVisualIconPalette.setSelected( visible );
            }
        }

        /// <summary>
        /// メニューのショートカットキーを、AppManager.EditorConfig.ShorcutKeysの内容に応じて変更します
        /// </summary>
04025         public void applyShortcut()
        {
            mSpecialShortcutHolders.clear();

            TreeMap<String, BKeys[]> dict = AppManager.editorConfig.getShortcutKeysDictionary( this.getDefaultShortcutKeys() );
            #region menuStripMain
            ByRef<Object> parent = new ByRef<Object>( null );
            for ( Iterator<String> itr = dict.keySet().iterator(); itr.hasNext(); ) {
                String key = itr.next();
                if ( str.compare( key, "menuEditCopy" ) || str.compare( key, "menuEditCut" ) || str.compare( key, "menuEditPaste" ) || str.compare( key, "SpecialShortcutGoToFirst" ) ) {
                    continue;
                }
                Object menu = searchMenuItemFromName( key, parent );
                if ( menu != null ) {
                    String menu_name = "";
#if JAVA
                    if( menu instanceof Component ){
                        menu_name = ((Component)menu).getName();
                    }else{
                        continue;
                    }
#else
                    if ( menu is BMenuItem ) {
                        menu_name = ((BMenuItem)menu).Name;
                    } else {
                        continue;
                    }
#endif
                    applyMenuItemShortcut( dict, menu, menu_name );
                }
            }
            if ( dict.containsKey( "menuEditCopy" ) ) {
                applyMenuItemShortcut( dict, menuHiddenCopy, "menuEditCopy" );
            }
            if ( dict.containsKey( "menuEditCut" ) ) {
                applyMenuItemShortcut( dict, menuHiddenCut, "menuEditCut" );
            }
            if ( dict.containsKey( "menuEditCopy" ) ) {
                applyMenuItemShortcut( dict, menuHiddenPaste, "menuEditPaste" );
            }
            #endregion

            Vector<ValuePair<String, BMenuItem[]>> work = new Vector<ValuePair<String, BMenuItem[]>>();
            work.add( new ValuePair<String, BMenuItem[]>( "menuEditUndo", new BMenuItem[] { cMenuPianoUndo, cMenuTrackSelectorUndo } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuEditRedo", new BMenuItem[] { cMenuPianoRedo, cMenuTrackSelectorRedo } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuEditCut", new BMenuItem[] { cMenuPianoCut, cMenuTrackSelectorCut, menuEditCut } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuEditCopy", new BMenuItem[] { cMenuPianoCopy, cMenuTrackSelectorCopy, menuEditCopy } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuEditPaste", new BMenuItem[] { cMenuPianoPaste, cMenuTrackSelectorPaste, menuEditPaste } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuEditSelectAll", new BMenuItem[] { cMenuPianoSelectAll, cMenuTrackSelectorSelectAll } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuEditSelectAllEvents", new BMenuItem[] { cMenuPianoSelectAllEvents } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuEditDelete", new BMenuItem[] { menuEditDelete } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuVisualGridline", new BMenuItem[] { cMenuPianoGrid } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuJobLyric", new BMenuItem[] { cMenuPianoImportLyric } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuLyricExpressionProperty", new BMenuItem[] { cMenuPianoExpressionProperty } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuLyricVibratoProperty", new BMenuItem[] { cMenuPianoVibratoProperty } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuTrackOn", new BMenuItem[] { cMenuTrackTabTrackOn } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuTrackAdd", new BMenuItem[] { cMenuTrackTabAdd } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuTrackCopy", new BMenuItem[] { cMenuTrackTabCopy } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuTrackDelete", new BMenuItem[] { cMenuTrackTabDelete } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuTrackRenderCurrent", new BMenuItem[] { cMenuTrackTabRenderCurrent } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuTrackRenderAll", new BMenuItem[] { cMenuTrackTabRenderAll } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuTrackOverlay", new BMenuItem[] { cMenuTrackTabOverlay } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuTrackRendererVOCALOID1", new BMenuItem[] { cMenuTrackTabRendererVOCALOID1 } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuTrackRendererVOCALOID2", new BMenuItem[] { cMenuTrackTabRendererVOCALOID2 } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuTrackRendererAquesTone", new BMenuItem[] { menuTrackRendererAquesTone } ) );
            work.add( new ValuePair<String, BMenuItem[]>( "menuTrackRendererVCNT", new BMenuItem[] { menuTrackRendererVCNT } ) );
            int c = work.size();
            for ( int j = 0; j < c; j++ ) {
                ValuePair<String, BMenuItem[]> item = work.get( j );
                if ( dict.containsKey( item.getKey() ) ) {
                    BKeys[] k = dict.get( item.getKey() );
                    String s = Utility.getShortcutDisplayString( k );
#if !JAVA
                    if ( s != "" ) {
                        for ( int i = 0; i < item.getValue().Length; i++ ) {
                            item.getValue()[i].ShortcutKeyDisplayString = s;
                        }
                    }
#endif
                }
            }

            // ミキサーウィンドウ
            if ( AppManager.mMixerWindow != null ) {
                if ( dict.containsKey( "menuVisualMixer" ) ) {
                    KeyStroke shortcut = BKeysUtility.getKeyStrokeFromBKeys( dict.get( "menuVisualMixer" ) );
                    AppManager.mMixerWindow.applyShortcut( shortcut );
                }
            }

            // アイコンパレット
            if ( AppManager.iconPalette != null ) {
                if ( dict.containsKey( "menuVisualIconPalette" ) ) {
                    KeyStroke shortcut = BKeysUtility.getKeyStrokeFromBKeys( dict.get( "menuVisualIconPalette" ) );
                    AppManager.iconPalette.applyShortcut( shortcut );
                }
            }

#if ENABLE_PROPERTY
            // プロパティ
            if( AppManager.propertyWindow != null ){
                if( dict.containsKey( menuVisualProperty.getName() ) ){
                    KeyStroke shortcut = BKeysUtility.getKeyStrokeFromBKeys( dict.get( menuVisualProperty.getName() ) );
                    AppManager.propertyWindow.applyShortcut( shortcut );
                }
            }
#endif

            // スクリプトにショートカットを適用
#if JAVA
            MenuElement[] sub_menu_script = menuScript.getSubElements();
            for ( int i = 0; i < sub_menu_script.Length; i++ ) {
                MenuElement tsi = sub_menu_script[i];
                MenuElement[] sub_tsi = tsi.getSubElements();
                if ( sub_tsi.Length == 1 ) {
                    MenuElement dd_run = sub_tsi[0];
#if DEBUG
                    AppManager.debugWriteLine( "    dd_run.name=" + PortUtil.getComponentName( dd_run ) );
#endif
                    if ( dict.containsKey( PortUtil.getComponentName( dd_run ) ) ) {
                        applyMenuItemShortcut( dict, tsi, PortUtil.getComponentName( tsi ) );
                    }
                }
            }
#else
            int count = menuScript.DropDownItems.Count;
            for ( int i = 0; i < count; i++ ) {
                System.Windows.Forms.ToolStripItem tsi = menuScript.DropDownItems[i];
                if ( tsi is System.Windows.Forms.ToolStripMenuItem ) {
                    System.Windows.Forms.ToolStripMenuItem tsmi = (System.Windows.Forms.ToolStripMenuItem)tsi;
                    if ( tsmi.DropDownItems.Count == 1 ) {
                        System.Windows.Forms.ToolStripItem subtsi_tsmi = tsmi.DropDownItems[0];
                        if ( subtsi_tsmi is System.Windows.Forms.ToolStripMenuItem ) {
                            System.Windows.Forms.ToolStripMenuItem dd_run = (System.Windows.Forms.ToolStripMenuItem)subtsi_tsmi;
                            if ( dict.containsKey( PortUtil.getComponentName( dd_run ) ) ) {
                                applyMenuItemShortcut( dict, tsmi, PortUtil.getComponentName( tsi ) );
                            }
                        }
                    }
                }
            }
#endif
        }

        /// <summary>
        /// dictの中から
        /// </summary>
        /// <param name="dict"></param>
        /// <param name="item"></param>
        /// <param name="item_name"></param>
        /// <param name="default_shortcut"></param>
04176         public void applyMenuItemShortcut( TreeMap<String, BKeys[]> dict, Object item, String item_name )
        {
#if JAVA
            if( item == null ){
                return;
            }
            if( item instanceof JMenu ){
                return;
            }
            if( !(item instanceof BMenuItem) ){
                return;
            }
            BMenuItem menu = (BMenuItem)item;
            menu.setAccelerator( null );
            if( !dict.containsKey( item_name ) ){
                return;
            }
            BKeys[] k = dict.get( item_name );
            if( k == null ){
                return;
            }
            if( k.length <= 0 ){
                return;
            }
            try {
                sout.println( "FormMain#applyMenuItemShortcut; item_name=" + item_name );
                KeyStroke ks = BKeysUtility.getKeyStrokeFromBKeys( k );
                if( str.startsWith( item_name, "menuHidden" ) ){
                    mSpecialShortcutHolders.add(
                        new SpecialShortcutHolder( BKeysUtility.getKeyStrokeFromBKeys( k ), menu ) );
                }else{
                    menu.setAccelerator( ks );
                }
            } catch ( Exception ex ) {
                Logger.write( FormMain.class  + ".applyMenuItemShortcut; ex=" + ex + "\n" );
                ex.printStackTrace();
            }
#else // JAVA
            try {
                if ( dict.containsKey( item_name ) ) {
#if DEBUG
                    if ( !(item is BMenuItem) ) {
                        throw new Exception( "FormMain#applyMenuItemShortcut; item is NOT BMenuItem" );
                    }
#endif // DEBUG
                    if ( item is BMenuItem ) {
                        BMenuItem menu = (BMenuItem)item;
                        BKeys[] keys = dict.get( item_name );
                        System.Windows.Forms.Keys shortcut = BKeysUtility.getKeyStrokeFromBKeys( keys ).keys;

                        if ( shortcut == System.Windows.Forms.Keys.Delete ) {
                            menu.ShortcutKeyDisplayString = "Delete";
                            menu.ShortcutKeys = System.Windows.Forms.Keys.None;
                            mSpecialShortcutHolders.add(
                                new SpecialShortcutHolder( BKeysUtility.getKeyStrokeFromBKeys( keys ), menu ) );
                        } else {
                            try {
                                menu.ShortcutKeyDisplayString = "";
                                menu.ShortcutKeys = shortcut;
                            } catch ( Exception ex ) {
                                // ショートカットの適用に失敗する→特殊な取り扱いが必要
                                menu.ShortcutKeyDisplayString = Utility.getShortcutDisplayString( keys );
                                menu.ShortcutKeys = System.Windows.Forms.Keys.None;
                                mSpecialShortcutHolders.add(
                                    new SpecialShortcutHolder( BKeysUtility.getKeyStrokeFromBKeys( keys ), menu ) );
                            }
                        }
                    }
                } else {
                    if ( item is BMenuItem ) {
                        ((BMenuItem)item).setAccelerator( BKeysUtility.getKeyStrokeFromBKeys( new BKeys[] { BKeys.None } ) );
                    }
                }
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".applyMenuItemShortcut; ex=" + ex + "\n" );
            }
#endif // else JAVA
        }

        /// <summary>
        /// ソングポジションを1小節進めます
        /// </summary>
04258         public void forward()
        {
            boolean playing = AppManager.isPlaying();
            if ( playing ) {
                return;
            }
            VsqFileEx vsq = AppManager.getVsqFile();
            if ( vsq == null ) {
                return;
            }
            int cl_clock = AppManager.getCurrentClock();
            int unit = QuantizeModeUtil.getQuantizeClock(
                AppManager.editorConfig.getPositionQuantize(),
                AppManager.editorConfig.isPositionQuantizeTriplet() );
            int cl_new = doQuantize( cl_clock + unit, unit );

            if ( cl_new <= hScroll.getMaximum() + (pictPianoRoll.getWidth() - AppManager.keyWidth) * controller.getScaleXInv() ) {
                // 表示の更新など
                AppManager.setCurrentClock( cl_new );

                // ステップ入力時の処理
                updateNoteLengthStepSequencer();

                ensureCursorVisible();
                AppManager.setPlaying( playing, this );
                refreshScreen();
            }
        }

        /// <summary>
        /// ソングポジションを1小節戻します
        /// </summary>
04290         public void rewind()
        {
            boolean playing = AppManager.isPlaying();
            if ( playing ) {
                return;
            }
            VsqFileEx vsq = AppManager.getVsqFile();
            if ( vsq == null ) {
                return;
            }
            int cl_clock = AppManager.getCurrentClock();
            int unit = QuantizeModeUtil.getQuantizeClock(
                AppManager.editorConfig.getPositionQuantize(),
                AppManager.editorConfig.isPositionQuantizeTriplet() );
            int cl_new = doQuantize( cl_clock - unit, unit );
            if ( cl_new < 0 ) {
                cl_new = 0;
            }

            AppManager.setCurrentClock( cl_new );

            // ステップ入力時の処理
            updateNoteLengthStepSequencer();

            ensureCursorVisible();
            AppManager.setPlaying( playing, this );
            refreshScreen();
        }

        /// <summary>
        /// cMenuPianoの固定長音符入力の各メニューのチェック状態をm_pencil_modeを元に更新します
        /// </summary>
04322         public void updateCMenuPianoFixed()
        {
            cMenuPianoFixed01.setSelected( false );
            cMenuPianoFixed02.setSelected( false );
            cMenuPianoFixed04.setSelected( false );
            cMenuPianoFixed08.setSelected( false );
            cMenuPianoFixed16.setSelected( false );
            cMenuPianoFixed32.setSelected( false );
            cMenuPianoFixed64.setSelected( false );
            cMenuPianoFixed128.setSelected( false );
            cMenuPianoFixedOff.setSelected( false );
            cMenuPianoFixedTriplet.setSelected( false );
            cMenuPianoFixedDotted.setSelected( false );
            PencilModeEnum mode = mPencilMode.getMode();
            if ( mode == PencilModeEnum.L1 ) {
                cMenuPianoFixed01.setSelected( true );
            } else if ( mode == PencilModeEnum.L2 ) {
                cMenuPianoFixed02.setSelected( true );
            } else if ( mode == PencilModeEnum.L4 ) {
                cMenuPianoFixed04.setSelected( true );
            } else if ( mode == PencilModeEnum.L8 ) {
                cMenuPianoFixed08.setSelected( true );
            } else if ( mode == PencilModeEnum.L16 ) {
                cMenuPianoFixed16.setSelected( true );
            } else if ( mode == PencilModeEnum.L32 ) {
                cMenuPianoFixed32.setSelected( true );
            } else if ( mode == PencilModeEnum.L64 ) {
                cMenuPianoFixed64.setSelected( true );
            } else if ( mode == PencilModeEnum.L128 ) {
                cMenuPianoFixed128.setSelected( true );
            } else if ( mode == PencilModeEnum.Off ) {
                cMenuPianoFixedOff.setSelected( true );
            }
            cMenuPianoFixedTriplet.setSelected( mPencilMode.isTriplet() );
            cMenuPianoFixedDotted.setSelected( mPencilMode.isDot() );
        }

        public void clearTempWave()
        {
            String tmppath = fsys.combine( AppManager.getCadenciiTempDir(), AppManager.getID() );
            if ( !fsys.isDirectoryExists( tmppath ) ) {
                return;
            }

            // 今回このPCが起動されるよりも以前に,Cadenciiが残したデータを削除する
            //TODO: システムカウンタは約49日でリセットされてしまい,厳密には実装できないようなので,保留.

            // このFormMainのインスタンスが使用したデータを消去する
            for ( int i = 1; i <= 16; i++ ) {
                String file = fsys.combine( tmppath, i + ".wav" );
                if ( fsys.isFileExists( file ) ) {
                    for ( int error = 0; error < 100; error++ ) {
                        try {
                            PortUtil.deleteFile( file );
                            break;
                        } catch ( Exception ex ) {
                            Logger.write( typeof( FormMain ) + ".clearTempWave; ex=" + ex + "\n" );
#if !JAVA
#if DEBUG
                            org.kbinani.debug.push_log( "FormMain+ClearTempWave()" );
                            org.kbinani.debug.push_log( "    ex=" + ex.ToString() );
                            org.kbinani.debug.push_log( "    error_count=" + error );
#endif
#endif

#if JAVA
                            try{
                                Thread.sleep( 100 );
                            }catch( Exception ex2 ){
                                Logger.write( typeof( FormMain ) + ".clearTempWave; ex=" + ex2 + "\n" );
                            }
#else
                            Thread.Sleep( 100 );
#endif
                        }
                    }
                }
            }
            String whd = fsys.combine( tmppath, UtauWaveGenerator.FILEBASE + ".whd" );
            if ( fsys.isFileExists( whd ) ) {
                try {
                    PortUtil.deleteFile( whd );
                } catch ( Exception ex ) {
                    Logger.write( typeof( FormMain ) + ".clearTempWave; ex=" + ex + "\n" );
                }
            }
            String dat = fsys.combine( tmppath, UtauWaveGenerator.FILEBASE + ".dat" );
            if ( fsys.isFileExists( dat ) ) {
                try {
                    PortUtil.deleteFile( dat );
                } catch ( Exception ex ) {
                    Logger.write( typeof( FormMain ) + ".clearTempWave; ex=" + ex + "\n" );
                }
            }
        }

        /// <summary>
        /// 鍵盤音キャッシュの中から指定したノートナンバーの音源を捜し、再生します。
        /// </summary>
        /// <param name="note">再生する音の高さを指定するノートナンバー</param>
04422         public void playPreviewSound( int note )
        {
            KeySoundPlayer.play( note );
        }

#if ENABLE_MOUSEHOVER
        public void MouseHoverEventGenerator( Object arg ) {
            int note = (int)arg;
            if ( AppManager.editorConfig.MouseHoverTime > 0 ) {
                Thread.Sleep( AppManager.editorConfig.MouseHoverTime );
            }
            KeySoundPlayer.play( note );
        }
#endif

        /// <summary>
        /// このコンポーネントの表示言語を、現在の言語設定に従って更新します。
        /// </summary>
04440         public void applyLanguage()
        {
            openXmlVsqDialog.clearChoosableFileFilter();
            try {
                openXmlVsqDialog.addFileFilter( _( "XML-VSQ Format(*.xvsq)|*.xvsq" ) );
                openXmlVsqDialog.addFileFilter( _( "All Files(*.*)|*.*" ) );
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".applyLanguage; ex=" + ex + "\n" );
                openXmlVsqDialog.addFileFilter( "XML-VSQ Format(*.xvsq)|*.xvsq" );
                openXmlVsqDialog.addFileFilter( "All Files(*.*)|*.*" );
            }

            saveXmlVsqDialog.clearChoosableFileFilter();
            try {
                saveXmlVsqDialog.addFileFilter( _( "XML-VSQ Format(*.xvsq)|*.xvsq" ) );
                saveXmlVsqDialog.addFileFilter( _( "All Files(*.*)|*.*" ) );
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".applyLanguage; ex=" + ex + "\n" );
                saveXmlVsqDialog.addFileFilter( "XML-VSQ Format(*.xvsq)|*.xvsq" );
                saveXmlVsqDialog.addFileFilter( "All Files(*.*)|*.*" );
            }

            openUstDialog.clearChoosableFileFilter();
            try {
                openUstDialog.addFileFilter( _( "UTAU Script Format(*.ust)|*.ust" ) );
                openUstDialog.addFileFilter( _( "All Files(*.*)|*.*" ) );
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".applyLanguage; ex=" + ex + "\n" );
                openUstDialog.addFileFilter( "UTAU Script Format(*.ust)|*.ust" );
                openUstDialog.addFileFilter( "All Files(*.*)|*.*" );
            }

            openMidiDialog.clearChoosableFileFilter();
            try {
                openMidiDialog.addFileFilter( _( "MIDI Format(*.mid)|*.mid" ) );
                openMidiDialog.addFileFilter( _( "VSQ Format(*.vsq)|*.vsq" ) );
                openMidiDialog.addFileFilter( _( "All Files(*.*)|*.*" ) );
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".applyLanguage; ex=" + ex + "\n" );
                openMidiDialog.addFileFilter( "MIDI Format(*.mid)|*.mid" );
                openMidiDialog.addFileFilter( "VSQ Format(*.vsq)|*.vsq" );
                openMidiDialog.addFileFilter( "All Files(*.*)|*.*" );
            }

            saveMidiDialog.clearChoosableFileFilter();
            try {
                saveMidiDialog.addFileFilter( _( "MIDI Format(*.mid)|*.mid" ) );
                saveMidiDialog.addFileFilter( _( "VSQ Format(*.vsq)|*.vsq" ) );
                saveMidiDialog.addFileFilter( _( "All Files(*.*)|*.*" ) );
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".applyLanguage; ex=" + ex + "\n" );
                saveMidiDialog.addFileFilter( "MIDI Format(*.mid)|*.mid" );
                saveMidiDialog.addFileFilter( "VSQ Format(*.vsq)|*.vsq" );
                saveMidiDialog.addFileFilter( "All Files(*.*)|*.*" );
            }

            openWaveDialog.clearChoosableFileFilter();
            try {
                openWaveDialog.addFileFilter( _( "Wave File(*.wav)|*.wav" ) );
                openWaveDialog.addFileFilter( _( "All Files(*.*)|*.*" ) );
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".applyLanguage; ex=" + ex + "\n" );
                openWaveDialog.addFileFilter( "Wave File(*.wav)|*.wav" );
                openWaveDialog.addFileFilter( "All Files(*.*)|*.*" );
            }

#if !JAVA
            stripLblGameCtrlMode.setToolTipText( _( "Game controler" ) );
#endif

#if JAVA
            updateGameControlerStatus( this, new EventArgs() );
#else
            this.Invoke( new BEventHandler( updateGameControlerStatus ) );
#endif

#if JAVA
            stripBtnPointer.setText( _( "Pointer" ) );
            stripBtnPointer.setToolTipText( _( "Pointer" ) );
            stripBtnPencil.setText( _( "Pencil" ) );
            stripBtnPencil.setToolTipText( _( "Pencil" ) );
            stripBtnLine.setText( _( "Line" ) );
            stripBtnLine.setToolTipText( _( "Line" ) );
            stripBtnEraser.setText( _( "Eraser" ) );
            stripBtnEraser.setToolTipText( _( "Eraser" ) );
            //stripBtnCurve.setText( _( "Curve" ) );
            stripBtnCurve.setToolTipText( _( "Curve" ) );
            //stripBtnGrid.setText( _( "Grid" ) );
            stripBtnGrid.setToolTipText( _( "Grid" ) );
            if ( AppManager.isPlaying() ) {
                stripBtnPlay.setText( _( "Stop" ) );
            } else {
                stripBtnPlay.setText( _( "Play" ) );
            }
#else
            stripBtnPointer.Text = _( "Pointer" );
            stripBtnPointer.ToolTipText = _( "Pointer" );
            stripBtnPencil.Text = _( "Pencil" );
            stripBtnPencil.ToolTipText = _( "Pencil" );
            stripBtnLine.Text = _( "Line" );
            stripBtnLine.ToolTipText = _( "Line" );
            stripBtnEraser.Text = _( "Eraser" );
            stripBtnEraser.ToolTipText = _( "Eraser" );
            stripBtnCurve.Text = _( "Curve" );
            stripBtnCurve.ToolTipText = _( "Curve" );
            stripBtnGrid.Text = _( "Grid" );
            stripBtnGrid.ToolTipText = _( "Grid" );
            if ( AppManager.isPlaying() ) {
                stripBtnPlay.Text = _( "Stop" );
            } else {
                stripBtnPlay.Text = _( "Play" );
            }
#endif

#if !JAVA
            stripBtnMoveTop.ToolTipText = _( "Move to beginning measure" );
            stripBtnMoveEnd.ToolTipText = _( "Move to end measure" );
            stripBtnForward.ToolTipText = _( "Move forward" );
            stripBtnRewind.ToolTipText = _( "Move backwared" );
            stripBtnLoop.ToolTipText = _( "Repeat" );
            stripBtnScroll.ToolTipText = _( "Auto scroll" );
#endif

            #region main menu
            menuFile.setText( _( "File" ) );
            menuFile.setMnemonic( KeyEvent.VK_F );
            menuFileNew.setText( _( "New" ) );
            menuFileNew.setMnemonic( KeyEvent.VK_N );
            menuFileOpen.setText( _( "Open" ) );
            menuFileOpen.setMnemonic( KeyEvent.VK_O );
            menuFileOpenVsq.setText( _( "Open VSQ/Vocaloid MIDI" ) );
            menuFileOpenVsq.setMnemonic( KeyEvent.VK_V );
            menuFileOpenUst.setText( _( "Open UTAU project file" ) );
            menuFileOpenUst.setMnemonic( KeyEvent.VK_U );
            menuFileSave.setText( _( "Save" ) );
            menuFileSave.setMnemonic( KeyEvent.VK_S );
            menuFileSaveNamed.setText( _( "Save as" ) );
            menuFileSaveNamed.setMnemonic( KeyEvent.VK_A );
            menuFileImport.setText( _( "Import" ) );
            menuFileImport.setMnemonic( KeyEvent.VK_I );
            menuFileImportVsq.setText( _( "VSQ / Vocaloid Midi" ) );
            menuFileExport.setText( _( "Export" ) );
            menuFileExport.setMnemonic( KeyEvent.VK_E );
            menuFileExportWave.setText( _( "WAVE" ) );
            menuFileExportParaWave.setText( _( "Serial numbered WAVEs" ) );
            menuFileExportUst.setText( _( "UTAU project file" ) );
            menuFileExportVxt.setText( _( "Metatext for vConnect" ) );
            menuFileRecent.setText( _( "Open Recent" ) );
            menuFileRecent.setMnemonic( KeyEvent.VK_R );
            menuFileRecentClear.setText( _( "Clear Menu" ) );
            menuFileQuit.setText( _( "Quit" ) );
            menuFileQuit.setMnemonic( KeyEvent.VK_Q );

            menuEdit.setText( _( "Edit" ) );
            menuEdit.setMnemonic( KeyEvent.VK_E );
            menuEditUndo.setText( _( "Undo" ) );
            menuEditUndo.setMnemonic( KeyEvent.VK_U );
            menuEditRedo.setText( _( "Redo" ) );
            menuEditRedo.setMnemonic( KeyEvent.VK_R );
            menuEditCut.setText( _( "Cut" ) );
            menuEditCut.setMnemonic( KeyEvent.VK_T );
            menuEditCopy.setText( _( "Copy" ) );
            menuEditCopy.setMnemonic( KeyEvent.VK_C );
            menuEditPaste.setText( _( "Paste" ) );
            menuEditPaste.setMnemonic( KeyEvent.VK_P );
            menuEditDelete.setText( _( "Delete" ) );
            menuEditDelete.setMnemonic( KeyEvent.VK_D );
            menuEditAutoNormalizeMode.setText( _( "Auto normalize mode" ) );
            menuEditAutoNormalizeMode.setMnemonic( KeyEvent.VK_N );
            menuEditSelectAll.setText( _( "Select All" ) );
            menuEditSelectAll.setMnemonic( KeyEvent.VK_A );
            menuEditSelectAllEvents.setText( _( "Select all events" ) );
            menuEditSelectAllEvents.setMnemonic( KeyEvent.VK_E );

            menuVisual.setText( _( "View" ) );
            menuVisual.setMnemonic( KeyEvent.VK_V );
            menuVisualControlTrack.setText( _( "Control track" ) );
            menuVisualControlTrack.setMnemonic( KeyEvent.VK_C );
            menuVisualMixer.setText( _( "Mixer" ) );
            menuVisualMixer.setMnemonic( KeyEvent.VK_X );
            menuVisualWaveform.setText( _( "Waveform" ) );
            menuVisualWaveform.setMnemonic( KeyEvent.VK_W );
            menuVisualProperty.setText( _( "Property window" ) );
            menuVisualOverview.setText( _( "Navigation" ) );
            menuVisualOverview.setMnemonic( KeyEvent.VK_V );
            menuVisualGridline.setText( _( "Grid line" ) );
            menuVisualGridline.setMnemonic( KeyEvent.VK_G );
            menuVisualStartMarker.setText( _( "Start marker" ) );
            menuVisualStartMarker.setMnemonic( KeyEvent.VK_S );
            menuVisualEndMarker.setText( _( "End marker" ) );
            menuVisualEndMarker.setMnemonic( KeyEvent.VK_E );
            menuVisualLyrics.setText( _( "Lyrics/Phoneme" ) );
            menuVisualLyrics.setMnemonic( KeyEvent.VK_L );
            menuVisualNoteProperty.setText( _( "Note expression/vibrato" ) );
            menuVisualNoteProperty.setMnemonic( KeyEvent.VK_N );
            menuVisualPitchLine.setText( _( "Pitch line" ) );
            menuVisualPitchLine.setMnemonic( KeyEvent.VK_P );
            menuVisualPluginUi.setText( _( "VSTi plugin UI" ) );
            menuVisualPluginUi.setMnemonic( KeyEvent.VK_U );
            menuVisualIconPalette.setText( _( "Icon palette" ) );
            menuVisualIconPalette.setMnemonic( KeyEvent.VK_I );

            menuJob.setText( _( "Job" ) );
            menuJob.setMnemonic( KeyEvent.VK_J );
            menuJobNormalize.setText( _( "Normalize notes" ) );
            menuJobNormalize.setMnemonic( KeyEvent.VK_N );
            menuJobInsertBar.setText( _( "Insert bars" ) );
            menuJobInsertBar.setMnemonic( KeyEvent.VK_I );
            menuJobDeleteBar.setText( _( "Delete bars" ) );
            menuJobDeleteBar.setMnemonic( KeyEvent.VK_D );
            menuJobRandomize.setText( _( "Randomize" ) );
            menuJobRandomize.setMnemonic( KeyEvent.VK_R );
            menuJobConnect.setText( _( "Connect notes" ) );
            menuJobConnect.setMnemonic( KeyEvent.VK_C );
            menuJobLyric.setText( _( "Insert lyrics" ) );
            menuJobLyric.setMnemonic( KeyEvent.VK_L );

            menuTrack.setText( _( "Track" ) );
            menuTrack.setMnemonic( KeyEvent.VK_T );
            menuTrackOn.setText( _( "Track on" ) );
            menuTrackOn.setMnemonic( KeyEvent.VK_K );
            menuTrackAdd.setText( _( "Add track" ) );
            menuTrackAdd.setMnemonic( KeyEvent.VK_A );
            menuTrackCopy.setText( _( "Copy track" ) );
            menuTrackCopy.setMnemonic( KeyEvent.VK_C );
            menuTrackChangeName.setText( _( "Rename track" ) );
            menuTrackDelete.setText( _( "Delete track" ) );
            menuTrackDelete.setMnemonic( KeyEvent.VK_D );
            menuTrackRenderCurrent.setText( _( "Render current track" ) );
            menuTrackRenderCurrent.setMnemonic( KeyEvent.VK_T );
            menuTrackRenderAll.setText( _( "Render all tracks" ) );
            menuTrackRenderAll.setMnemonic( KeyEvent.VK_S );
            menuTrackOverlay.setText( _( "Overlay" ) );
            menuTrackOverlay.setMnemonic( KeyEvent.VK_O );
            menuTrackRenderer.setText( _( "Renderer" ) );
            menuTrackRenderer.setMnemonic( KeyEvent.VK_R );
            menuTrackRendererVOCALOID1.setMnemonic( KeyEvent.VK_1 );
            menuTrackRendererVOCALOID2.setMnemonic( KeyEvent.VK_3 );
            menuTrackRendererUtau.setMnemonic( KeyEvent.VK_4 );
            menuTrackRendererVCNT.setMnemonic( KeyEvent.VK_5 );
            menuTrackRendererAquesTone.setMnemonic( KeyEvent.VK_6 );

            menuLyric.setText( _( "Lyrics" ) );
            menuLyric.setMnemonic( KeyEvent.VK_L );
            menuLyricExpressionProperty.setText( _( "Note expression property" ) );
            menuLyricExpressionProperty.setMnemonic( KeyEvent.VK_E );
            menuLyricVibratoProperty.setText( _( "Note vibrato property" ) );
            menuLyricVibratoProperty.setMnemonic( KeyEvent.VK_V );
            menuLyricApplyUtauParameters.setText( _( "Apply UTAU Parameters" ) );
            menuLyricApplyUtauParameters.setMnemonic( KeyEvent.VK_A );
            menuLyricPhonemeTransformation.setText( _( "Phoneme transformation" ) );
            menuLyricPhonemeTransformation.setMnemonic( KeyEvent.VK_T );
            menuLyricDictionary.setText( _( "User word dictionary" ) );
            menuLyricDictionary.setMnemonic( KeyEvent.VK_C );
            menuLyricCopyVibratoToPreset.setText( _( "Copy vibrato config to preset" ) );
            menuLyricCopyVibratoToPreset.setMnemonic( KeyEvent.VK_P );

            menuScript.setText( _( "Script" ) );
            menuScript.setMnemonic( KeyEvent.VK_C );
            menuScriptUpdate.setText( _( "Update script list" ) );
            menuScriptUpdate.setMnemonic( KeyEvent.VK_U );

            menuSetting.setText( _( "Setting" ) );
            menuSetting.setMnemonic( KeyEvent.VK_S );
            menuSettingPreference.setText( _( "Preference" ) );
            menuSettingPreference.setMnemonic( KeyEvent.VK_P );
            menuSettingGameControler.setText( _( "Game controler" ) );
            menuSettingGameControler.setMnemonic( KeyEvent.VK_G );
            menuSettingGameControlerLoad.setText( _( "Load" ) );
            menuSettingGameControlerLoad.setMnemonic( KeyEvent.VK_L );
            menuSettingGameControlerRemove.setText( _( "Remove" ) );
            menuSettingGameControlerRemove.setMnemonic( KeyEvent.VK_R );
            menuSettingGameControlerSetting.setText( _( "Setting" ) );
            menuSettingGameControlerSetting.setMnemonic( KeyEvent.VK_S );
            menuSettingSequence.setText( _( "Sequence config" ) );
            menuSettingSequence.setMnemonic( KeyEvent.VK_S );
            menuSettingShortcut.setText( _( "Shortcut key" ) );
            menuSettingShortcut.setMnemonic( KeyEvent.VK_K );
            menuSettingDefaultSingerStyle.setText( _( "Singing style defaults" ) );
            menuSettingDefaultSingerStyle.setMnemonic( KeyEvent.VK_D );
            menuSettingPositionQuantize.setText( _( "Quantize" ) );
            menuSettingPositionQuantize.setMnemonic( KeyEvent.VK_Q );
            menuSettingPositionQuantizeOff.setText( _( "Off" ) );
            menuSettingPositionQuantizeTriplet.setText( _( "Triplet" ) );
            //menuSettingSingerProperty.setText( _( "Singer Properties" ) );
            //menuSettingSingerProperty.setMnemonic( KeyEvent.VK_S );
            menuSettingPaletteTool.setText( _( "Palette Tool" ) );
            menuSettingPaletteTool.setMnemonic( KeyEvent.VK_T );
            menuSettingVibratoPreset.setText( _( "Vibrato preset" ) );
            menuSettingVibratoPreset.setMnemonic( KeyEvent.VK_V );

#if JAVA
            menuWindow.setText( _( "Window" ) );
            menuWindowMinimize.setText( _( "Minimize" ) );
#endif

            menuHelp.setText( _( "Help" ) );
            menuHelp.setMnemonic( KeyEvent.VK_H );
            menuHelpLog.setText( _( "Log" ) );
            menuHelpLog.setMnemonic( KeyEvent.VK_L );
            menuHelpLogSwitch.setText( Logger.isEnabled() ? _( "Disable" ) : _( "Enable" ) );
            menuHelpLogSwitch.setMnemonic( KeyEvent.VK_L );
            menuHelpLogOpen.setText( _( "Open" ) );
            menuHelpLogOpen.setMnemonic( KeyEvent.VK_O );
            menuHelpAbout.setText( _( "About Cadencii" ) );
            menuHelpAbout.setMnemonic( KeyEvent.VK_A );
            menuHelpManual.setText( _( "Manual" ) + " (PDF)" );

            menuHiddenCopy.setText( _( "Copy" ) );
            menuHiddenCut.setText( _( "Cut" ) );
            menuHiddenEditFlipToolPointerEraser.setText( _( "Chagne tool pointer / eraser" ) );
            menuHiddenEditFlipToolPointerPencil.setText( _( "Change tool pointer / pencil" ) );
            menuHiddenEditLyric.setText( _( "Start lyric input" ) );
            menuHiddenGoToEndMarker.setText( _( "GoTo end marker" ) );
            menuHiddenGoToStartMarker.setText( _( "Goto start marker" ) );
            menuHiddenLengthen.setText( _( "Lengthen" ) );
            menuHiddenMoveDown.setText( _( "Move down" ) );
            menuHiddenMoveLeft.setText( _( "Move left" ) );
            menuHiddenMoveRight.setText( _( "Move right" ) );
            menuHiddenMoveUp.setText( _( "Move up" ) );
            menuHiddenPaste.setText( _( "Paste" ) );
            menuHiddenPlayFromStartMarker.setText( _( "Play from start marker" ) );
            menuHiddenSelectBackward.setText( _( "Select backward" ) );
            menuHiddenSelectForward.setText( _( "Select forward" ) );
            menuHiddenShorten.setText( _( "Shorten" ) );
            menuHiddenTrackBack.setText( _( "Previous track" ) );
            menuHiddenTrackNext.setText( _( "Next track" ) );
            menuHiddenVisualBackwardParameter.setText( _( "Previous control curve" ) );
            menuHiddenVisualForwardParameter.setText( _( "Next control curve" ) );
            menuHiddenFlipCurveOnPianorollMode.setText( _( "Change pitch drawing mode" ) );
            #endregion

            #region cMenuPiano
            cMenuPianoPointer.setText( _( "Arrow" ) );
            cMenuPianoPointer.setMnemonic( KeyEvent.VK_A );
            cMenuPianoPencil.setText( _( "Pencil" ) );
            cMenuPianoPencil.setMnemonic( KeyEvent.VK_W );
            cMenuPianoEraser.setText( _( "Eraser" ) );
            cMenuPianoEraser.setMnemonic( KeyEvent.VK_E );
            cMenuPianoPaletteTool.setText( _( "Palette Tool" ) );

            cMenuPianoCurve.setText( _( "Curve" ) );
            cMenuPianoCurve.setMnemonic( KeyEvent.VK_V );

            cMenuPianoFixed.setText( _( "Note Fixed Length" ) );
            cMenuPianoFixed.setMnemonic( KeyEvent.VK_N );
            cMenuPianoFixedTriplet.setText( _( "Triplet" ) );
            cMenuPianoFixedOff.setText( _( "Off" ) );
            cMenuPianoFixedDotted.setText( _( "Dot" ) );
            cMenuPianoQuantize.setText( _( "Quantize" ) );
            cMenuPianoQuantize.setMnemonic( KeyEvent.VK_Q );
            cMenuPianoQuantizeTriplet.setText( _( "Triplet" ) );
            cMenuPianoQuantizeOff.setText( _( "Off" ) );
            cMenuPianoGrid.setText( _( "Show/Hide Grid Line" ) );
            cMenuPianoGrid.setMnemonic( KeyEvent.VK_S );

            cMenuPianoUndo.setText( _( "Undo" ) );
            cMenuPianoUndo.setMnemonic( KeyEvent.VK_U );
            cMenuPianoRedo.setText( _( "Redo" ) );
            cMenuPianoRedo.setMnemonic( KeyEvent.VK_R );

            cMenuPianoCut.setText( _( "Cut" ) );
            cMenuPianoCut.setMnemonic( KeyEvent.VK_T );
            cMenuPianoPaste.setText( _( "Paste" ) );
            cMenuPianoPaste.setMnemonic( KeyEvent.VK_P );
            cMenuPianoCopy.setText( _( "Copy" ) );
            cMenuPianoCopy.setMnemonic( KeyEvent.VK_C );
            cMenuPianoDelete.setText( _( "Delete" ) );
            cMenuPianoDelete.setMnemonic( KeyEvent.VK_D );

            cMenuPianoSelectAll.setText( _( "Select All" ) );
            cMenuPianoSelectAll.setMnemonic( KeyEvent.VK_A );
            cMenuPianoSelectAllEvents.setText( _( "Select All Events" ) );
            cMenuPianoSelectAllEvents.setMnemonic( KeyEvent.VK_E );

            cMenuPianoExpressionProperty.setText( _( "Note Expression Property" ) );
            cMenuPianoExpressionProperty.setMnemonic( KeyEvent.VK_P );
            cMenuPianoVibratoProperty.setText( _( "Note Vibrato Property" ) );
            cMenuPianoImportLyric.setText( _( "Insert Lyrics" ) );
            cMenuPianoImportLyric.setMnemonic( KeyEvent.VK_P );
            #endregion

            #region cMenuTrackTab
            cMenuTrackTabTrackOn.setText( _( "Track On" ) );
            cMenuTrackTabTrackOn.setMnemonic( KeyEvent.VK_K );
            cMenuTrackTabAdd.setText( _( "Add Track" ) );
            cMenuTrackTabAdd.setMnemonic( KeyEvent.VK_A );
            cMenuTrackTabCopy.setText( _( "Copy Track" ) );
            cMenuTrackTabCopy.setMnemonic( KeyEvent.VK_C );
            cMenuTrackTabChangeName.setText( _( "Rename Track" ) );
            cMenuTrackTabDelete.setText( _( "Delete Track" ) );
            cMenuTrackTabDelete.setMnemonic( KeyEvent.VK_D );

            cMenuTrackTabRenderCurrent.setText( _( "Render Current Track" ) );
            cMenuTrackTabRenderCurrent.setMnemonic( KeyEvent.VK_T );
            cMenuTrackTabRenderAll.setText( _( "Render All Tracks" ) );
            cMenuTrackTabRenderAll.setMnemonic( KeyEvent.VK_S );
            cMenuTrackTabOverlay.setText( _( "Overlay" ) );
            cMenuTrackTabOverlay.setMnemonic( KeyEvent.VK_O );
            cMenuTrackTabRenderer.setText( _( "Renderer" ) );
            cMenuTrackTabRenderer.setMnemonic( KeyEvent.VK_R );
            #endregion

            #region cMenuTrackSelector
            cMenuTrackSelectorPointer.setText( _( "Arrow" ) );
            cMenuTrackSelectorPointer.setMnemonic( KeyEvent.VK_A );
            cMenuTrackSelectorPencil.setText( _( "Pencil" ) );
            cMenuTrackSelectorPencil.setMnemonic( KeyEvent.VK_W );
            cMenuTrackSelectorLine.setText( _( "Line" ) );
            cMenuTrackSelectorLine.setMnemonic( KeyEvent.VK_L );
            cMenuTrackSelectorEraser.setText( _( "Eraser" ) );
            cMenuTrackSelectorEraser.setMnemonic( KeyEvent.VK_E );
            cMenuTrackSelectorPaletteTool.setText( _( "Palette Tool" ) );

            cMenuTrackSelectorCurve.setText( _( "Curve" ) );
            cMenuTrackSelectorCurve.setMnemonic( KeyEvent.VK_V );

            cMenuTrackSelectorUndo.setText( _( "Undo" ) );
            cMenuTrackSelectorUndo.setMnemonic( KeyEvent.VK_U );
            cMenuTrackSelectorRedo.setText( _( "Redo" ) );
            cMenuTrackSelectorRedo.setMnemonic( KeyEvent.VK_R );

            cMenuTrackSelectorCut.setText( _( "Cut" ) );
            cMenuTrackSelectorCut.setMnemonic( KeyEvent.VK_T );
            cMenuTrackSelectorCopy.setText( _( "Copy" ) );
            cMenuTrackSelectorCopy.setMnemonic( KeyEvent.VK_C );
            cMenuTrackSelectorPaste.setText( _( "Paste" ) );
            cMenuTrackSelectorPaste.setMnemonic( KeyEvent.VK_P );
            cMenuTrackSelectorDelete.setText( _( "Delete" ) );
            cMenuTrackSelectorDelete.setMnemonic( KeyEvent.VK_D );
            cMenuTrackSelectorDeleteBezier.setText( _( "Delete Bezier Point" ) );
            cMenuTrackSelectorDeleteBezier.setMnemonic( KeyEvent.VK_B );

            cMenuTrackSelectorSelectAll.setText( _( "Select All Events" ) );
            cMenuTrackSelectorSelectAll.setMnemonic( KeyEvent.VK_E );
            #endregion

            #region cMenuPositionIndicator
            cMenuPositionIndicatorStartMarker.setText( _( "Set start marker" ) );
            cMenuPositionIndicatorEndMarker.setText( _( "Set end marker" ) );
            #endregion

#if !JAVA
            stripLblGameCtrlMode.setToolTipText( _( "Game Controler" ) );
#endif

            // Palette Tool
#if DEBUG
            AppManager.debugWriteLine( "FormMain#applyLanguage; Messaging.Language=" + Messaging.getLanguage() );
#endif
#if ENABLE_SCRIPT
            int count = toolBarTool.Buttons.Count;// toolStripTool.getComponentCount();
            for ( int i = 0; i < count; i++ ) {
                Object tsi = toolBarTool.Buttons[i];// toolStripTool.getComponentAtIndex( i );
                if ( tsi is System.Windows.Forms.ToolBarButton ) {
                    System.Windows.Forms.ToolBarButton tsb = (System.Windows.Forms.ToolBarButton)tsi;
                    if ( tsb.Style == System.Windows.Forms.ToolBarButtonStyle.ToggleButton && tsb.Tag != null && tsb.Tag is String ) {
                        String id = (String)tsb.Tag;
                        if ( PaletteToolServer.loadedTools.containsKey( id ) ) {
                            IPaletteTool ipt = (IPaletteTool)PaletteToolServer.loadedTools.get( id );
                            tsb.Text = ipt.getName( Messaging.getLanguage() );
                            tsb.ToolTipText = ipt.getDescription( Messaging.getLanguage() );
                        }
                    }
                }
            }

            foreach ( MenuElement tsi in cMenuPianoPaletteTool.getSubElements() ) {
                if ( tsi is BMenuItem ) {
                    BMenuItem tsmi = (BMenuItem)tsi;
                    if ( tsmi.getTag() != null && tsmi.getTag() is String ) {
                        String id = (String)tsmi.getTag();
                        if ( PaletteToolServer.loadedTools.containsKey( id ) ) {
                            IPaletteTool ipt = (IPaletteTool)PaletteToolServer.loadedTools.get( id );
                            tsmi.setText( ipt.getName( Messaging.getLanguage() ) );
                            tsmi.setToolTipText( ipt.getDescription( Messaging.getLanguage() ) );
                        }
                    }
                }
            }

            foreach ( MenuElement tsi in cMenuTrackSelectorPaletteTool.getSubElements() ) {
                if ( tsi is BMenuItem ) {
                    BMenuItem tsmi = (BMenuItem)tsi;
                    if ( tsmi.getTag() != null && tsmi.getTag() is String ) {
                        String id = (String)tsmi.getTag();
                        if ( PaletteToolServer.loadedTools.containsKey( id ) ) {
                            IPaletteTool ipt = (IPaletteTool)PaletteToolServer.loadedTools.get( id );
                            tsmi.setText( ipt.getName( Messaging.getLanguage() ) );
                            tsmi.setToolTipText( ipt.getDescription( Messaging.getLanguage() ) );
                        }
                    }
                }
            }

            foreach ( MenuElement tsi in menuSettingPaletteTool.getSubElements() ) {
                if ( tsi is BMenuItem ) {
                    BMenuItem tsmi = (BMenuItem)tsi;
                    if ( tsmi.getTag() != null && tsmi.getTag() is String ) {
                        String id = (String)tsmi.getTag();
                        if ( PaletteToolServer.loadedTools.containsKey( id ) ) {
                            IPaletteTool ipt = (IPaletteTool)PaletteToolServer.loadedTools.get( id );
                            tsmi.setText( ipt.getName( Messaging.getLanguage() ) );
                        }
                    }
                }
            }

            for ( Iterator<String> itr = PaletteToolServer.loadedTools.keySet().iterator(); itr.hasNext(); ) {
                String id = (String)itr.next();
                IPaletteTool ipt = (IPaletteTool)PaletteToolServer.loadedTools.get( id );
                ipt.applyLanguage( Messaging.getLanguage() );
            }
#endif
        }

        /// <summary>
        /// 歌詞の流し込みダイアログを開き,選択された音符を起点に歌詞を流し込みます
        /// </summary>
04959         public void importLyric()
        {
            int start = 0;
            int selected = AppManager.getSelected();
            VsqFileEx vsq = AppManager.getVsqFile();
            VsqTrack vsq_track = vsq.Track.get( selected );
            int selectedid = AppManager.itemSelection.getLastEvent().original.InternalID;
            int numEvents = vsq_track.getEventCount();
            for ( int i = 0; i < numEvents; i++ ) {
                if ( selectedid == vsq_track.getEvent( i ).InternalID ) {
                    start = i;
                    break;
                }
            }
            int count = vsq_track.getEventCount() - 1 - start + 1;
            try {
                if ( mDialogImportLyric == null ) {
                    mDialogImportLyric = new FormImportLyric( count );
                } else {
                    mDialogImportLyric.setMaxNotes( count );
                }
                mDialogImportLyric.setLocation( getFormPreferedLocation( mDialogImportLyric ) );
                BDialogResult dr = AppManager.showModalDialog( mDialogImportLyric, this );
                if ( dr == BDialogResult.OK ) {
                    String[] phrases = mDialogImportLyric.getLetters();
#if DEBUG
                    foreach ( String s in phrases ) {
                        sout.println( "FormMain#importLyric; phrases; s=" + s );
                    }
#endif
                    int min = Math.Min( count, phrases.Length );
                    Vector<String> new_phrases = new Vector<String>();
                    Vector<String> new_symbols = new Vector<String>();
                    for ( int i = 0; i < phrases.Length; i++ ) {
                        SymbolTableEntry entry = SymbolTable.attatch( phrases[i] );
                        if ( new_phrases.size() + 1 > count ) {
                            break;
                        }
                        if ( entry == null ) {
                            new_phrases.add( phrases[i] );
                            new_symbols.add( "a" );
                        } else {
                            if ( entry.Word.IndexOf( '-' ) >= 0 ) {
                                // 分節に分割する必要がある
                                String[] spl = PortUtil.splitString( entry.Word, '\t' );
                                if ( new_phrases.size() + spl.Length > count ) {
                                    // 分節の全部を分割すると制限個数を超えてしまう
                                    // 分割せずにハイフンを付けたまま登録
                                    new_phrases.add( entry.Word.Replace( "\t", "" ) );
                                    new_symbols.add( entry.getSymbol() );
                                } else {
                                    String[] spl_symbol = PortUtil.splitString( entry.getRawSymbol(), '\t' );
                                    for ( int j = 0; j < spl.Length; j++ ) {
                                        new_phrases.add( spl[j] );
                                        new_symbols.add( spl_symbol[j] );
                                    }
                                }
                            } else {
                                // 分節に分割しない
                                new_phrases.add( phrases[i] );
                                new_symbols.add( entry.getSymbol() );
                            }
                        }
                    }
                    VsqEvent[] new_events = new VsqEvent[new_phrases.size()];
                    int indx = -1;
                    for ( Iterator<Integer> itr = vsq_track.indexIterator( IndexIteratorKind.NOTE ); itr.hasNext(); ) {
                        int index = itr.next();
                        if ( index < start ) {
                            continue;
                        }
                        indx++;
                        VsqEvent item = vsq_track.getEvent( index );
                        new_events[indx] = (VsqEvent)item.clone();
                        new_events[indx].ID.LyricHandle.L0.Phrase = new_phrases.get( indx );
                        new_events[indx].ID.LyricHandle.L0.setPhoneticSymbol( new_symbols.get( indx ) );
                        AppManager.applyUtauParameter( vsq_track, new_events[indx] );
                        if ( indx + 1 >= new_phrases.size() ) {
                            break;
                        }
                    }
                    CadenciiCommand run = new CadenciiCommand(
                        VsqCommand.generateCommandEventReplaceRange( selected, new_events ) );
                    AppManager.editHistory.register( vsq.executeCommand( run ) );
                    setEdited( true );
                    repaint();
                }
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".importLyric; ex=" + ex + "\n" );
            } finally {
                mDialogImportLyric.setVisible( false );
            }
        }

        /// <summary>
        /// 選択されている音符のビブラートを編集するためのダイアログを起動し、編集を行います。
        /// </summary>
05056         public void editNoteVibratoProperty()
        {
            SelectedEventEntry item = AppManager.itemSelection.getLastEvent();
            if ( item == null ) {
                return;
            }

            VsqEvent ev = item.original;
            int selected = AppManager.getSelected();
            VsqFileEx vsq = AppManager.getVsqFile();
            RendererKind kind = VsqFileEx.getTrackRendererKind( vsq.Track.get( selected ) );
            SynthesizerType type = SynthesizerType.VOCALOID2;
            if ( kind == RendererKind.VOCALOID1 ) {
                type = SynthesizerType.VOCALOID1;
            }
            FormVibratoConfig dlg = null;
            try {
                dlg = new FormVibratoConfig(
                    ev.ID.VibratoHandle,
                    ev.ID.getLength(),
                    AppManager.editorConfig.DefaultVibratoLength,
                    type,
                    AppManager.editorConfig.UseUserDefinedAutoVibratoType );
                dlg.setLocation( getFormPreferedLocation( dlg ) );
                BDialogResult dr = AppManager.showModalDialog( dlg, this );
                if ( dlg.getDialogResult() == BDialogResult.OK ) {
                    VsqEvent edited = (VsqEvent)ev.clone();
                    if ( dlg.getVibratoHandle() != null ) {
                        edited.ID.VibratoHandle = (VibratoHandle)dlg.getVibratoHandle().clone();
                        //edited.ID.VibratoHandle.setStartDepth( AppManager.editorConfig.DefaultVibratoDepth );
                        //edited.ID.VibratoHandle.setStartRate( AppManager.editorConfig.DefaultVibratoRate );
                        edited.ID.VibratoDelay = ev.ID.getLength() - dlg.getVibratoHandle().getLength();
                    } else {
                        edited.ID.VibratoHandle = null;
                    }
                    CadenciiCommand run = new CadenciiCommand(
                        VsqCommand.generateCommandEventChangeIDContaints( selected, ev.InternalID, edited.ID ) );
                    AppManager.editHistory.register( vsq.executeCommand( run ) );
                    setEdited( true );
                    refreshScreen();
                }
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".editNoteVibratoProperty; ex=" + ex + "\n" );
            } finally {
                if ( dlg != null ) {
                    try {
                        dlg.close();
                    } catch ( Exception ex2 ) {
                        Logger.write( typeof( FormMain ) + ".editNoteVibratoProperty; ex=" + ex2 + "\n" );
                    }
                }
            }
        }

        /// <summary>
        /// 選択されている音符の表情を編集するためのダイアログを起動し、編集を行います。
        /// </summary>
05113         public void editNoteExpressionProperty()
        {
            SelectedEventEntry item = AppManager.itemSelection.getLastEvent();
            if ( item == null ) {
                return;
            }

            VsqEvent ev = item.original;
            SynthesizerType type = SynthesizerType.VOCALOID2;
            int selected = AppManager.getSelected();
            VsqFileEx vsq = AppManager.getVsqFile();
            RendererKind kind = VsqFileEx.getTrackRendererKind( vsq.Track.get( selected ) );
            if ( kind == RendererKind.VOCALOID1 ) {
                type = SynthesizerType.VOCALOID1;
            }
            FormNoteExpressionConfig dlg = null;
            try {
                dlg = new FormNoteExpressionConfig( type, ev.ID.NoteHeadHandle );
                dlg.setPMBendDepth( ev.ID.PMBendDepth );
                dlg.setPMBendLength( ev.ID.PMBendLength );
                dlg.setPMbPortamentoUse( ev.ID.PMbPortamentoUse );
                dlg.setDEMdecGainRate( ev.ID.DEMdecGainRate );
                dlg.setDEMaccent( ev.ID.DEMaccent );

                dlg.setLocation( getFormPreferedLocation( dlg ) );
                BDialogResult dr = AppManager.showModalDialog( dlg, this );
                if ( dr == BDialogResult.OK ) {
                    VsqEvent edited = (VsqEvent)ev.clone();
                    edited.ID.PMBendDepth = dlg.getPMBendDepth();
                    edited.ID.PMBendLength = dlg.getPMBendLength();
                    edited.ID.PMbPortamentoUse = dlg.getPMbPortamentoUse();
                    edited.ID.DEMdecGainRate = dlg.getDEMdecGainRate();
                    edited.ID.DEMaccent = dlg.getDEMaccent();
                    edited.ID.NoteHeadHandle = dlg.getEditedNoteHeadHandle();
                    CadenciiCommand run = new CadenciiCommand(
                        VsqCommand.generateCommandEventChangeIDContaints( selected, ev.InternalID, edited.ID ) );
                    AppManager.editHistory.register( vsq.executeCommand( run ) );
                    setEdited( true );
                    refreshScreen();
                }
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".editNoteExpressionProperty; ex=" + ex + "\n" );
            } finally {
                if ( dlg != null ) {
                    try {
                        dlg.close();
                    } catch ( Exception ex2 ) {
                        Logger.write( typeof( FormMain ) + ".editNoteExpressionProperty; ex=" + ex2 + "\n" );
                    }
                }
            }
        }

        /// <summary>
        /// マウスのスクロールによって受け取ったスクロール幅から、実際に縦スクロールバーに渡す値(候補値)を計算します。
        /// </summary>
        /// <param name="delta"></param>
        /// <returns></returns>
05171         public int computeScrollValueFromWheelDelta( int delta )
        {
            double new_val = (double)hScroll.getValue() - delta * AppManager.editorConfig.WheelOrder / (5.0 * controller.getScaleX());
            if ( new_val < 0.0 ) {
                new_val = 0;
            }
            int max = hScroll.getMaximum() - hScroll.getVisibleAmount();
            int draft = (int)new_val;
            if ( draft > max ) {
                draft = max;
            } else if ( draft < hScroll.getMinimum() ) {
                draft = hScroll.getMinimum();
            }
            return draft;
        }

        #region 音符の編集関連
        public void selectAll()
        {

            AppManager.itemSelection.clearEvent();
            AppManager.itemSelection.clearTempo();
            AppManager.itemSelection.clearTimesig();
            AppManager.itemSelection.clearPoint();
            int min = int.MaxValue;
            int max = int.MinValue;
            int premeasure = AppManager.getVsqFile().getPreMeasureClocks();
            Vector<Integer> add_required = new Vector<Integer>();
            for ( Iterator<VsqEvent> itr = AppManager.getVsqFile().Track.get( AppManager.getSelected() ).getEventIterator(); itr.hasNext(); ) {
                VsqEvent ve = itr.next();
                if ( premeasure <= ve.Clock ) {
                    add_required.add( ve.InternalID );
                    min = Math.Min( min, ve.Clock );
                    max = Math.Max( max, ve.Clock + ve.ID.getLength() );
                }
            }
            if ( add_required.size() > 0 ) {
                AppManager.itemSelection.addEventAll( add_required );
            }
            foreach ( CurveType vct in Utility.CURVE_USAGE ) {
                if ( vct.isScalar() || vct.isAttachNote() ) {
                    continue;
                }
                VsqBPList target = AppManager.getVsqFile().Track.get( AppManager.getSelected() ).getCurve( vct.getName() );
                if ( target == null ) {
                    continue;
                }
                int count = target.size();
                if ( count >= 1 ) {
                    //int[] keys = target.getKeys();
                    int max_key = target.getKeyClock( count - 1 );
                    max = Math.Max( max, target.getValue( max_key ) );
                    for ( int i = 0; i < count; i++ ) {
                        int key = target.getKeyClock( i );
                        if ( premeasure <= key ) {
                            min = Math.Min( min, key );
                            break;
                        }
                    }
                }
            }
            if ( min < premeasure ) {
                min = premeasure;
            }
            if ( min < max ) {
                //int stdx = AppManager.startToDrawX;
                //min = xCoordFromClocks( min ) + stdx;
                //max = xCoordFromClocks( max ) + stdx;
                AppManager.mWholeSelectedInterval = new SelectedRegion( min );
                AppManager.mWholeSelectedInterval.setEnd( max );
                AppManager.setWholeSelectedIntervalEnabled( true );
            }
        }

        public void selectAllEvent()
        {
            AppManager.itemSelection.clearTempo();
            AppManager.itemSelection.clearTimesig();
            AppManager.itemSelection.clearEvent();
            AppManager.itemSelection.clearPoint();
            int selected = AppManager.getSelected();
            VsqFileEx vsq = AppManager.getVsqFile();
            VsqTrack vsq_track = vsq.Track.get( selected );
            int premeasureclock = vsq.getPreMeasureClocks();
            Vector<Integer> add_required = new Vector<Integer>();
            for ( Iterator<VsqEvent> itr = vsq_track.getEventIterator(); itr.hasNext(); ) {
                VsqEvent ev = itr.next();
                if ( ev.ID.type == VsqIDType.Anote && ev.Clock >= premeasureclock ) {
                    add_required.add( ev.InternalID );
                }
            }
            if ( add_required.size() > 0 ) {
                AppManager.itemSelection.addEventAll( add_required );
            }
            refreshScreen();
        }

        public void deleteEvent()
        {
#if DEBUG
            AppManager.debugWriteLine(
                "FormMain#deleteEvent(); AppManager.mInputTextBox.isEnabled()=" +
                AppManager.mInputTextBox.isEnabled() );
#endif

            if ( AppManager.mInputTextBox.isVisible() ) {
                return;
            }
#if ENABLE_PROPERTY
            if ( AppManager.propertyPanel.isEditing() ) {
                return;
            }
#endif

            int selected = AppManager.getSelected();
            VsqFileEx vsq = AppManager.getVsqFile();
            VsqTrack vsq_track = vsq.Track.get( selected );

            if ( AppManager.itemSelection.getEventCount() > 0 ) {
                Vector<Integer> ids = new Vector<Integer>();
                boolean contains_aicon = false;
                for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                    SelectedEventEntry ev = itr.next();
                    ids.add( ev.original.InternalID );
                    if ( ev.original.ID.type == VsqIDType.Aicon ) {
                        contains_aicon = true;
                    }
                }
                VsqCommand run = VsqCommand.generateCommandEventDeleteRange( selected, ids );
                if ( AppManager.isWholeSelectedIntervalEnabled() ) {
                    VsqFileEx work = (VsqFileEx)vsq.clone();
                    work.executeCommand( run );
                    int stdx = controller.getStartToDrawX();
                    int start_clock = AppManager.mWholeSelectedInterval.getStart();
                    int end_clock = AppManager.mWholeSelectedInterval.getEnd();
                    Vector<Vector<BPPair>> curves = new Vector<Vector<BPPair>>();
                    Vector<CurveType> types = new Vector<CurveType>();
                    VsqTrack work_vsq_track = work.Track.get( selected );
                    foreach ( CurveType vct in Utility.CURVE_USAGE ) {
                        if ( vct.isScalar() || vct.isAttachNote() ) {
                            continue;
                        }
                        VsqBPList work_curve = work_vsq_track.getCurve( vct.getName() );
                        Vector<BPPair> t = new Vector<BPPair>();
                        t.add( new BPPair( start_clock, work_curve.getValue( start_clock ) ) );
                        t.add( new BPPair( end_clock, work_curve.getValue( end_clock ) ) );
                        curves.add( t );
                        types.add( vct );
                    }
                    Vector<String> strs = new Vector<String>();
                    for ( int i = 0; i < types.size(); i++ ) {
                        strs.add( types.get( i ).getName() );
                    }
                    CadenciiCommand delete_curve = new CadenciiCommand(
                        VsqCommand.generateCommandTrackCurveEditRange( selected, strs, curves ) );
                    work.executeCommand( delete_curve );
                    if ( contains_aicon ) {
                        work.Track.get( selected ).reflectDynamics();
                    }
                    CadenciiCommand run2 = new CadenciiCommand( VsqCommand.generateCommandReplace( work ) );
                    AppManager.editHistory.register( vsq.executeCommand( run2 ) );
                    setEdited( true );
                } else {
                    CadenciiCommand run2 = null;
                    if ( contains_aicon ) {
                        VsqFileEx work = (VsqFileEx)vsq.clone();
                        work.executeCommand( run );
                        VsqTrack vsq_track_copied = work.Track.get( selected );
                        vsq_track_copied.reflectDynamics();
                        run2 = VsqFileEx.generateCommandTrackReplace( selected,
                                                                      vsq_track_copied,
                                                                      work.AttachedCurves.get( selected - 1 ) );
                    } else {
                        run2 = new CadenciiCommand( run );
                    }
                    AppManager.editHistory.register( vsq.executeCommand( run2 ) );
                    setEdited( true );
                    AppManager.itemSelection.clearEvent();
                }
                repaint();
            } else if ( AppManager.itemSelection.getTempoCount() > 0 ) {
                Vector<Integer> clocks = new Vector<Integer>();
                for ( Iterator<ValuePair<Integer, SelectedTempoEntry>> itr = AppManager.itemSelection.getTempoIterator(); itr.hasNext(); ) {
                    ValuePair<Integer, SelectedTempoEntry> item = itr.next();
                    if ( item.getKey() <= 0 ) {
                        String msg = _( "Cannot remove first symbol of track!" );
#if JAVA
                        statusLabel.setText( msg );
#else
                        statusLabel.Text = msg;
#endif
#if !JAVA
                        SystemSounds.Asterisk.Play();
#endif
                        return;
                    }
                    clocks.add( item.getKey() );
                }
                int[] dum = new int[clocks.size()];
                for ( int i = 0; i < dum.Length; i++ ) {
                    dum[i] = -1;
                }
                CadenciiCommand run = new CadenciiCommand(
                    VsqCommand.generateCommandUpdateTempoRange( PortUtil.convertIntArray( clocks.toArray( new Integer[] { } ) ),
                                                                PortUtil.convertIntArray( clocks.toArray( new Integer[] { } ) ),
                                                                dum ) );
                AppManager.editHistory.register( vsq.executeCommand( run ) );
                setEdited( true );
                AppManager.itemSelection.clearTempo();
                repaint();
            } else if ( AppManager.itemSelection.getTimesigCount() > 0 ) {
#if DEBUG
                AppManager.debugWriteLine( "    Timesig" );
#endif
                int[] barcounts = new int[AppManager.itemSelection.getTimesigCount()];
                int[] numerators = new int[AppManager.itemSelection.getTimesigCount()];
                int[] denominators = new int[AppManager.itemSelection.getTimesigCount()];
                int count = -1;
                for ( Iterator<ValuePair<Integer, SelectedTimesigEntry>> itr = AppManager.itemSelection.getTimesigIterator(); itr.hasNext(); ) {
                    ValuePair<Integer, SelectedTimesigEntry> item = itr.next();
                    int key = item.getKey();
                    SelectedTimesigEntry value = item.getValue();
                    count++;
                    barcounts[count] = key;
                    if ( key <= 0 ) {
                        String msg = "Cannot remove first symbol of track!";
#if JAVA
                        statusLabel.setText( _( msg ) );
#else
                        statusLabel.Text = _( msg );
#endif
#if !JAVA
                        SystemSounds.Asterisk.Play();
#endif
                        return;
                    }
                    numerators[count] = -1;
                    denominators[count] = -1;
                }
                CadenciiCommand run = new CadenciiCommand(
                    VsqCommand.generateCommandUpdateTimesigRange( barcounts, barcounts, numerators, denominators ) );
                AppManager.editHistory.register( vsq.executeCommand( run ) );
                setEdited( true );
                AppManager.itemSelection.clearTimesig();
                repaint();
            }
            if ( AppManager.itemSelection.getPointIDCount() > 0 ) {
#if DEBUG
                AppManager.debugWriteLine( "    Curve" );
#endif
                String curve;
                if ( !trackSelector.getSelectedCurve().isAttachNote() ) {
                    curve = trackSelector.getSelectedCurve().getName();
                    VsqBPList src = vsq_track.getCurve( curve );
                    VsqBPList list = (VsqBPList)src.clone();
                    Vector<Integer> remove_clock_queue = new Vector<Integer>();
                    int count = list.size();
                    for ( int i = 0; i < count; i++ ) {
                        VsqBPPair item = list.getElementB( i );
                        if ( AppManager.itemSelection.isPointContains( item.id ) ) {
                            remove_clock_queue.add( list.getKeyClock( i ) );
                        }
                    }
                    count = remove_clock_queue.size();
                    for ( int i = 0; i < count; i++ ) {
                        list.remove( remove_clock_queue.get( i ) );
                    }
                    CadenciiCommand run = new CadenciiCommand(
                        VsqCommand.generateCommandTrackCurveReplace( selected,
                                                                     trackSelector.getSelectedCurve().getName(),
                                                                     list ) );
                    AppManager.editHistory.register( vsq.executeCommand( run ) );
                    setEdited( true );
                } else {
                    //todo: FormMain+DeleteEvent; VibratoDepth, VibratoRateの場合
                }
                AppManager.itemSelection.clearPoint();
                refreshScreen();
            }
        }

        public void pasteEvent()
        {
            int clock = AppManager.getCurrentClock();
            int unit = AppManager.getPositionQuantizeClock();
            clock = doQuantize( clock, unit );

            VsqCommand add_event = null; // VsqEventを追加するコマンド

            ClipboardEntry ce = AppManager.clipboard.getCopiedItems();
            int copy_started_clock = ce.copyStartedClock;
            Vector<VsqEvent> copied_events = ce.events;
#if DEBUG
            sout.println( "FormMain#pasteEvent; copy_started_clock=" + copy_started_clock );
            sout.println( "FormMain#pasteEvent; copied_events.size()=" + copied_events.size() );
#endif
            if ( copied_events.size() != 0 ) {
                // VsqEventのペーストを行うコマンドを発行
                int dclock = clock - copy_started_clock;
                if ( clock >= AppManager.getVsqFile().getPreMeasureClocks() ) {
                    Vector<VsqEvent> paste = new Vector<VsqEvent>();
                    int count = copied_events.size();
                    for ( int i = 0; i < count; i++ ) {
                        VsqEvent item = (VsqEvent)copied_events.get( i ).clone();
                        item.Clock = copied_events.get( i ).Clock + dclock;
                        paste.add( item );
                    }
                    add_event = VsqCommand.generateCommandEventAddRange(
                        AppManager.getSelected(), paste.toArray( new VsqEvent[] { } ) );
                }
            }
            Vector<TempoTableEntry> copied_tempo = ce.tempo;
            if ( copied_tempo.size() != 0 ) {
                // テンポ変更の貼付けを実行
                int dclock = clock - copy_started_clock;
                int count = copied_tempo.size();
                int[] clocks = new int[count];
                int[] tempos = new int[count];
                for ( int i = 0; i < count; i++ ) {
                    TempoTableEntry item = copied_tempo.get( i );
                    clocks[i] = item.Clock + dclock;
                    tempos[i] = item.Tempo;
                }
                CadenciiCommand run = new CadenciiCommand(
                    VsqCommand.generateCommandUpdateTempoRange( clocks, clocks, tempos ) );
                AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                setEdited( true );
                refreshScreen();
                return;
            }
            Vector<TimeSigTableEntry> copied_timesig = ce.timesig;
            if ( copied_timesig.size() > 0 ) {
                // 拍子変更の貼付けを実行
                int bar_count = AppManager.getVsqFile().getBarCountFromClock( clock );
                int min_barcount = copied_timesig.get( 0 ).BarCount;
                for ( Iterator<TimeSigTableEntry> itr = copied_timesig.iterator(); itr.hasNext(); ) {
                    TimeSigTableEntry tste = itr.next();
                    min_barcount = Math.Min( min_barcount, tste.BarCount );
                }
                int dbarcount = bar_count - min_barcount;
                int count = copied_timesig.size();
                int[] barcounts = new int[count];
                int[] numerators = new int[count];
                int[] denominators = new int[count];
                for ( int i = 0; i < count; i++ ) {
                    TimeSigTableEntry item = copied_timesig.get( i );
                    barcounts[i] = item.BarCount + dbarcount;
                    numerators[i] = item.Numerator;
                    denominators[i] = item.Denominator;
                }
                CadenciiCommand run = new CadenciiCommand(
                    VsqCommand.generateCommandUpdateTimesigRange(
                        barcounts, barcounts, numerators, denominators ) );
                AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                setEdited( true );
                refreshScreen();
                return;
            }

            // BPPairの貼付け
            VsqCommand edit_bpcurve = null; // BPListを変更するコマンド
            TreeMap<CurveType, VsqBPList> copied_curve = ce.points;
#if DEBUG
            sout.println( "FormMain#pasteEvent; copied_curve.size()=" + copied_curve.size() );
#endif
            if ( copied_curve.size() > 0 ) {
                int dclock = clock - copy_started_clock;

                TreeMap<String, VsqBPList> work = new TreeMap<String, VsqBPList>();
                for ( Iterator<CurveType> itr = copied_curve.keySet().iterator(); itr.hasNext(); ) {
                    CurveType curve = itr.next();
                    VsqBPList list = copied_curve.get( curve );
#if DEBUG
                    AppManager.debugWriteLine( "FormMain#pasteEvent; curve=" + curve );
#endif
                    if ( curve.isScalar() ) {
                        continue;
                    }
                    if ( list.size() <= 0 ) {
                        continue;
                    }
                    if ( curve.isAttachNote() ) {
                        //todo: FormMain+PasteEvent; VibratoRate, VibratoDepthカーブのペースト処理
                    } else {
                        VsqBPList target = (VsqBPList)AppManager.getVsqFile().Track.get( AppManager.getSelected() ).getCurve( curve.getName() ).clone();
                        int count = list.size();
#if DEBUG
                        sout.println( "FormMain#pasteEvent; list.getCount()=" + count );
#endif
                        int min = list.getKeyClock( 0 ) + dclock;
                        int max = list.getKeyClock( count - 1 ) + dclock;
                        int valueAtEnd = target.getValue( max );
                        for ( int i = 0; i < target.size(); i++ ) {
                            int cl = target.getKeyClock( i );
                            if ( min <= cl && cl <= max ) {
                                target.removeElementAt( i );
                                i--;
                            }
                        }
                        int lastClock = min;
                        for ( int i = 0; i < count - 1; i++ ) {
                            lastClock = list.getKeyClock( i ) + dclock;
                            target.add( lastClock, list.getElementA( i ) );
                        }
                        // 最後のやつ
                        if ( lastClock < max - 1 ) {
                            target.add( max - 1, list.getElementA( count - 1 ) );
                        }
                        target.add( max, valueAtEnd );
                        if ( copied_curve.size() == 1 ) {
                            work.put( trackSelector.getSelectedCurve().getName(), target );
                        } else {
                            work.put( curve.getName(), target );
                        }
                    }
                }
#if DEBUG
                sout.println( "FormMain#pasteEvent; work.size()=" + work.size() );
#endif
                if ( work.size() > 0 ) {
                    String[] curves = new String[work.size()];
                    VsqBPList[] bplists = new VsqBPList[work.size()];
                    int count = -1;
                    for ( Iterator<String> itr = work.keySet().iterator(); itr.hasNext(); ) {
                        String s = itr.next();
                        count++;
                        curves[count] = s;
                        bplists[count] = work.get( s );
                    }
                    edit_bpcurve = VsqCommand.generateCommandTrackCurveReplaceRange( AppManager.getSelected(), curves, bplists );
                }
                AppManager.itemSelection.clearPoint();
            }

            // ベジエ曲線の貼付け
            CadenciiCommand edit_bezier = null;
            TreeMap<CurveType, Vector<BezierChain>> copied_bezier = ce.beziers;
#if DEBUG
            sout.println( "FormMain#pasteEvent; copied_bezier.size()=" + copied_bezier.size() );
#endif
            if ( copied_bezier.size() > 0 ) {
                int dclock = clock - copy_started_clock;
                BezierCurves attached_curve = (BezierCurves)AppManager.getVsqFile().AttachedCurves.get( AppManager.getSelected() - 1 ).clone();
                TreeMap<CurveType, Vector<BezierChain>> command_arg = new TreeMap<CurveType, Vector<BezierChain>>();
                for ( Iterator<CurveType> itr = copied_bezier.keySet().iterator(); itr.hasNext(); ) {
                    CurveType curve = itr.next();
                    if ( curve.isScalar() ) {
                        continue;
                    }
                    for ( Iterator<BezierChain> itr2 = copied_bezier.get( curve ).iterator(); itr2.hasNext(); ) {
                        BezierChain bc = itr2.next();
                        BezierChain bc_copy = (BezierChain)bc.clone();
                        for ( Iterator<BezierPoint> itr3 = bc_copy.points.iterator(); itr3.hasNext(); ) {
                            BezierPoint bp = itr3.next();
                            bp.setBase( new PointD( bp.getBase().getX() + dclock, bp.getBase().getY() ) );
                        }
                        attached_curve.mergeBezierChain( curve, bc_copy );
                    }
                    Vector<BezierChain> arg = new Vector<BezierChain>();
                    for ( Iterator<BezierChain> itr2 = attached_curve.get( curve ).iterator(); itr2.hasNext(); ) {
                        BezierChain bc = itr2.next();
                        arg.add( bc );
                    }
                    command_arg.put( curve, arg );
                }
                edit_bezier = VsqFileEx.generateCommandReplaceAttachedCurveRange( AppManager.getSelected(), command_arg );
            }

            int commands = 0;
            commands += (add_event != null) ? 1 : 0;
            commands += (edit_bpcurve != null) ? 1 : 0;
            commands += (edit_bezier != null) ? 1 : 0;

#if DEBUG
            AppManager.debugWriteLine( "FormMain#pasteEvent; commands=" + commands );
            AppManager.debugWriteLine( "FormMain#pasteEvent; (add_event != null)=" + (add_event != null) );
            AppManager.debugWriteLine( "FormMain#pasteEvent; (edit_bpcurve != null)=" + (edit_bpcurve != null) );
            AppManager.debugWriteLine( "FormMain#pasteEvent; (edit_bezier != null)=" + (edit_bezier != null) );
#endif
            if ( commands == 1 ) {
                if ( add_event != null ) {
                    CadenciiCommand run = new CadenciiCommand( add_event );
                    AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                } else if ( edit_bpcurve != null ) {
                    CadenciiCommand run = new CadenciiCommand( edit_bpcurve );
                    AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                } else if ( edit_bezier != null ) {
                    AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( edit_bezier ) );
                }
                AppManager.getVsqFile().updateTotalClocks();
                setEdited( true );
                refreshScreen();
            } else if ( commands > 1 ) {
                VsqFileEx work = (VsqFileEx)AppManager.getVsqFile().clone();
                if ( add_event != null ) {
                    work.executeCommand( add_event );
                }
                if ( edit_bezier != null ) {
                    work.executeCommand( edit_bezier );
                }
                if ( edit_bpcurve != null ) {
                    // edit_bpcurveのVsqCommandTypeはTrackEditCurveRangeしかありえない
                    work.executeCommand( edit_bpcurve );
                }
                CadenciiCommand run = VsqFileEx.generateCommandReplace( work );
                AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                AppManager.getVsqFile().updateTotalClocks();
                setEdited( true );
                refreshScreen();
            }
        }

        /// <summary>
        /// アイテムのコピーを行います
        /// </summary>
05686         public void copyEvent()
        {
#if DEBUG
            AppManager.debugWriteLine( "FormMain#copyEvent" );
#endif
            int min = int.MaxValue; // コピーされたアイテムの中で、最小の開始クロック

            if ( AppManager.isWholeSelectedIntervalEnabled() ) {
#if DEBUG
                sout.println( "FormMain#copyEvent; selected with CTRL key" );
#endif
                int stdx = controller.getStartToDrawX();
                int start_clock = AppManager.mWholeSelectedInterval.getStart();
                int end_clock = AppManager.mWholeSelectedInterval.getEnd();
                ClipboardEntry ce = new ClipboardEntry();
                ce.copyStartedClock = start_clock;
                ce.points = new TreeMap<CurveType, VsqBPList>();
                ce.beziers = new TreeMap<CurveType, Vector<BezierChain>>();
                for ( int i = 0; i < Utility.CURVE_USAGE.Length; i++ ) {
                    CurveType vct = Utility.CURVE_USAGE[i];
                    VsqBPList list = AppManager.getVsqFile().Track.get( AppManager.getSelected() ).getCurve( vct.getName() );
                    if ( list == null ) {
                        continue;
                    }
                    Vector<BezierChain> tmp_bezier = new Vector<BezierChain>();
                    copyCurveCor( AppManager.getSelected(),
                                  vct,
                                  start_clock,
                                  end_clock,
                                  tmp_bezier );
                    VsqBPList tmp_bplist = new VsqBPList( list.getName(), list.getDefault(), list.getMinimum(), list.getMaximum() );
                    int c = list.size();
                    for ( int j = 0; j < c; j++ ) {
                        int clock = list.getKeyClock( j );
                        if ( start_clock <= clock && clock <= end_clock ) {
                            tmp_bplist.add( clock, list.getElement( j ) );
                        } else if ( end_clock < clock ) {
                            break;
                        }
                    }
                    ce.beziers.put( vct, tmp_bezier );
                    ce.points.put( vct, tmp_bplist );
                }

                if ( AppManager.itemSelection.getEventCount() > 0 ) {
                    Vector<VsqEvent> list = new Vector<VsqEvent>();
                    for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                        SelectedEventEntry item = itr.next();
                        if ( item.original.ID.type == VsqIDType.Anote ) {
                            min = Math.Min( item.original.Clock, min );
                            list.add( (VsqEvent)item.original.clone() );
                        }
                    }
                    ce.events = list;
                }
                AppManager.clipboard.setClipboard( ce );
            } else if ( AppManager.itemSelection.getEventCount() > 0 ) {
                Vector<VsqEvent> list = new Vector<VsqEvent>();
                for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                    SelectedEventEntry item = itr.next();
                    min = Math.Min( item.original.Clock, min );
                    list.add( (VsqEvent)item.original.clone() );
                }
                AppManager.clipboard.setCopiedEvent( list, min );
            } else if ( AppManager.itemSelection.getTempoCount() > 0 ) {
                Vector<TempoTableEntry> list = new Vector<TempoTableEntry>();
                for ( Iterator<ValuePair<Integer, SelectedTempoEntry>> itr = AppManager.itemSelection.getTempoIterator(); itr.hasNext(); ) {
                    ValuePair<Integer, SelectedTempoEntry> item = itr.next();
                    int key = item.getKey();
                    SelectedTempoEntry value = item.getValue();
                    min = Math.Min( value.original.Clock, min );
                    list.add( (TempoTableEntry)value.original.clone() );
                }
                AppManager.clipboard.setCopiedTempo( list, min );
            } else if ( AppManager.itemSelection.getTimesigCount() > 0 ) {
                Vector<TimeSigTableEntry> list = new Vector<TimeSigTableEntry>();
                for ( Iterator<ValuePair<Integer, SelectedTimesigEntry>> itr = AppManager.itemSelection.getTimesigIterator(); itr.hasNext(); ) {
                    ValuePair<Integer, SelectedTimesigEntry> item = itr.next();
                    int key = item.getKey();
                    SelectedTimesigEntry value = item.getValue();
                    min = Math.Min( value.original.Clock, min );
                    list.add( (TimeSigTableEntry)value.original.clone() );
                }
                AppManager.clipboard.setCopiedTimesig( list, min );
            } else if ( AppManager.itemSelection.getPointIDCount() > 0 ) {
                ClipboardEntry ce = new ClipboardEntry();
                ce.points = new TreeMap<CurveType, VsqBPList>();
                ce.beziers = new TreeMap<CurveType, Vector<BezierChain>>();

                ValuePair<Integer, Integer> t = trackSelector.getSelectedRegion();
                int start = t.getKey();
                int end = t.getValue();
                ce.copyStartedClock = start;
                Vector<BezierChain> tmp_bezier = new Vector<BezierChain>();
                copyCurveCor( AppManager.getSelected(),
                              trackSelector.getSelectedCurve(),
                              start,
                              end,
                              tmp_bezier );
                if ( tmp_bezier.size() > 0 ) {
                    // ベジエ曲線が1個以上コピーされた場合
                    // 範囲内のデータ点を追加する
                    ce.beziers.put( trackSelector.getSelectedCurve(), tmp_bezier );
                    CurveType curve = trackSelector.getSelectedCurve();
                    VsqBPList list = AppManager.getVsqFile().Track.get( AppManager.getSelected() ).getCurve( curve.getName() );
                    if ( list != null ) {
                        VsqBPList tmp_bplist = new VsqBPList( list.getName(), list.getDefault(), list.getMinimum(), list.getMaximum() );
                        int c = list.size();
                        for ( int i = 0; i < c; i++ ) {
                            int clock = list.getKeyClock( i );
                            if ( start <= clock && clock <= end ) {
                                tmp_bplist.add( clock, list.getElement( i ) );
                            } else if ( end < clock ) {
                                break;
                            }
                        }
                        ce.points.put( curve, tmp_bplist );
                    }
                } else {
                    // ベジエ曲線がコピーされなかった場合
                    // AppManager.selectedPointIDIteratorの中身のみを選択
                    CurveType curve = trackSelector.getSelectedCurve();
                    VsqBPList list = AppManager.getVsqFile().Track.get( AppManager.getSelected() ).getCurve( curve.getName() );
                    if ( list != null ) {
                        VsqBPList tmp_bplist = new VsqBPList( curve.getName(), curve.getDefault(), curve.getMinimum(), curve.getMaximum() );
                        for ( Iterator<Long> itr = AppManager.itemSelection.getPointIDIterator(); itr.hasNext(); ) {
                            long id = itr.next();
                            VsqBPPairSearchContext cxt = list.findElement( id );
                            if ( cxt.index >= 0 ) {
                                tmp_bplist.add( cxt.clock, cxt.point.value );
                            }
                        }
                        if ( tmp_bplist.size() > 0 ) {
                            ce.copyStartedClock = tmp_bplist.getKeyClock( 0 );
                            ce.points.put( curve, tmp_bplist );
                        }
                    }
                }
                AppManager.clipboard.setClipboard( ce );
            }
        }

        public void cutEvent()
        {
            // まずコピー
            copyEvent();

            int track = AppManager.getSelected();

            // 選択されたノートイベントがあれば、まず、削除を行うコマンドを発行
            VsqCommand delete_event = null;
            boolean other_command_executed = false;
            if ( AppManager.itemSelection.getEventCount() > 0 ) {
                Vector<Integer> ids = new Vector<Integer>();
                for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                    SelectedEventEntry item = itr.next();
                    ids.add( item.original.InternalID );
                }
                delete_event = VsqCommand.generateCommandEventDeleteRange( AppManager.getSelected(), ids );
            }

            // Ctrlキーを押しながらドラッグしたか、そうでないかで分岐
            if ( AppManager.isWholeSelectedIntervalEnabled() || AppManager.itemSelection.getPointIDCount() > 0 ) {
                int stdx = controller.getStartToDrawX();
                int start_clock, end_clock;
                if ( AppManager.isWholeSelectedIntervalEnabled() ) {
                    start_clock = AppManager.mWholeSelectedInterval.getStart();
                    end_clock = AppManager.mWholeSelectedInterval.getEnd();
                } else {
                    start_clock = trackSelector.getSelectedRegion().getKey();
                    end_clock = trackSelector.getSelectedRegion().getValue();
                }

                // クローンを作成
                VsqFileEx work = (VsqFileEx)AppManager.getVsqFile().clone();
                if ( delete_event != null ) {
                    // 選択されたノートイベントがあれば、クローンに対して削除を実行
                    work.executeCommand( delete_event );
                }

                // BPListに削除処理を施す
                for ( int i = 0; i < Utility.CURVE_USAGE.Length; i++ ) {
                    CurveType curve = Utility.CURVE_USAGE[i];
                    VsqBPList list = work.Track.get( track ).getCurve( curve.getName() );
                    if ( list == null ) {
                        continue;
                    }
                    int c = list.size();
                    Vector<Long> delete = new Vector<Long>();
                    if ( AppManager.isWholeSelectedIntervalEnabled() ) {
                        // 一括選択モード
                        for ( int j = 0; j < c; j++ ) {
                            int clock = list.getKeyClock( j );
                            if ( start_clock <= clock && clock <= end_clock ) {
                                delete.add( list.getElementB( j ).id );
                            } else if ( end_clock < clock ) {
                                break;
                            }
                        }
                    } else {
                        // 普通の範囲選択
                        for ( Iterator<Long> itr = AppManager.itemSelection.getPointIDIterator(); itr.hasNext(); ) {
                            long id = (Long)itr.next();
                            delete.add( id );
                        }
                    }
                    VsqCommand tmp = VsqCommand.generateCommandTrackCurveEdit2( track, curve.getName(), delete, new TreeMap<Integer, VsqBPPair>() );
                    work.executeCommand( tmp );
                }

                // ベジエ曲線に削除処理を施す
                Vector<CurveType> target_curve = new Vector<CurveType>();
                if ( AppManager.isWholeSelectedIntervalEnabled() ) {
                    // ctrlによる全選択モード
                    for ( int i = 0; i < Utility.CURVE_USAGE.Length; i++ ) {
                        CurveType ct = Utility.CURVE_USAGE[i];
                        if ( ct.isScalar() || ct.isAttachNote() ) {
                            continue;
                        }
                        target_curve.add( ct );
                    }
                } else {
                    // 普通の選択モード
                    target_curve.add( trackSelector.getSelectedCurve() );
                }
                work.AttachedCurves.get( AppManager.getSelected() - 1 ).deleteBeziers( target_curve, start_clock, end_clock );

                // コマンドを発行し、実行
                CadenciiCommand run = VsqFileEx.generateCommandReplace( work );
                AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                this.setEdited( true );

                other_command_executed = true;
            } else if ( AppManager.itemSelection.getTempoCount() > 0 ) {
                // テンポ変更のカット
                int count = -1;
                int[] dum = new int[AppManager.itemSelection.getTempoCount()];
                int[] clocks = new int[AppManager.itemSelection.getTempoCount()];
                for ( Iterator<ValuePair<Integer, SelectedTempoEntry>> itr = AppManager.itemSelection.getTempoIterator(); itr.hasNext(); ) {
                    ValuePair<Integer, SelectedTempoEntry> item = itr.next();
                    int key = item.getKey();
                    SelectedTempoEntry value = item.getValue();
                    count++;
                    dum[count] = -1;
                    clocks[count] = value.original.Clock;
                }
                CadenciiCommand run = new CadenciiCommand( VsqCommand.generateCommandUpdateTempoRange( clocks, clocks, dum ) );
                AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                setEdited( true );
                other_command_executed = true;
            } else if ( AppManager.itemSelection.getTimesigCount() > 0 ) {
                // 拍子変更のカット
                int[] barcounts = new int[AppManager.itemSelection.getTimesigCount()];
                int[] numerators = new int[AppManager.itemSelection.getTimesigCount()];
                int[] denominators = new int[AppManager.itemSelection.getTimesigCount()];
                int count = -1;
                for ( Iterator<ValuePair<Integer, SelectedTimesigEntry>> itr = AppManager.itemSelection.getTimesigIterator(); itr.hasNext(); ) {
                    ValuePair<Integer, SelectedTimesigEntry> item = itr.next();
                    int key = item.getKey();
                    SelectedTimesigEntry value = item.getValue();
                    count++;
                    barcounts[count] = value.original.BarCount;
                    numerators[count] = -1;
                    denominators[count] = -1;
                }
                CadenciiCommand run = new CadenciiCommand(
                    VsqCommand.generateCommandUpdateTimesigRange( barcounts, barcounts, numerators, denominators ) );
                AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                setEdited( true );
                other_command_executed = true;
            }

            // 冒頭で作成した音符イベント削除以外に、コマンドが実行されなかった場合
            if ( delete_event != null && !other_command_executed ) {
                CadenciiCommand run = new CadenciiCommand( delete_event );
                AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                setEdited( true );
            }

            refreshScreen();
        }

        public void copyCurveCor(
            int track,
            CurveType curve_type,
            int start,
            int end,
            Vector<BezierChain> copied_chain
        )
        {
            for ( Iterator<BezierChain> itr = AppManager.getVsqFile().AttachedCurves.get( track - 1 ).get( curve_type ).iterator(); itr.hasNext(); ) {
                BezierChain bc = itr.next();
                int len = bc.points.size();
                if ( len < 2 ) {
                    continue;
                }
                int chain_start = (int)bc.points.get( 0 ).getBase().getX();
                int chain_end = (int)bc.points.get( len - 1 ).getBase().getX();
                BezierChain add = null;
                if ( start < chain_start && chain_start < end && end < chain_end ) {
                    // (1) chain_start ~ end をコピー
                    try {
                        add = bc.extractPartialBezier( chain_start, end );
                    } catch ( Exception ex ) {
                        Logger.write( typeof( FormMain ) + ".copyCurveCor; ex=" + ex + "\n" );
                        add = null;
                    }
                } else if ( chain_start <= start && end <= chain_end ) {
                    // (2) start ~ endをコピー
                    try {
                        add = bc.extractPartialBezier( start, end );
                    } catch ( Exception ex ) {
                        Logger.write( typeof( FormMain ) + ".copyCurveCor; ex=" + ex + "\n" );
                        add = null;
                    }
                } else if ( chain_start < start && start < chain_end && chain_end <= end ) {
                    // (3) start ~ chain_endをコピー
                    try {
                        add = bc.extractPartialBezier( start, chain_end );
                    } catch ( Exception ex ) {
                        Logger.write( typeof( FormMain ) + ".copyCurveCor; ex=" + ex + "\n" );
                        add = null;
                    }
                } else if ( start <= chain_start && chain_end <= end ) {
                    // (4) 全部コピーでOK
                    add = (BezierChain)bc.clone();
                }
                if ( add != null ) {
                    copied_chain.add( add );
                }
            }
        }
        #endregion

        #region トラックの編集関連
        /// <summary>
        /// トラック全体のコピーを行います。
        /// </summary>
06024         public void copyTrackCore()
        {
            VsqFileEx vsq = AppManager.getVsqFile();
            int selected = AppManager.getSelected();
            VsqTrack track = (VsqTrack)vsq.Track.get( selected ).clone();
            track.setName( track.getName() + " (1)" );
            CadenciiCommand run = VsqFileEx.generateCommandAddTrack( track,
                                                                     vsq.Mixer.Slave.get( selected - 1 ),
                                                                     vsq.Track.size(),
                                                                     vsq.AttachedCurves.get( selected - 1 ) ); ;
            AppManager.editHistory.register( vsq.executeCommand( run ) );
            setEdited( true );
            AppManager.mMixerWindow.updateStatus();
            refreshScreen();
        }

        /// <summary>
        /// トラックの名前変更を行います。
        /// </summary>
06043         public void changeTrackNameCore()
        {
            InputBox ib = null;
            try{
                int selected = AppManager.getSelected();
                VsqFileEx vsq = AppManager.getVsqFile();
                ib = new InputBox( _( "Input new name of track" ) );
                ib.setResult( vsq.Track.get( selected ).getName() );
                ib.setLocation( getFormPreferedLocation( ib ) );
                BDialogResult dr = AppManager.showModalDialog( ib, this );
                if( dr == BDialogResult.OK ){
                    String ret = ib.getResult();
                    CadenciiCommand run = new CadenciiCommand(
                        VsqCommand.generateCommandTrackChangeName( selected, ret ) );
                    AppManager.editHistory.register( vsq.executeCommand( run ) );
                    setEdited( true );
                    refreshScreen();
                }
            }catch( Exception ex ){
            }finally{
                if( ib != null ){
                    ib.close();
                }
            }

/*            if ( mTextBoxTrackName != null ) {
#if !JAVA
                if ( !mTextBoxTrackName.IsDisposed ) {
                    mTextBoxTrackName.Dispose();
                }
#endif
                mTextBoxTrackName = null;
            }
#if JAVA
            mTextBoxTrackName = new LyricTextBox( this );
#else
            mTextBoxTrackName = new LyricTextBox();
#endif
            mTextBoxTrackName.setVisible( false );
            int selector_width = trackSelector.getSelectorWidth();
            int x = AppManager.keyWidth + (AppManager.getSelected() - 1) * selector_width;
            mTextBoxTrackName.setLocation( x, trackSelector.getHeight() - TrackSelector.OFFSET_TRACK_TAB + 1 );
            mTextBoxTrackName.setText( AppManager.getVsqFile().Track.get( AppManager.getSelected() ).getName() );
#if JAVA
            mTextBoxTrackName.keyUpEvent.add( new BKeyEventHandler( this, "mTextBoxTrackName_KeyUp" ) );
#else
            mTextBoxTrackName.BorderStyle = System.Windows.Forms.BorderStyle.None;
            mTextBoxTrackName.KeyUp += new System.Windows.Forms.KeyEventHandler( mTextBoxTrackName_KeyUp );
            mTextBoxTrackName.Parent = trackSelector;
#endif
            mTextBoxTrackName.setSize( selector_width, TrackSelector.OFFSET_TRACK_TAB );
            mTextBoxTrackName.setVisible( true );
            mTextBoxTrackName.requestFocus();
            mTextBoxTrackName.selectAll();*/
        }

        /// <summary>
        /// トラックの削除を行います。
        /// </summary>
06102         public void deleteTrackCore()
        {
            int selected = AppManager.getSelected();
            VsqFileEx vsq = AppManager.getVsqFile();
            if ( AppManager.showMessageBox(
                    PortUtil.formatMessage( _( "Do you wish to remove track? {0} : '{1}'" ), selected, vsq.Track.get( selected ).getName() ),
                    _APP_NAME,
                    org.kbinani.windows.forms.Utility.MSGBOX_YES_NO_OPTION,
                    org.kbinani.windows.forms.Utility.MSGBOX_QUESTION_MESSAGE ) == BDialogResult.YES ) {
                CadenciiCommand run = VsqFileEx.generateCommandDeleteTrack( selected );
                if ( selected >= 2 ) {
                    AppManager.setSelected( selected - 1 );
                }
                AppManager.editHistory.register( vsq.executeCommand( run ) );
                updateDrawObjectList();
                setEdited( true );
                AppManager.mMixerWindow.updateStatus();
                refreshScreen();
            }
        }

        /// <summary>
        /// トラックの追加を行います。
        /// </summary>
06126         public void addTrackCore()
        {
            VsqFileEx vsq = AppManager.getVsqFile();
            int i = vsq.Track.size();
            String name = "Voice" + i;
            String singer = AppManager.editorConfig.DefaultSingerName;
            VsqTrack vsq_track = new VsqTrack( name, singer );

            RendererKind kind = AppManager.editorConfig.DefaultSynthesizer;
            String renderer = AppManager.getVersionStringFromRendererKind( kind );
            Vector<VsqID> singers = AppManager.getSingerListFromRendererKind( kind );

            vsq_track.changeRenderer( renderer, singers );
            CadenciiCommand run = VsqFileEx.generateCommandAddTrack( vsq_track,
                                                                     new VsqMixerEntry( 0, 0, 0, 0 ),
                                                                     i,
                                                                     new BezierCurves() );
            AppManager.editHistory.register( vsq.executeCommand( run ) );
            updateDrawObjectList();
            setEdited( true );
            AppManager.setSelected( i );
            AppManager.mMixerWindow.updateStatus();
            refreshScreen();
        }
        #endregion

        /// <summary>
        /// length, positionの各Quantizeモードに応じて、
        /// 関連する全てのメニュー・コンテキストメニューの表示状態を更新します。
        /// </summary>
06156         public void applyQuantizeMode()
        {
            cMenuPianoQuantize04.setSelected( false );
            cMenuPianoQuantize08.setSelected( false );
            cMenuPianoQuantize16.setSelected( false );
            cMenuPianoQuantize32.setSelected( false );
            cMenuPianoQuantize64.setSelected( false );
            cMenuPianoQuantize128.setSelected( false );
            cMenuPianoQuantizeOff.setSelected( false );

#if ENABLE_STRIP_DROPDOWN
            stripDDBtnQuantize04.Checked = false;
            stripDDBtnQuantize08.Checked = false;
            stripDDBtnQuantize16.Checked = false;
            stripDDBtnQuantize32.Checked = false;
            stripDDBtnQuantize64.Checked = false;
            stripDDBtnQuantize128.Checked = false;
            stripDDBtnQuantizeOff.Checked = false;
#endif

            menuSettingPositionQuantize04.setSelected( false );
            menuSettingPositionQuantize08.setSelected( false );
            menuSettingPositionQuantize16.setSelected( false );
            menuSettingPositionQuantize32.setSelected( false );
            menuSettingPositionQuantize64.setSelected( false );
            menuSettingPositionQuantize128.setSelected( false );
            menuSettingPositionQuantizeOff.setSelected( false );

#if !JAVA
            QuantizeMode qm = AppManager.editorConfig.getPositionQuantize();
            boolean triplet = AppManager.editorConfig.isPositionQuantizeTriplet();
            stripDDBtnQuantizeParent.Text =
                "QUANTIZE " + QuantizeModeUtil.getString( qm ) +
                ((qm != QuantizeMode.off && triplet) ? " [3]" : "");
#endif
            if ( AppManager.editorConfig.getPositionQuantize() == QuantizeMode.p4 ) {
                cMenuPianoQuantize04.setSelected( true );
#if ENABLE_STRIP_DROPDOWN
                stripDDBtnQuantize04.Checked = true;
#endif
#if !JAVA
                stripDDBtnQuantizeParent.ImageKey = "note004.png";
#endif
                menuSettingPositionQuantize04.setSelected( true );
            } else if ( AppManager.editorConfig.getPositionQuantize() == QuantizeMode.p8 ) {
                cMenuPianoQuantize08.setSelected( true );
#if ENABLE_STRIP_DROPDOWN
                stripDDBtnQuantize08.Checked = true;
#endif
#if !JAVA
                stripDDBtnQuantizeParent.ImageKey = "note008.png";
#endif
                menuSettingPositionQuantize08.setSelected( true );
            } else if ( AppManager.editorConfig.getPositionQuantize() == QuantizeMode.p16 ) {
                cMenuPianoQuantize16.setSelected( true );
#if ENABLE_STRIP_DROPDOWN
                stripDDBtnQuantize16.Checked = true;
#endif
#if !JAVA
                stripDDBtnQuantizeParent.ImageKey = "note016.png";
#endif
                menuSettingPositionQuantize16.setSelected( true );
            } else if ( AppManager.editorConfig.getPositionQuantize() == QuantizeMode.p32 ) {
                cMenuPianoQuantize32.setSelected( true );
#if ENABLE_STRIP_DROPDOWN
                stripDDBtnQuantize32.Checked = true;
#endif
#if !JAVA
                stripDDBtnQuantizeParent.ImageKey = "note032.png";
#endif
                menuSettingPositionQuantize32.setSelected( true );
            } else if ( AppManager.editorConfig.getPositionQuantize() == QuantizeMode.p64 ) {
                cMenuPianoQuantize64.setSelected( true );
#if ENABLE_STRIP_DROPDOWN
                stripDDBtnQuantize64.Checked = true;
#endif
#if !JAVA
                stripDDBtnQuantizeParent.ImageKey = "note064.png";
#endif
                menuSettingPositionQuantize64.setSelected( true );
            } else if ( AppManager.editorConfig.getPositionQuantize() == QuantizeMode.p128 ) {
                cMenuPianoQuantize128.setSelected( true );
#if ENABLE_STRIP_DROPDOWN
                stripDDBtnQuantize128.Checked = true;
#endif
#if !JAVA
                stripDDBtnQuantizeParent.ImageKey = "note128.png";
#endif
                menuSettingPositionQuantize128.setSelected( true );
            } else if ( AppManager.editorConfig.getPositionQuantize() == QuantizeMode.off ) {
                cMenuPianoQuantizeOff.setSelected( true );
#if ENABLE_STRIP_DROPDOWN
                stripDDBtnQuantizeOff.Checked = true;
#endif
#if !JAVA
                stripDDBtnQuantizeParent.ImageKey = "notenull.png";
#endif
                menuSettingPositionQuantizeOff.setSelected( true );
            }
            cMenuPianoQuantizeTriplet.setSelected( AppManager.editorConfig.isPositionQuantizeTriplet() );
#if ENABLE_STRIP_DROPDOWN
            stripDDBtnQuantizeTriplet.Checked = AppManager.editorConfig.isPositionQuantizeTriplet();
#endif
            menuSettingPositionQuantizeTriplet.setSelected( AppManager.editorConfig.isPositionQuantizeTriplet() );
        }

        /// <summary>
        /// 現在選択されている編集ツールに応じて、メニューのチェック状態を更新します
        /// </summary>
06265         public void applySelectedTool()
        {
            EditTool tool = AppManager.getSelectedTool();

#if JAVA
            int count = toolStripTool.getComponentCount();
#else
            int count = toolBarTool.Buttons.Count;
#endif
            for ( int i = 0; i < count; i++ ) {
#if JAVA
                Object tsi = toolStripTool.getComponentAtIndex( i );
#else
                Object tsi = toolBarTool.Buttons[i];
#endif
#if JAVA
                if( tsi instanceof PaletteToolButton ){
                    BToggleButton tsb = (PaletteToolButton)tsi;
                    boolean sel = false;
#if ENABLE_SCRIPT
                    String id = tsb.getPaletteToolID();
                    if( id != null ){
                        if( tool == EditTool.PALETTE_TOOL ){
                            sel = str.compare( AppManager.mSelectedPaletteTool, id );
                        }
                    }
#endif // ENABLE_SCRIPT
                    tsb.setSelected( sel );
                }
#else // JAVA
                if ( tsi is System.Windows.Forms.ToolBarButton ) {
                    System.Windows.Forms.ToolBarButton tsb = (System.Windows.Forms.ToolBarButton)tsi;
                    Object tag = tsb.Tag;
                    if ( tsb.Style == System.Windows.Forms.ToolBarButtonStyle.ToggleButton && tag != null && tag is String ) {
#if ENABLE_SCRIPT
                        if ( tool == EditTool.PALETTE_TOOL ) {
                            String id = (String)tag;
                            tsb.Pushed = str.compare( AppManager.mSelectedPaletteTool, id );
                        } else
#endif // ENABLE_SCRIPT
 {
                            tsb.Pushed = false;
                        }
                    }
                }
#endif // JAVA
            }
            MenuElement[] items = cMenuTrackSelectorPaletteTool.getSubElements();
            foreach ( MenuElement tsi in items ) {
                if ( tsi is PaletteToolMenuItem ) {
                    PaletteToolMenuItem tsmi = (PaletteToolMenuItem)tsi;
                    String id = tsmi.getPaletteToolID();
                    boolean sel = false;
#if ENABLE_SCRIPT
                    if ( tool == EditTool.PALETTE_TOOL ) {
                        sel = str.compare( AppManager.mSelectedPaletteTool, id );
                    }
#endif
                    tsmi.setSelected( sel );
                }
            }

            items = cMenuPianoPaletteTool.getSubElements();
            foreach ( MenuElement tsi in items ) {
                if ( tsi is PaletteToolMenuItem ) {
                    PaletteToolMenuItem tsmi = (PaletteToolMenuItem)tsi;
                    String id = tsmi.getPaletteToolID();
                    boolean sel = false;
#if ENABLE_SCRIPT
                    if ( tool == EditTool.PALETTE_TOOL ) {
                        sel = str.compare( AppManager.mSelectedPaletteTool, id );
                    }
#endif
                    tsmi.setSelected( sel );
                }
            }

            EditTool selected_tool = AppManager.getSelectedTool();
            cMenuPianoPointer.setSelected( (selected_tool == EditTool.ARROW) );
            cMenuPianoPencil.setSelected( (selected_tool == EditTool.PENCIL) );
            cMenuPianoEraser.setSelected( (selected_tool == EditTool.ERASER) );

            cMenuTrackSelectorPointer.setSelected( (selected_tool == EditTool.ARROW) );
            cMenuTrackSelectorPencil.setSelected( (selected_tool == EditTool.PENCIL) );
            cMenuTrackSelectorLine.setSelected( (selected_tool == EditTool.LINE) );
            cMenuTrackSelectorEraser.setSelected( (selected_tool == EditTool.ERASER) );

#if JAVA
            stripBtnPointer.setSelected( (selected_tool == EditTool.ARROW) );
            stripBtnPencil.setSelected( (selected_tool == EditTool.PENCIL) );
            stripBtnLine.setSelected( (selected_tool == EditTool.LINE) );
            stripBtnEraser.setSelected( (selected_tool == EditTool.ERASER) );
#else
            stripBtnPointer.Pushed = (selected_tool == EditTool.ARROW);
            stripBtnPencil.Pushed = (selected_tool == EditTool.PENCIL);
            stripBtnLine.Pushed = (selected_tool == EditTool.LINE);
            stripBtnEraser.Pushed = (selected_tool == EditTool.ERASER);
#endif


            cMenuPianoCurve.setSelected( AppManager.isCurveMode() );
            cMenuTrackSelectorCurve.setSelected( AppManager.isCurveMode() );
#if JAVA
            stripBtnCurve.setSelected( AppManager.isCurveMode() );
#else
            stripBtnCurve.Pushed = AppManager.isCurveMode();
#endif
        }

        /// <summary>
        /// 描画すべきオブジェクトのリスト,AppManager.drawObjectsを更新します
        /// </summary>
06377         public void updateDrawObjectList()
        {
            // AppManager.m_draw_objects
            if ( AppManager.mDrawObjects == null ) {
                AppManager.mDrawObjects = new Vector<Vector<DrawObject>>();
            }
            lock ( AppManager.mDrawObjects ) {
                if ( AppManager.getVsqFile() == null ) {
                    return;
                }
                for ( int i = 0; i < AppManager.mDrawStartIndex.Length; i++ ) {
                    AppManager.mDrawStartIndex[i] = 0;
                }
                if ( AppManager.mDrawObjects != null ) {
                    for ( Iterator<Vector<DrawObject>> itr = AppManager.mDrawObjects.iterator(); itr.hasNext(); ) {
                        Vector<DrawObject> list = itr.next();
                        list.clear();
                    }
                    AppManager.mDrawObjects.clear();
                }

                int xoffset = AppManager.keyOffset;// 6 + AppManager.keyWidth;
                int yoffset = (int)(127 * (int)(100 * controller.getScaleY()));
                float scalex = controller.getScaleX();
                Font SMALL_FONT = null;
                try {
                    SMALL_FONT = new Font( AppManager.editorConfig.ScreenFontName, java.awt.Font.PLAIN, AppManager.FONT_SIZE8 );
                    int track_height = (int)(100 * controller.getScaleY());
                    VsqFileEx vsq = AppManager.getVsqFile();
                    int track_count = vsq.Track.size();
                    Polygon env = new Polygon( new int[7], new int[7], 7 );
                    ByRef<Integer> overlap_x = new ByRef<Integer>( 0 );
                    for ( int track = 1; track < track_count; track++ ) {
                        VsqTrack vsq_track = vsq.Track.get( track );
                        Vector<DrawObject> tmp = new Vector<DrawObject>();
                        RendererKind kind = VsqFileEx.getTrackRendererKind( vsq_track );
                        AppManager.mDrawIsUtau[track - 1] = kind == RendererKind.UTAU;

                        // 音符イベント
                        Iterator<VsqEvent> itr_note = vsq_track.getNoteEventIterator();
                        VsqEvent item_prev = null;
                        VsqEvent item = null;
                        VsqEvent item_next = itr_note.hasNext() ? itr_note.next() : null;
                        while ( item_prev != null || item != null || item_next != null ) {
                            item_prev = item;
                            item = item_next;
                            if ( itr_note.hasNext() ) {
                                item_next = itr_note.next();
                            } else {
                                item_next = null;
                            }
                            if ( item == null ) {
                                continue;
                            }
                            if ( item.ID.LyricHandle == null ) {
                                continue;
                            }
                            int timesig = item.Clock;
                            int length = item.ID.getLength();
                            int note = item.ID.Note;
                            int x = (int)(timesig * scalex + xoffset);
                            int y = -note * track_height + yoffset;
                            int lyric_width = (int)(length * scalex);
                            String lyric_jp = item.ID.LyricHandle.L0.Phrase;
                            String lyric_en = item.ID.LyricHandle.L0.getPhoneticSymbol();
                            String title = Utility.trimString( lyric_jp + " [" + lyric_en + "]", SMALL_FONT, lyric_width );
                            int accent = item.ID.DEMaccent;
                            int px_vibrato_start = x + lyric_width;
                            int px_vibrato_end = x;
                            int px_vibrato_delay = lyric_width * 2;
                            int vib_delay = length;
                            if ( item.ID.VibratoHandle != null ) {
                                vib_delay = item.ID.VibratoDelay;
                                double rate = (double)vib_delay / (double)length;
                                px_vibrato_delay = _PX_ACCENT_HEADER + (int)((lyric_width - _PX_ACCENT_HEADER) * rate);
                            }
                            VibratoBPList rate_bp = null;
                            VibratoBPList depth_bp = null;
                            int rate_start = 0;
                            int depth_start = 0;
                            if ( item.ID.VibratoHandle != null ) {
                                rate_bp = item.ID.VibratoHandle.getRateBP();
                                depth_bp = item.ID.VibratoHandle.getDepthBP();
                                rate_start = item.ID.VibratoHandle.getStartRate();
                                depth_start = item.ID.VibratoHandle.getStartDepth();
                            }

                            // analyzed/のSTFが引き当てられるかどうか
                            // UTAUのWAVが引き当てられるかどうか
                            boolean is_valid_for_utau = false;
                            VsqEvent singer_at_clock = vsq_track.getSingerEventAt( timesig );
                            int program = singer_at_clock.ID.IconHandle.Program;
                            if ( 0 <= program && program < AppManager.editorConfig.UtauSingers.size() ) {
                                SingerConfig sc = AppManager.editorConfig.UtauSingers.get( program );
                                // 通常のUTAU音源
                                if ( AppManager.mUtauVoiceDB.containsKey( sc.VOICEIDSTR ) ) {
                                    UtauVoiceDB db = AppManager.mUtauVoiceDB.get( sc.VOICEIDSTR );
                                    OtoArgs oa = db.attachFileNameFromLyric( lyric_jp );
                                    if ( oa.fileName == null ||
                                        (oa.fileName != null && str.compare( oa.fileName, "" )) ) {
                                        is_valid_for_utau = false;
                                    } else {
                                        is_valid_for_utau = fsys.isFileExists( fsys.combine( sc.VOICEIDSTR, oa.fileName ) );
                                    }
                                }
                            }
                            int intensity = item.UstEvent == null ? 100 : item.UstEvent.getIntensity();

                            //追加
                            tmp.add( new DrawObject( DrawObjectType.Note,
                                                     vsq,
                                                     new Rectangle( x, y, lyric_width, track_height ),
                                                     title,
                                                     accent,
                                                     item.ID.DEMdecGainRate,
                                                     item.ID.Dynamics,
                                                     item.InternalID,
                                                     px_vibrato_delay,
                                                     false,
                                                     item.ID.LyricHandle.L0.PhoneticSymbolProtected,
                                                     rate_bp,
                                                     depth_bp,
                                                     rate_start,
                                                     depth_start,
                                                     item.ID.Note,
                                                     item.UstEvent.getEnvelope(),
                                                     length,
                                                     timesig,
                                                     is_valid_for_utau,
                                                     is_valid_for_utau, // vConnect-STANDはstfファイルを必要としないので,
                                                     vib_delay,
                                                     intensity ) );
                        }

                        // Dynaff, Crescendイベント
                        for ( Iterator<VsqEvent> itr = vsq_track.getDynamicsEventIterator(); itr.hasNext(); ) {
                            VsqEvent item_itr = itr.next();
                            IconDynamicsHandle handle = item_itr.ID.IconDynamicsHandle;
                            if ( handle == null ) {
                                continue;
                            }
                            int clock = item_itr.Clock;
                            int length = item_itr.ID.getLength();
                            if ( length <= 0 ) {
                                length = 1;
                            }
                            int raw_width = (int)(length * scalex);
                            DrawObjectType type = DrawObjectType.Note;
                            int width = 0;
                            String str = "";
                            if ( handle.isDynaffType() ) {
                                // 強弱記号
                                type = DrawObjectType.Dynaff;
                                width = AppManager.DYNAFF_ITEM_WIDTH;
                                int startDyn = handle.getStartDyn();
                                if ( startDyn == 120 ) {
                                    str = "fff";
                                } else if ( startDyn == 104 ) {
                                    str = "ff";
                                } else if ( startDyn == 88 ) {
                                    str = "f";
                                } else if ( startDyn == 72 ) {
                                    str = "mf";
                                } else if ( startDyn == 56 ) {
                                    str = "mp";
                                } else if ( startDyn == 40 ) {
                                    str = "p";
                                } else if ( startDyn == 24 ) {
                                    str = "pp";
                                } else if ( startDyn == 8 ) {
                                    str = "ppp";
                                } else {
                                    str = "?";
                                }
                            } else if ( handle.isCrescendType() ) {
                                // クレッシェンド
                                type = DrawObjectType.Crescend;
                                width = raw_width;
                                str = handle.IDS;
                            } else if ( handle.isDecrescendType() ) {
                                // デクレッシェンド
                                type = DrawObjectType.Decrescend;
                                width = raw_width;
                                str = handle.IDS;
                            }
                            if ( type == DrawObjectType.Note ) {
                                continue;
                            }
                            int note = item_itr.ID.Note;
                            int x = (int)(clock * scalex + xoffset);
                            int y = -note * (int)(100 * controller.getScaleY()) + yoffset;
                            tmp.add( new DrawObject( type,
                                                     vsq,
                                                     new Rectangle( x, y, width, track_height ),
                                                     str,
                                                     0,
                                                     0,
                                                     0,
                                                     item_itr.InternalID,
                                                     0,
                                                     false,
                                                     false,
                                                     null,
                                                     null,
                                                     0,
                                                     0,
                                                     item_itr.ID.Note,
                                                     null,
                                                     length,
                                                     clock,
                                                     true,
                                                     true,
                                                     length,
                                                     0 ) );
                        }

                        // 重複部分があるかどうかを判定
                        int count = tmp.size();
                        for ( int i = 0; i < count - 1; i++ ) {
                            DrawObject itemi = tmp.get( i );
                            DrawObjectType parent_type = itemi.mType;
                            /*if ( itemi.type != DrawObjectType.Note ) {
                                continue;
                            }*/
                            boolean overwrapped = false;
                            int istart = itemi.mClock;
                            int iend = istart + itemi.mLength;
                            if ( itemi.mIsOverlapped ) {
                                continue;
                            }
                            for ( int j = i + 1; j < count; j++ ) {
                                DrawObject itemj = tmp.get( j );
                                if ( (itemj.mType == DrawObjectType.Note && parent_type != DrawObjectType.Note) ||
                                     (itemj.mType != DrawObjectType.Note && parent_type == DrawObjectType.Note) ) {
                                    continue;
                                }
                                int jstart = itemj.mClock;
                                int jend = jstart + itemj.mLength;
                                if ( jstart <= istart ) {
                                    if ( istart < jend ) {
                                        overwrapped = true;
                                        itemj.mIsOverlapped = true;
                                        // breakできない.2個以上の重複を検出する必要があるので.
                                    }
                                }
                                if ( istart <= jstart ) {
                                    if ( jstart < iend ) {
                                        overwrapped = true;
                                        itemj.mIsOverlapped = true;
                                    }
                                }
                            }
                            if ( overwrapped ) {
                                itemi.mIsOverlapped = true;
                            }
                        }
                        Collections.sort( tmp );
                        AppManager.mDrawObjects.add( tmp );
                    }
                } catch ( Exception ex ) {
                    Logger.write( typeof( FormMain ) + ".updateDrawObjectList; ex=" + ex + "\n" );
                    serr.println( "FormMain#updateDrawObjectList; ex=" + ex );
#if JAVA
                    ex.printStackTrace();
#endif
                } finally {
#if !JAVA
                    if ( SMALL_FONT != null ) {
                        SMALL_FONT.font.Dispose();
                    }
#endif
                }
            }
        }

        /// <summary>
        /// editorConfigのRecentFilesを元に,menuFileRecentのドロップダウンアイテムを更新します
        /// </summary>
06655         public void updateRecentFileMenu()
        {
            int added = 0;
            menuFileRecent.removeAll();
            if ( AppManager.editorConfig.RecentFiles != null ) {
                for ( int i = 0; i < AppManager.editorConfig.RecentFiles.size(); i++ ) {
                    String item = AppManager.editorConfig.RecentFiles.get( i );
                    if ( item == null ) {
                        continue;
                    }
                    if ( item != "" ) {
                        String short_name = PortUtil.getFileName( item );
                        boolean available = fsys.isFileExists( item );
                        RecentFileMenuItem itm = new RecentFileMenuItem( item );
                        itm.setText( short_name );
                        String tooltip = "";
                        if ( !available ) {
                            tooltip = _( "[file not found]" ) + " ";
                        }
                        tooltip += item;
                        itm.setToolTipText( tooltip );
                        itm.setEnabled( available );
                        itm.Click += new BEventHandler( handleRecentFileMenuItem_Click );
                        itm.MouseEnter += new BEventHandler( handleRecentFileMenuItem_MouseEnter );
                        menuFileRecent.add( itm );
                        added++;
                    }
                }
            } else {
                AppManager.editorConfig.pushRecentFiles( "" );
            }
            menuFileRecent.addSeparator();
            menuFileRecent.add( menuFileRecentClear );
            menuFileRecent.setEnabled( true );
        }

        /// <summary>
        /// 最後に保存したときから変更されているかどうかを取得または設定します
        /// </summary>
06694         public boolean isEdited()
        {
            return mEdited;
        }

        public void setEdited( boolean value )
        {
            mEdited = value;
            String file = AppManager.getFileName();
            if ( str.compare( file, "" ) ) {
                file = "Untitled";
            } else {
                file = PortUtil.getFileNameWithoutExtension( file );
            }
            if ( mEdited ) {
                file += " *";
            }
            String title = file + " - " + _APP_NAME;
            if ( !str.compare( getTitle(), title ) ) {
                setTitle( title );
            }
            boolean redo = AppManager.editHistory.hasRedoHistory();
            boolean undo = AppManager.editHistory.hasUndoHistory();
            menuEditRedo.setEnabled( redo );
            menuEditUndo.setEnabled( undo );
            cMenuPianoRedo.setEnabled( redo );
            cMenuPianoUndo.setEnabled( undo );
            cMenuTrackSelectorRedo.setEnabled( redo );
            cMenuTrackSelectorUndo.setEnabled( undo );
#if JAVA
            stripBtnUndo.setEnabled( undo );
            stripBtnRedo.setEnabled( redo );
#else
            stripBtnUndo.Enabled = undo;
            stripBtnRedo.Enabled = redo;
#endif
            //AppManager.setRenderRequired( AppManager.getSelected(), true );
            updateScrollRangeHorizontal();
            updateDrawObjectList();
            panelOverview.updateCachedImage();

#if ENABLE_PROPERTY
            AppManager.propertyPanel.updateValue( AppManager.getSelected() );
#endif
        }

        /// <summary>
        /// 入力用のテキストボックスを初期化します
        /// </summary>
06743         public void showInputTextBox( String phrase, String phonetic_symbol, Point position, boolean phonetic_symbol_edit_mode )
        {
#if DEBUG
            AppManager.debugWriteLine( "InitializeInputTextBox" );
#endif
            hideInputTextBox();

            AppManager.mInputTextBox.KeyUp += new BKeyEventHandler( mInputTextBox_KeyUp );
            AppManager.mInputTextBox.KeyDown += new BKeyEventHandler( mInputTextBox_KeyDown );
            //TODO: JAVA: AppManager.mInputTextBox.ImeModeChanged += mInputTextBox_ImeModeChanged;
#if !JAVA
            AppManager.mInputTextBox.ImeModeChanged += mInputTextBox_ImeModeChanged;
#endif

            AppManager.mInputTextBox.setImeModeOn( mLastIsImeModeOn );
            if ( phonetic_symbol_edit_mode ) {
                AppManager.mInputTextBox.setBufferText( phrase );
                AppManager.mInputTextBox.setPhoneticSymbolEditMode( true );
                AppManager.mInputTextBox.setText( phonetic_symbol );
                AppManager.mInputTextBox.setBackground( mColorTextboxBackcolor );
            } else {
                AppManager.mInputTextBox.setBufferText( phonetic_symbol );
                AppManager.mInputTextBox.setPhoneticSymbolEditMode( false );
                AppManager.mInputTextBox.setText( phrase );
                AppManager.mInputTextBox.setBackground( Color.white );
            }
            AppManager.mInputTextBox.setFont( new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.PLAIN, AppManager.FONT_SIZE9 ) );
            Point p = new Point( position.x + 4, position.y + 2 );
#if JAVA
            p = pictPianoRoll.pointToScreen( p );
#endif
            AppManager.mInputTextBox.setLocation( p );

#if !JAVA
            AppManager.mInputTextBox.Parent = pictPianoRoll;
#endif
            AppManager.mInputTextBox.setEnabled( true );
            AppManager.mInputTextBox.setVisible( true );
            AppManager.mInputTextBox.requestFocusInWindow();
            AppManager.mInputTextBox.selectAll();
        }

        public void hideInputTextBox()
        {
#if JAVA
            AppManager.mInputTextBox.keyUpEvent.remove( new BKeyEventHandler( this, "mInputTextBox_KeyUp" ) );
            AppManager.mInputTextBox.keyDownEvent.remove( new BKeyEventHandler( this, "mInputTextBox_KeyDown" ) );
            // TODO: JAVA: AppManager.mInputTextBox.ImeModeChanged -= mInputTextBox_ImeModeChanged;
#else
            AppManager.mInputTextBox.KeyUp -= new System.Windows.Forms.KeyEventHandler( mInputTextBox_KeyUp );
            AppManager.mInputTextBox.KeyDown -= new System.Windows.Forms.KeyEventHandler( mInputTextBox_KeyDown );
            AppManager.mInputTextBox.ImeModeChanged -= mInputTextBox_ImeModeChanged;
#endif
            mLastSymbolEditMode = AppManager.mInputTextBox.isPhoneticSymbolEditMode();
            AppManager.mInputTextBox.setVisible( false );
#if !JAVA
            AppManager.mInputTextBox.Parent = null;
#endif
            AppManager.mInputTextBox.setEnabled( false );
            focusPianoRoll();
        }

        /// <summary>
        /// 歌詞入力用テキストボックスのモード(歌詞/発音記号)を切り替えます
        /// </summary>
06808         public void flipInputTextBoxMode()
        {
            String new_value = AppManager.mInputTextBox.getText();
            if ( !AppManager.mInputTextBox.isPhoneticSymbolEditMode() ) {
                AppManager.mInputTextBox.setBackground( mColorTextboxBackcolor );
            } else {
                AppManager.mInputTextBox.setBackground( Color.white );
            }
            AppManager.mInputTextBox.setText( AppManager.mInputTextBox.getBufferText() );
            AppManager.mInputTextBox.setBufferText( new_value );
            AppManager.mInputTextBox.setPhoneticSymbolEditMode( !AppManager.mInputTextBox.isPhoneticSymbolEditMode() );
        }

        /// <summary>
        /// アンドゥ処理を行います
        /// </summary>
06824         public void undo()
        {
            if ( AppManager.editHistory.hasUndoHistory() ) {
                AppManager.undo();
                menuEditRedo.setEnabled( AppManager.editHistory.hasRedoHistory() );
                menuEditUndo.setEnabled( AppManager.editHistory.hasUndoHistory() );
                cMenuPianoRedo.setEnabled( AppManager.editHistory.hasRedoHistory() );
                cMenuPianoUndo.setEnabled( AppManager.editHistory.hasUndoHistory() );
                cMenuTrackSelectorRedo.setEnabled( AppManager.editHistory.hasRedoHistory() );
                cMenuTrackSelectorUndo.setEnabled( AppManager.editHistory.hasUndoHistory() );
                AppManager.mMixerWindow.updateStatus();
                setEdited( true );
                updateDrawObjectList();

#if ENABLE_PROPERTY
                if ( AppManager.propertyPanel != null ) {
                    AppManager.propertyPanel.updateValue( AppManager.getSelected() );
                }
#endif
            }
        }

        /// <summary>
        /// リドゥ処理を行います
        /// </summary>
06849         public void redo()
        {
            if ( AppManager.editHistory.hasRedoHistory() ) {
                AppManager.redo();
                menuEditRedo.setEnabled( AppManager.editHistory.hasRedoHistory() );
                menuEditUndo.setEnabled( AppManager.editHistory.hasUndoHistory() );
                cMenuPianoRedo.setEnabled( AppManager.editHistory.hasRedoHistory() );
                cMenuPianoUndo.setEnabled( AppManager.editHistory.hasUndoHistory() );
                cMenuTrackSelectorRedo.setEnabled( AppManager.editHistory.hasRedoHistory() );
                cMenuTrackSelectorUndo.setEnabled( AppManager.editHistory.hasUndoHistory() );
                AppManager.mMixerWindow.updateStatus();
                setEdited( true );
                updateDrawObjectList();

#if ENABLE_PROPERTY
                if ( AppManager.propertyPanel != null ) {
                    AppManager.propertyPanel.updateValue( AppManager.getSelected() );
                }
#endif
            }
        }

        /// <summary>
        /// xvsqファイルを開きます
        /// </summary>
        /// <returns>ファイルを開くのに成功した場合trueを,それ以外はfalseを返します</returns>
06875         public boolean openVsqCor( String file )
        {
            if( AppManager.readVsq( file ) ){
                return true;
            }
            if ( AppManager.getVsqFile().Track.size() >= 2 ) {
                updateScrollRangeHorizontal();
            }
            AppManager.editorConfig.pushRecentFiles( file );
            updateRecentFileMenu();
            setEdited( false );
            AppManager.editHistory.clear();
            AppManager.mMixerWindow.updateStatus();

            // キャッシュwaveなどの処理
            if ( AppManager.editorConfig.UseProjectCache ) {
                #region キャッシュディレクトリの処理
                VsqFileEx vsq = AppManager.getVsqFile();
                String cacheDir = vsq.cacheDir; // xvsqに保存されていたキャッシュのディレクトリ
                String dir = PortUtil.getDirectoryName( file );
                String name = PortUtil.getFileNameWithoutExtension( file );
                String estimatedCacheDir = fsys.combine( dir, name + ".cadencii" ); // ファイル名から推測されるキャッシュディレクトリ
                if ( cacheDir == null ) {
                    cacheDir = "";
                }
                if ( !str.compare( cacheDir, "" ) && 
                     fsys.isDirectoryExists( cacheDir ) &&
                     !str.compare( estimatedCacheDir, "" ) &&
                     !str.compare( cacheDir, estimatedCacheDir ) ) {
                    // ファイル名から推測されるキャッシュディレクトリ名と
                    // xvsqに指定されているキャッシュディレクトリと異なる場合
                    // cacheDirの必要な部分をestimatedCacheDirに移す

                    // estimatedCacheDirが存在しない場合、新しく作る
#if DEBUG
                    sout.println( "FormMain#openVsqCor;fsys.isDirectoryExists( estimatedCacheDir )=" + fsys.isDirectoryExists( estimatedCacheDir ) ); 
#endif
                    if ( !fsys.isDirectoryExists( estimatedCacheDir ) ) {
                        try {
                            PortUtil.createDirectory( estimatedCacheDir );
                        } catch ( Exception ex ) {
                            Logger.write( typeof( FormMain ) + ".openVsqCor; ex=" + ex + "\n" );
                            serr.println( "FormMain#openVsqCor; ex=" + ex );
                            AppManager.showMessageBox( PortUtil.formatMessage( _( "cannot create cache directory: '{0}'" ), estimatedCacheDir ),
                                                       _( "Info." ),
                                                       PortUtil.OK_OPTION,
                                                       org.kbinani.windows.forms.Utility.MSGBOX_INFORMATION_MESSAGE );
                            return true;
                        }
                    }

                    // ファイルを移す
                    for ( int i = 1; i < vsq.Track.size(); i++ ) {
                        String wavFrom = fsys.combine( cacheDir, i + ".wav" );
                        String xmlFrom = fsys.combine( cacheDir, i + ".xml" );

                        String wavTo = fsys.combine( estimatedCacheDir, i + ".wav" );
                        String xmlTo = fsys.combine( estimatedCacheDir, i + ".xml" );
                        if ( fsys.isFileExists( wavFrom ) ) {
                            try {
                                PortUtil.moveFile( wavFrom, wavTo );
                            } catch ( Exception ex ) {
                                Logger.write( typeof( FormMain ) + ".openVsqCor; ex=" + ex + "\n" );
                                serr.println( "FormMain#openVsqCor; ex=" + ex );
                            }
                        }
                        if ( fsys.isFileExists( xmlFrom ) ) {
                            try {
                                PortUtil.moveFile( xmlFrom, xmlTo );
                            } catch ( Exception ex ) {
                                Logger.write( typeof( FormMain ) + ".openVsqCor; ex=" + ex + "\n" );
                                serr.println( "FormMain#openVsqCor; ex=" + ex );
                            }
                        }
                    }
                }
                cacheDir = estimatedCacheDir;

                // キャッシュが無かったら作成
                if ( !fsys.isDirectoryExists( cacheDir ) ) {
                    try {
                        PortUtil.createDirectory( cacheDir );
                    } catch ( Exception ex ) {
                        Logger.write( typeof( FormMain ) + ".openVsqCor; ex=" + ex + "\n" );
                        serr.println( "FormMain#openVsqCor; ex=" + ex );
                        AppManager.showMessageBox( PortUtil.formatMessage( _( "cannot create cache directory: '{0}'" ), estimatedCacheDir ),
                                                   _( "Info." ),
                                                   PortUtil.OK_OPTION,
                                                   org.kbinani.windows.forms.Utility.MSGBOX_INFORMATION_MESSAGE );
                        return true;
                    }
                }

                // RenderedStatusを読み込む
                for ( int i = 1; i < vsq.Track.size(); i++ ) {
                    AppManager.deserializeRenderingStatus( cacheDir, i );
                }

                // キャッシュ内のwavを、waveViewに読み込む
                waveView.unloadAll();
                for ( int i = 1; i < vsq.Track.size(); i++ ) {
                    String wav = fsys.combine( cacheDir, i + ".wav" );
#if DEBUG
                    sout.println( "FormMain#openVsqCor; wav=" + wav + "; isExists=" + fsys.isFileExists( wav ) );
#endif
                    if ( !fsys.isFileExists( wav ) ) {
                        continue;
                    }
                    waveView.load( i - 1, wav );
                }

                // 一時ディレクトリを、cachedirに変更
                AppManager.setTempWaveDir( cacheDir );
                #endregion
            }
            return false;
        }

        public void updateMenuFonts()
        {
            if ( str.compare( AppManager.editorConfig.BaseFontName, "" ) ) {
                return;
            }
            Font font = AppManager.editorConfig.getBaseFont();
            Util.applyFontRecurse( this, font );
#if !JAVA_MAC
            Util.applyContextMenuFontRecurse( cMenuPiano, font );
            Util.applyContextMenuFontRecurse( cMenuTrackSelector, font );
            if ( AppManager.mMixerWindow != null ) {
                Util.applyFontRecurse( AppManager.mMixerWindow, font );
            }
            Util.applyContextMenuFontRecurse( cMenuTrackTab, font );
            trackSelector.applyFont( font );
            Util.applyToolStripFontRecurse( menuFile, font );
            Util.applyToolStripFontRecurse( menuEdit, font );
            Util.applyToolStripFontRecurse( menuVisual, font );
            Util.applyToolStripFontRecurse( menuJob, font );
            Util.applyToolStripFontRecurse( menuTrack, font );
            Util.applyToolStripFontRecurse( menuLyric, font );
            Util.applyToolStripFontRecurse( menuScript, font );
            Util.applyToolStripFontRecurse( menuSetting, font );
            Util.applyToolStripFontRecurse( menuHelp, font );
#endif
#if !JAVA
            Util.applyFontRecurse( toolBarFile, font );
            Util.applyFontRecurse( toolBarMeasure, font );
            Util.applyFontRecurse( toolBarPosition, font );
            Util.applyFontRecurse( toolBarTool, font );
#endif
#if !JAVA_MAC
            if ( mDialogPreference != null ) {
                Util.applyFontRecurse( mDialogPreference, font );
            }
#endif

            AppManager.baseFont10Bold = new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.BOLD, AppManager.FONT_SIZE10 );
            AppManager.baseFont8 = new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.PLAIN, AppManager.FONT_SIZE8 );
            AppManager.baseFont10 = new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.PLAIN, AppManager.FONT_SIZE10 );
            AppManager.baseFont9 = new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.PLAIN, AppManager.FONT_SIZE9 );
            AppManager.baseFont50Bold = new Font( AppManager.editorConfig.BaseFontName, java.awt.Font.BOLD, AppManager.FONT_SIZE50 );
            AppManager.baseFont10OffsetHeight = Util.getStringDrawOffset( AppManager.baseFont10 );
            AppManager.baseFont8OffsetHeight = Util.getStringDrawOffset( AppManager.baseFont8 );
            AppManager.baseFont9OffsetHeight = Util.getStringDrawOffset( AppManager.baseFont9 );
            AppManager.baseFont50OffsetHeight = Util.getStringDrawOffset( AppManager.baseFont50Bold );
            AppManager.baseFont8Height = Util.measureString( Util.PANGRAM, AppManager.baseFont8 ).height;
            AppManager.baseFont9Height = Util.measureString( Util.PANGRAM, AppManager.baseFont9 ).height;
            AppManager.baseFont10Height = Util.measureString( Util.PANGRAM, AppManager.baseFont10 ).height;
            AppManager.baseFont50Height = Util.measureString( Util.PANGRAM, AppManager.baseFont50Bold ).height;
        }

        public void picturePositionIndicatorDrawTo( java.awt.Graphics g1 )
        {
            Graphics2D g = (Graphics2D)g1;
            Font SMALL_FONT = AppManager.baseFont8;
            int small_font_offset = AppManager.baseFont8OffsetHeight;
            try {
                int key_width = AppManager.keyWidth;
                int width = picturePositionIndicator.getWidth();
                int height = picturePositionIndicator.getHeight();
                VsqFileEx vsq = AppManager.getVsqFile();

                #region 小節ごとの線
                int dashed_line_step = AppManager.getPositionQuantizeClock();
                for ( Iterator<VsqBarLineType> itr = vsq.getBarLineIterator( AppManager.clockFromXCoord( width ) ); itr.hasNext(); ) {
                    VsqBarLineType blt = itr.next();
                    int local_clock_step = 480 * 4 / blt.getLocalDenominator();
                    int x = AppManager.xCoordFromClocks( blt.clock() );
                    if ( blt.isSeparator() ) {
                        int current = blt.getBarCount() - vsq.getPreMeasure() + 1;
                        g.setColor( mColorR105G105B105 );
                        g.drawLine( x, 0, x, 49 );
                        // 小節の数字
                        //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                        g.setColor( Color.black );
                        g.setFont( SMALL_FONT );
                        g.drawString( current + "", x + 4, 8 - small_font_offset + 1 );
                        //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
                    } else {
                        g.setColor( mColorR105G105B105 );
                        g.drawLine( x, 11, x, 16 );
                        g.drawLine( x, 26, x, 31 );
                        g.drawLine( x, 41, x, 46 );
                    }
                    if ( dashed_line_step > 1 && AppManager.isGridVisible() ) {
                        int numDashedLine = local_clock_step / dashed_line_step;
                        for ( int i = 1; i < numDashedLine; i++ ) {
                            int x2 = AppManager.xCoordFromClocks( blt.clock() + i * dashed_line_step );
                            g.setColor( mColorR065G065B065 );
                            g.drawLine( x2, 9 + 5, x2, 14 + 3 );
                            g.drawLine( x2, 24 + 5, x2, 29 + 3 );
                            g.drawLine( x2, 39 + 5, x2, 44 + 3 );
                        }
                    }
                }
                #endregion

                if ( vsq != null ) {
                    #region 拍子の変更
                    int c = vsq.TimesigTable.size();
                    for ( int i = 0; i < c; i++ ) {
                        TimeSigTableEntry itemi = vsq.TimesigTable.get( i );
                        int clock = itemi.Clock;
                        int barcount = itemi.BarCount;
                        int x = AppManager.xCoordFromClocks( clock );
                        if ( width < x ) {
                            break;
                        }
                        String s = itemi.Numerator + "/" + itemi.Denominator;
                        g.setFont( SMALL_FONT );
                        if ( AppManager.itemSelection.isTimesigContains( barcount ) ) {
                            g.setColor( AppManager.getHilightColor() );
                            g.drawString( s, x + 4, 40 - small_font_offset + 1 );
                        } else {
                            g.setColor( Color.black );
                            g.drawString( s, x + 4, 40 - small_font_offset + 1 );
                        }

                        if ( mPositionIndicatorMouseDownMode == PositionIndicatorMouseDownMode.TIMESIG ) {
                            if ( AppManager.itemSelection.isTimesigContains( barcount ) ) {
                                int edit_clock_x = AppManager.xCoordFromClocks( vsq.getClockFromBarCount( AppManager.itemSelection.getTimesig( barcount ).editing.BarCount ) );
                                g.setColor( mColorR187G187B255 );
                                g.drawLine( edit_clock_x - 1, 32,
                                            edit_clock_x - 1, picturePositionIndicator.getHeight() - 1 );
                                g.setColor( mColorR007G007B151 );
                                g.drawLine( edit_clock_x, 32,
                                            edit_clock_x, picturePositionIndicator.getHeight() - 1 );
                            }
                        }
                    }
                    #endregion

                    #region テンポの変更
                    g.setFont( SMALL_FONT );
                    c = vsq.TempoTable.size();
                    for ( int i = 0; i < c; i++ ) {
                        TempoTableEntry itemi = vsq.TempoTable.get( i );
                        int clock = itemi.Clock;
                        int x = AppManager.xCoordFromClocks( clock );
                        if ( width < x ) {
                            break;
                        }
                        String s = PortUtil.formatDecimal( "#.00", 60e6 / (float)itemi.Tempo );
                        if ( AppManager.itemSelection.isTempoContains( clock ) ) {
                            g.setColor( AppManager.getHilightColor() );
                            g.drawString( s, x + 4, 24 - small_font_offset + 1 );
                        } else {
                            g.setColor( Color.black );
                            g.drawString( s, x + 4, 24 - small_font_offset + 1 );
                        }

                        if ( mPositionIndicatorMouseDownMode == PositionIndicatorMouseDownMode.TEMPO ) {
                            if ( AppManager.itemSelection.isTempoContains( clock ) ) {
                                int edit_clock_x = AppManager.xCoordFromClocks( AppManager.itemSelection.getTempo( clock ).editing.Clock );
                                g.setColor( mColorR187G187B255 );
                                g.drawLine( edit_clock_x - 1, 18,
                                            edit_clock_x - 1, 32 );
                                g.setColor( mColorR007G007B151 );
                                g.drawLine( edit_clock_x, 18,
                                            edit_clock_x, 32 );
                            }
                        }
                    }
                    #endregion
                }

                #region 現在のマーカー
                // ソングポジション
                float xoffset = key_width + AppManager.keyOffset - controller.getStartToDrawX();
                int marker_x = (int)(AppManager.getCurrentClock() * controller.getScaleX() + xoffset);
                if ( key_width <= marker_x && marker_x <= width ) {
                    g.setStroke( new BasicStroke( 2.0f ) );
                    g.setColor( Color.white );
                    g.drawLine( marker_x, 0, marker_x, height );
                    g.setStroke( new BasicStroke() );
                }

                // スタートマーカーとエンドマーカー
                boolean right = false;
                boolean left = false;
                if ( vsq.config.StartMarkerEnabled ) {
                    int x = AppManager.xCoordFromClocks( vsq.config.StartMarker );
                    if ( x < key_width ) {
                        left = true;
                    } else if ( width < x ) {
                        right = true;
                    } else {
                        g.drawImage(
                            Resources.get_start_marker(), x, 3, this );
                    }
                }
                if ( vsq.config.EndMarkerEnabled ) {
                    int x = AppManager.xCoordFromClocks( vsq.config.EndMarker ) - 6;
                    if ( x < key_width ) {
                        left = true;
                    } else if ( width < x ) {
                        right = true;
                    } else {
                        g.drawImage(
                            Resources.get_end_marker(), x, 3, this );
                    }
                }

                // 範囲外にスタートマーカーとエンドマーカーがある場合のマーク
                if ( right ) {
                    g.setColor( Color.white );
                    g.fillPolygon(
                        new int[] { width - 6, width, width - 6 },
                        new int[] { 3, 10, 16 },
                        3 );
                }
                if ( left ) {
                    g.setColor( Color.white );
                    g.fillPolygon(
                        new int[] { key_width + 7, key_width + 1, key_width + 7 },
                        new int[] { 3, 10, 16 },
                        3 );
                }
                #endregion

                #region TEMPO & BEAT
                // TEMPO BEATの文字の部分。小節数が被っている可能性があるので、塗り潰す
                g.setColor( picturePositionIndicator.getBackground() );
                g.fillRect( 0, 0, AppManager.keyWidth, 48 );
                // 横ライン上
                g.setColor( new Color( 104, 104, 104 ) );
                g.drawLine( 0, 17, width, 17 );
                // 横ライン中央
                g.drawLine( 0, 32, width, 32 );
                // 横ライン下
                g.drawLine( 0, 47, width, 47 );
                // 縦ライン
                g.drawLine( AppManager.keyWidth, 0, AppManager.keyWidth, 48 );
                /* TEMPO&BEATとピアノロールの境界 */
                g.drawLine( AppManager.keyWidth, 48, width - 18, 48 );
                g.setFont( SMALL_FONT );
                g.setColor( Color.black );
                g.drawString( "TEMPO", 11, 24 - small_font_offset + 1 );
                g.drawString( "BEAT", 11, 40 - small_font_offset + 1 );
                #endregion
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".picturePositionIndicatorDrawTo; ex=" + ex + "\n" );
                serr.println( "FormMain#picturePositionIndicatorDrawTo; ex=" + ex );
            }
        }

        /// <summary>
        /// イベントハンドラを登録します。
        /// </summary>
07243         public void registerEventHandlers()
        {
            this.Load += new BEventHandler( FormMain_Load );
            menuFileNew.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileNew.Click += new BEventHandler( handleFileNew_Click );
            menuFileOpen.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileOpen.Click += new BEventHandler( handleFileOpen_Click );
            menuFileSave.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileSave.Click += new BEventHandler( handleFileSave_Click );
            menuFileSaveNamed.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileSaveNamed.Click += new BEventHandler( menuFileSaveNamed_Click );
            menuFileOpenVsq.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileOpenVsq.Click += new BEventHandler( menuFileOpenVsq_Click );
            menuFileOpenUst.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileOpenUst.Click += new BEventHandler( menuFileOpenUst_Click );
            menuFileImport.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileImportMidi.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileImportMidi.Click += new BEventHandler( menuFileImportMidi_Click );
            menuFileImportUst.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileImportUst.Click += new BEventHandler( menuFileImportUst_Click );
            menuFileImportVsq.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileImportVsq.Click += new BEventHandler( menuFileImportVsq_Click );
            menuFileExport.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileExport.DropDownOpening += new BEventHandler( menuFileExport_DropDownOpening );
            menuFileExportWave.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileExportWave.Click += new BEventHandler( menuFileExportWave_Click );
            menuFileExportParaWave.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileExportParaWave.Click += new BEventHandler( menuFileExportParaWave_Click );
            menuFileExportMidi.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileExportMidi.Click += new BEventHandler( menuFileExportMidi_Click );
            menuFileExportMusicXml.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileExportMusicXml.Click += new BEventHandler( menuFileExportMusicXml_Click );
            menuFileExportUst.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileExportUst.Click += new BEventHandler( menuFileExportUst_Click );
            menuFileExportVsq.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileExportVsq.Click += new BEventHandler( menuFileExportVsq_Click );
            menuFileExportVxt.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileExportVxt.Click += new BEventHandler( menuFileExportVxt_Click );
            menuFileRecent.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileRecentClear.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileRecentClear.Click += new BEventHandler( menuFileRecentClear_Click );
            menuFileQuit.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuFileQuit.Click += new BEventHandler( menuFileQuit_Click );
            menuEdit.DropDownOpening += new BEventHandler( menuEdit_DropDownOpening );
            menuEditUndo.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuEditUndo.Click += new BEventHandler( handleEditUndo_Click );
            menuEditRedo.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuEditRedo.Click += new BEventHandler( handleEditRedo_Click );
            menuEditCut.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuEditCut.Click += new BEventHandler( handleEditCut_Click );
            menuEditCopy.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuEditCopy.Click += new BEventHandler( handleEditCopy_Click );
            menuEditPaste.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuEditPaste.Click += new BEventHandler( handleEditPaste_Click );
            menuEditDelete.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuEditDelete.Click += new BEventHandler( menuEditDelete_Click );
            menuEditAutoNormalizeMode.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuEditAutoNormalizeMode.Click += new BEventHandler( menuEditAutoNormalizeMode_Click );
            menuEditSelectAll.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuEditSelectAll.Click += new BEventHandler( menuEditSelectAll_Click );
            menuEditSelectAllEvents.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuEditSelectAllEvents.Click += new BEventHandler( menuEditSelectAllEvents_Click );
            menuVisualOverview.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualControlTrack.CheckedChanged += new BEventHandler( menuVisualControlTrack_CheckedChanged );
            menuVisualControlTrack.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualMixer.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualMixer.Click += new BEventHandler( menuVisualMixer_Click );
            menuVisualWaveform.CheckedChanged += new BEventHandler( menuVisualWaveform_CheckedChanged );
            menuVisualWaveform.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualProperty.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualProperty.CheckedChanged += new BEventHandler( menuVisualProperty_CheckedChanged );
            menuVisualGridline.CheckedChanged += new BEventHandler( menuVisualGridline_CheckedChanged );
            menuVisualGridline.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualIconPalette.Click += new BEventHandler( menuVisualIconPalette_Click );
            menuVisualIconPalette.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualStartMarker.Click += new BEventHandler( handleStartMarker_Click );
            menuVisualStartMarker.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualEndMarker.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualEndMarker.Click += new BEventHandler( handleEndMarker_Click );
            menuVisualLyrics.CheckedChanged += new BEventHandler( menuVisualLyrics_CheckedChanged );
            menuVisualLyrics.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualNoteProperty.CheckedChanged += new BEventHandler( menuVisualNoteProperty_CheckedChanged );
            menuVisualNoteProperty.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualPitchLine.CheckedChanged += new BEventHandler( menuVisualPitchLine_CheckedChanged );
            menuVisualPitchLine.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualPluginUi.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuVisualPluginUi.DropDownOpening += new BEventHandler( menuVisualPluginUi_DropDownOpening );
            menuVisualPluginUiVocaloid1.Click += new BEventHandler( menuVisualPluginUiVocaloidCommon_Click );
            menuVisualPluginUiVocaloid2.Click += new BEventHandler( menuVisualPluginUiVocaloidCommon_Click );
            menuVisualPluginUiAquesTone.Click += new BEventHandler( menuVisualPluginUiAquesTone_Click );
            menuJob.DropDownOpening += new BEventHandler( menuJob_DropDownOpening );
            menuJobNormalize.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuJobNormalize.Click += new BEventHandler( menuJobNormalize_Click );
            menuJobInsertBar.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuJobInsertBar.Click += new BEventHandler( menuJobInsertBar_Click );
            menuJobDeleteBar.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuJobDeleteBar.Click += new BEventHandler( menuJobDeleteBar_Click );
            menuJobRandomize.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuJobRandomize.Click += new BEventHandler( menuJobRandomize_Click );
            menuJobConnect.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuJobConnect.Click += new BEventHandler( menuJobConnect_Click );
            menuJobLyric.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuJobLyric.Click += new BEventHandler( menuJobLyric_Click );
            menuTrack.DropDownOpening += new BEventHandler( menuTrack_DropDownOpening );
            menuTrackOn.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackBgm.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackOn.Click += new BEventHandler( handleTrackOn_Click );
            menuTrackAdd.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackAdd.Click += new BEventHandler( menuTrackAdd_Click );
            menuTrackCopy.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackCopy.Click += new BEventHandler( menuTrackCopy_Click );
            menuTrackChangeName.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackChangeName.Click += new BEventHandler( menuTrackChangeName_Click );
            menuTrackDelete.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackDelete.Click += new BEventHandler( menuTrackDelete_Click );
            menuTrackRenderCurrent.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackRenderCurrent.Click += new BEventHandler( menuTrackRenderCurrent_Click );
            menuTrackRenderAll.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackRenderAll.Click += new BEventHandler( handleTrackRenderAll_Click );
            menuTrackOverlay.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackOverlay.Click += new BEventHandler( menuTrackOverlay_Click );
            menuTrackRenderer.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackRenderer.DropDownOpening += new BEventHandler( menuTrackRenderer_DropDownOpening );
            menuTrackRendererVOCALOID1.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackRendererVOCALOID1.Click += new BEventHandler( handleChangeRenderer );
            menuTrackRendererVOCALOID2.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackRendererVOCALOID2.Click += new BEventHandler( handleChangeRenderer );
            menuTrackRendererUtau.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            //UTAUはresamplerを識別するのでmenuTrackRendererUtauのサブアイテムのClickイベントを拾う
            //menuTrackRendererUtau.Click += new BEventHandler( handleChangeRenderer );
            menuTrackRendererVCNT.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackRendererVCNT.Click += new BEventHandler( handleChangeRenderer );
            menuTrackRendererAquesTone.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuTrackRendererAquesTone.Click += new BEventHandler( handleChangeRenderer );
            menuLyric.DropDownOpening += new BEventHandler( menuLyric_DropDownOpening );
            menuLyricCopyVibratoToPreset.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuLyricExpressionProperty.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuLyricExpressionProperty.Click += new BEventHandler( menuLyricExpressionProperty_Click );
            menuLyricVibratoProperty.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuLyricVibratoProperty.Click += new BEventHandler( menuLyricVibratoProperty_Click );
            menuLyricPhonemeTransformation.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuLyricDictionary.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuLyricDictionary.Click += new BEventHandler( menuLyricDictionary_Click );
            menuLyricPhonemeTransformation.Click += new BEventHandler( menuLyricPhonemeTransformation_Click );
            menuLyricApplyUtauParameters.Click += new BEventHandler( menuLyricApplyUtauParameters_Click );
            menuScriptUpdate.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuScriptUpdate.Click += new BEventHandler( menuScriptUpdate_Click );
            menuSettingPreference.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuSettingPreference.Click += new BEventHandler( menuSettingPreference_Click );
            menuSettingGameControler.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuSettingGameControlerSetting.Click += new BEventHandler( menuSettingGameControlerSetting_Click );
            menuSettingGameControlerLoad.Click += new BEventHandler( menuSettingGameControlerLoad_Click );
            menuSettingGameControlerRemove.Click += new BEventHandler( menuSettingGameControlerRemove_Click );
            menuSettingSequence.Click += new BEventHandler( menuSettingSequence_Click );
            menuSettingSequence.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuSettingShortcut.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuSettingShortcut.Click += new BEventHandler( menuSettingShortcut_Click );
            menuSettingVibratoPreset.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuSettingVibratoPreset.Click += new BEventHandler( menuSettingVibratoPreset_Click );
            menuSettingDefaultSingerStyle.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuSettingDefaultSingerStyle.Click += new BEventHandler( menuSettingDefaultSingerStyle_Click );
            menuSettingPaletteTool.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuSettingPositionQuantize.MouseEnter += new BEventHandler( handleMenuMouseEnter );
            menuSettingPositionQuantize04.Click += new BEventHandler( handlePositionQuantize );
            menuSettingPositionQuantize08.Click += new BEventHandler( handlePositionQuantize );
            menuSettingPositionQuantize16.Click += new BEventHandler( handlePositionQuantize );
            menuSettingPositionQuantize32.Click += new BEventHandler( handlePositionQuantize );
            menuSettingPositionQuantize64.Click += new BEventHandler( handlePositionQuantize );
            menuSettingPositionQuantize128.Click += new BEventHandler( handlePositionQuantize );
            menuSettingPositionQuantizeOff.Click += new BEventHandler( handlePositionQuantize );
            menuSettingPositionQuantizeTriplet.Click += new BEventHandler( handlePositionQuantizeTriplet_Click );
#if JAVA
            menuWindowMinimize.Click += new BEventHandler( menuWindowMinimize_Click );
#endif
            menuHelpAbout.Click += new BEventHandler( menuHelpAbout_Click );
            menuHelpManual.Click += new BEventHandler( menuHelpManual_Click );
            menuHelpLogSwitch.CheckedChanged += new BEventHandler( menuHelpLogSwitch_CheckedChanged );
            menuHelpLogOpen.Click += new BEventHandler( menuHelpLogOpen_Click );
            menuHelpDebug.Click += new BEventHandler( menuHelpDebug_Click );
            menuHiddenEditLyric.Click += new BEventHandler( menuHiddenEditLyric_Click );
            menuHiddenEditFlipToolPointerPencil.Click += new BEventHandler( menuHiddenEditFlipToolPointerPencil_Click );
            menuHiddenEditFlipToolPointerEraser.Click += new BEventHandler( menuHiddenEditFlipToolPointerEraser_Click );
            menuHiddenVisualForwardParameter.Click += new BEventHandler( menuHiddenVisualForwardParameter_Click );
            menuHiddenVisualBackwardParameter.Click += new BEventHandler( menuHiddenVisualBackwardParameter_Click );
            menuHiddenTrackNext.Click += new BEventHandler( menuHiddenTrackNext_Click );
            menuHiddenTrackBack.Click += new BEventHandler( menuHiddenTrackBack_Click );
            menuHiddenCopy.Click += new BEventHandler( handleEditCopy_Click );
            menuHiddenPaste.Click += new BEventHandler( handleEditPaste_Click );
            menuHiddenCut.Click += new BEventHandler( handleEditCut_Click );
            menuHiddenSelectBackward.Click += new BEventHandler( menuHiddenSelectBackward_Click );
            menuHiddenSelectForward.Click += new BEventHandler( menuHiddenSelectForward_Click );
            menuHiddenMoveUp.Click += new BEventHandler( menuHiddenMoveUp_Click );
            menuHiddenMoveDown.Click += new BEventHandler( menuHiddenMoveDown_Click );
            menuHiddenMoveLeft.Click += new BEventHandler( menuHiddenMoveLeft_Click );
            menuHiddenMoveRight.Click += new BEventHandler( menuHiddenMoveRight_Click );
            menuHiddenLengthen.Click += new BEventHandler( menuHiddenLengthen_Click );
            menuHiddenShorten.Click += new BEventHandler( menuHiddenShorten_Click );
            menuHiddenGoToEndMarker.Click += new BEventHandler( menuHiddenGoToEndMarker_Click );
            menuHiddenGoToStartMarker.Click += new BEventHandler( menuHiddenGoToStartMarker_Click );
            menuHiddenPlayFromStartMarker.Click += new BEventHandler( menuHiddenPlayFromStartMarker_Click );
            menuHiddenPrintPoToCSV.Click += new BEventHandler( menuHiddenPrintPoToCSV_Click );
            menuHiddenFlipCurveOnPianorollMode.Click += new BEventHandler( menuHiddenFlipCurveOnPianorollMode_Click );

            cMenuPiano.Opening += new BCancelEventHandler( cMenuPiano_Opening );
            cMenuPianoPointer.Click += new BEventHandler( cMenuPianoPointer_Click );
            cMenuPianoPencil.Click += new BEventHandler( cMenuPianoPencil_Click );
            cMenuPianoEraser.Click += new BEventHandler( cMenuPianoEraser_Click );
            cMenuPianoCurve.Click += new BEventHandler( cMenuPianoCurve_Click );
            cMenuPianoFixed01.Click += new BEventHandler( cMenuPianoFixed01_Click );
            cMenuPianoFixed02.Click += new BEventHandler( cMenuPianoFixed02_Click );
            cMenuPianoFixed04.Click += new BEventHandler( cMenuPianoFixed04_Click );
            cMenuPianoFixed08.Click += new BEventHandler( cMenuPianoFixed08_Click );
            cMenuPianoFixed16.Click += new BEventHandler( cMenuPianoFixed16_Click );
            cMenuPianoFixed32.Click += new BEventHandler( cMenuPianoFixed32_Click );
            cMenuPianoFixed64.Click += new BEventHandler( cMenuPianoFixed64_Click );
            cMenuPianoFixed128.Click += new BEventHandler( cMenuPianoFixed128_Click );
            cMenuPianoFixedOff.Click += new BEventHandler( cMenuPianoFixedOff_Click );
            cMenuPianoFixedTriplet.Click += new BEventHandler( cMenuPianoFixedTriplet_Click );
            cMenuPianoFixedDotted.Click += new BEventHandler( cMenuPianoFixedDotted_Click );
            cMenuPianoQuantize04.Click += new BEventHandler( handlePositionQuantize );
            cMenuPianoQuantize08.Click += new BEventHandler( handlePositionQuantize );
            cMenuPianoQuantize16.Click += new BEventHandler( handlePositionQuantize );
            cMenuPianoQuantize32.Click += new BEventHandler( handlePositionQuantize );
            cMenuPianoQuantize64.Click += new BEventHandler( handlePositionQuantize );
            cMenuPianoQuantize128.Click += new BEventHandler( handlePositionQuantize );
            cMenuPianoQuantizeOff.Click += new BEventHandler( handlePositionQuantize );
            cMenuPianoQuantizeTriplet.Click += new BEventHandler( handlePositionQuantizeTriplet_Click );
            cMenuPianoGrid.Click += new BEventHandler( cMenuPianoGrid_Click );
            cMenuPianoUndo.Click += new BEventHandler( cMenuPianoUndo_Click );
            cMenuPianoRedo.Click += new BEventHandler( cMenuPianoRedo_Click );
            cMenuPianoCut.Click += new BEventHandler( cMenuPianoCut_Click );
            cMenuPianoCopy.Click += new BEventHandler( cMenuPianoCopy_Click );
            cMenuPianoPaste.Click += new BEventHandler( cMenuPianoPaste_Click );
            cMenuPianoDelete.Click += new BEventHandler( cMenuPianoDelete_Click );
            cMenuPianoSelectAll.Click += new BEventHandler( cMenuPianoSelectAll_Click );
            cMenuPianoSelectAllEvents.Click += new BEventHandler( cMenuPianoSelectAllEvents_Click );
            cMenuPianoImportLyric.Click += new BEventHandler( cMenuPianoImportLyric_Click );
            cMenuPianoExpressionProperty.Click += new BEventHandler( cMenuPianoProperty_Click );
            cMenuPianoVibratoProperty.Click += new BEventHandler( cMenuPianoVibratoProperty_Click );
            cMenuTrackTab.Opening += new BCancelEventHandler( cMenuTrackTab_Opening );
            cMenuTrackTabTrackOn.Click += new BEventHandler( handleTrackOn_Click );
            cMenuTrackTabAdd.Click += new BEventHandler( cMenuTrackTabAdd_Click );
            cMenuTrackTabCopy.Click += new BEventHandler( cMenuTrackTabCopy_Click );
            cMenuTrackTabChangeName.Click += new BEventHandler( cMenuTrackTabChangeName_Click );
            cMenuTrackTabDelete.Click += new BEventHandler( cMenuTrackTabDelete_Click );
            cMenuTrackTabRenderCurrent.Click += new BEventHandler( cMenuTrackTabRenderCurrent_Click );
            cMenuTrackTabRenderAll.Click += new BEventHandler( handleTrackRenderAll_Click );
            cMenuTrackTabOverlay.Click += new BEventHandler( cMenuTrackTabOverlay_Click );
            cMenuTrackTabRenderer.DropDownOpening += new BEventHandler( cMenuTrackTabRenderer_DropDownOpening );
            cMenuTrackTabRendererVOCALOID1.Click += new BEventHandler( handleChangeRenderer );
            cMenuTrackTabRendererVOCALOID2.Click += new BEventHandler( handleChangeRenderer );
            cMenuTrackTabRendererStraight.Click += new BEventHandler( handleChangeRenderer );
            cMenuTrackTabRendererAquesTone.Click += new BEventHandler( handleChangeRenderer );
            cMenuTrackSelector.Opening += new BCancelEventHandler( cMenuTrackSelector_Opening );
            cMenuTrackSelectorPointer.Click += new BEventHandler( cMenuTrackSelectorPointer_Click );
            cMenuTrackSelectorPencil.Click += new BEventHandler( cMenuTrackSelectorPencil_Click );
            cMenuTrackSelectorLine.Click += new BEventHandler( cMenuTrackSelectorLine_Click );
            cMenuTrackSelectorEraser.Click += new BEventHandler( cMenuTrackSelectorEraser_Click );
            cMenuTrackSelectorCurve.Click += new BEventHandler( cMenuTrackSelectorCurve_Click );
            cMenuTrackSelectorUndo.Click += new BEventHandler( cMenuTrackSelectorUndo_Click );
            cMenuTrackSelectorRedo.Click += new BEventHandler( cMenuTrackSelectorRedo_Click );
            cMenuTrackSelectorCut.Click += new BEventHandler( cMenuTrackSelectorCut_Click );
            cMenuTrackSelectorCopy.Click += new BEventHandler( cMenuTrackSelectorCopy_Click );
            cMenuTrackSelectorPaste.Click += new BEventHandler( cMenuTrackSelectorPaste_Click );
            cMenuTrackSelectorDelete.Click += new BEventHandler( cMenuTrackSelectorDelete_Click );
            cMenuTrackSelectorDeleteBezier.Click += new BEventHandler( cMenuTrackSelectorDeleteBezier_Click );
            cMenuTrackSelectorSelectAll.Click += new BEventHandler( cMenuTrackSelectorSelectAll_Click );
            cMenuPositionIndicatorEndMarker.Click += new BEventHandler( cMenuPositionIndicatorEndMarker_Click );
            cMenuPositionIndicatorStartMarker.Click += new BEventHandler( cMenuPositionIndicatorStartMarker_Click );
            trackBar.ValueChanged += new BEventHandler( trackBar_ValueChanged );
            trackBar.Enter += new BEventHandler( trackBar_Enter );
            bgWorkScreen.DoWork += new BDoWorkEventHandler( bgWorkScreen_DoWork );
            timer.Tick += new BEventHandler( timer_Tick );
            pictKeyLengthSplitter.MouseMove += new BMouseEventHandler( pictKeyLengthSplitter_MouseMove );
            pictKeyLengthSplitter.MouseDown += new BMouseEventHandler( pictKeyLengthSplitter_MouseDown );
            pictKeyLengthSplitter.MouseUp += new BMouseEventHandler( pictKeyLengthSplitter_MouseUp );
            panelOverview.KeyUp += new BKeyEventHandler( handleSpaceKeyUp );
            panelOverview.KeyDown += new BKeyEventHandler( handleSpaceKeyDown );
            vScroll.ValueChanged += new BEventHandler( vScroll_ValueChanged );
            //this.Resize += new BEventHandler( handleVScrollResize );
            pictPianoRoll.Resize += new BEventHandler( handleVScrollResize );
            vScroll.Enter += new BEventHandler( vScroll_Enter );
            hScroll.ValueChanged += new BEventHandler( hScroll_ValueChanged );
            hScroll.Resize += new BEventHandler( hScroll_Resize );
            hScroll.Enter += new BEventHandler( hScroll_Enter );
            picturePositionIndicator.PreviewKeyDown += new BPreviewKeyDownEventHandler( picturePositionIndicator_PreviewKeyDown );
            picturePositionIndicator.MouseMove += new BMouseEventHandler( picturePositionIndicator_MouseMove );
            picturePositionIndicator.MouseClick += new BMouseEventHandler( picturePositionIndicator_MouseClick );
            picturePositionIndicator.MouseDoubleClick += new BMouseEventHandler( picturePositionIndicator_MouseDoubleClick );
            picturePositionIndicator.MouseDown += new BMouseEventHandler( picturePositionIndicator_MouseDown );
            picturePositionIndicator.MouseUp += new BMouseEventHandler( picturePositionIndicator_MouseUp );
            picturePositionIndicator.Paint += new BPaintEventHandler( picturePositionIndicator_Paint );
            pictPianoRoll.PreviewKeyDown += new BPreviewKeyDownEventHandler( pictPianoRoll_PreviewKeyDown );
            pictPianoRoll.KeyUp += new BKeyEventHandler( handleSpaceKeyUp );
            pictPianoRoll.KeyUp += new BKeyEventHandler( pictPianoRoll_KeyUp );
            pictPianoRoll.MouseMove += new BMouseEventHandler( pictPianoRoll_MouseMove );
            pictPianoRoll.MouseDoubleClick += new BMouseEventHandler( pictPianoRoll_MouseDoubleClick );
            pictPianoRoll.MouseClick += new BMouseEventHandler( pictPianoRoll_MouseClick );
            pictPianoRoll.MouseDown += new BMouseEventHandler( pictPianoRoll_MouseDown );
            pictPianoRoll.MouseUp += new BMouseEventHandler( pictPianoRoll_MouseUp );
            pictPianoRoll.KeyDown += new BKeyEventHandler( handleSpaceKeyDown );
            waveView.MouseDoubleClick += new BMouseEventHandler( waveView_MouseDoubleClick );
            waveView.MouseDown += new BMouseEventHandler( waveView_MouseDown );
            waveView.MouseUp += new BMouseEventHandler( waveView_MouseUp );
            waveView.MouseMove += new BMouseEventHandler( waveView_MouseMove );
#if !JAVA
            this.DragEnter += new System.Windows.Forms.DragEventHandler( FormMain_DragEnter );
            this.DragDrop += new System.Windows.Forms.DragEventHandler( FormMain_DragDrop );
            this.DragOver += new System.Windows.Forms.DragEventHandler( FormMain_DragOver );
            this.DragLeave += new BEventHandler( FormMain_DragLeave );
#endif

#if JAVA
            buttonVZoom.clickEvent.add( new BEventHandler( this, "buttonVZoom_Click" ) );
            buttonVMooz.clickEvent.add( new BEventHandler( this, "buttonVMooz_Click" ) );
#else
            pictureBox2.MouseDown += new BMouseEventHandler( pictureBox2_MouseDown );
            pictureBox2.MouseUp += new BMouseEventHandler( pictureBox2_MouseUp );
            pictureBox2.Paint += new BPaintEventHandler( pictureBox2_Paint );
#endif
#if JAVA
            stripBtnFileNew.clickEvent.add( new BEventHandler( this, "handleFileNew_Click" ) );
            stripBtnFileNew.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnFileOpen.clickEvent.add( new BEventHandler( this, "handleFileOpen_Click" ) );
            stripBtnFileOpen.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnFileSave.clickEvent.add( new BEventHandler( this, "handleFileSave_Click" ) );
            stripBtnFileSave.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnCut.clickEvent.add( new BEventHandler( this, "handleEditCut_Click" ) );
            stripBtnCut.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnCopy.clickEvent.add( new BEventHandler( this, "handleEditCopy_Click" ) );
            stripBtnCopy.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnPaste.clickEvent.add( new BEventHandler( this, "handleEditPaste_Click" ) );
            stripBtnPaste.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnUndo.clickEvent.add( new BEventHandler( this, "handleEditUndo_Click" ) );
            stripBtnUndo.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnRedo.clickEvent.add( new BEventHandler( this, "handleEditRedo_Click" ) );
            stripBtnRedo.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );

            stripBtnMoveTop.clickEvent.add( new BEventHandler( this, "stripBtnMoveTop_Click" ) );
            stripBtnMoveTop.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnRewind.clickEvent.add( new BEventHandler( this, "stripBtnRewind_Click" ) );
            stripBtnRewind.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnForward.clickEvent.add( new BEventHandler( this, "stripBtnForward_Click" ) );
            stripBtnForward.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnMoveEnd.clickEvent.add( new BEventHandler( this, "stripBtnMoveEnd_Click" ) );
            stripBtnMoveEnd.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnPlay.clickEvent.add( new BEventHandler( this, "stripBtnPlay_Click" ) );
            stripBtnPlay.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnScroll.checkedChangedEvent.add( new BEventHandler( this, "stripBtnScroll_CheckedChanged" ) );
            stripBtnScroll.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnLoop.checkedChangedEvent.add( new BEventHandler( this, "stripBtnLoop_CheckedChanged" ) );
            stripBtnLoop.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );

            stripBtnPointer.clickEvent.add( new BEventHandler( this, "stripBtnArrow_Click" ) );
            stripBtnPointer.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnPencil.clickEvent.add( new BEventHandler( this, "stripBtnPencil_Click" ) );
            stripBtnPencil.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnLine.clickEvent.add( new BEventHandler( this, "stripBtnLine_Click" ) );
            stripBtnLine.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnEraser.clickEvent.add( new BEventHandler( this, "stripBtnEraser_Click" ) );
            stripBtnEraser.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnGrid.clickEvent.add( new BEventHandler( this, "stripBtnGrid_Click" ) );
            stripBtnGrid.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnCurve.clickEvent.add( new BEventHandler( this, "stripBtnCurve_Click" ) );
            stripBtnCurve.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
            stripBtnStepSequencer.enterEvent.add( new BEventHandler( this, "handleStripButton_Enter" ) );
#else
            toolBarTool.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler( toolBarTool_ButtonClick );
            rebar.SizeChanged += new BEventHandler( toolStripContainer_TopToolStripPanel_SizeChanged );// toolStripContainer.TopToolStripPanel.SizeChanged += new BEventHandler( toolStripContainer_TopToolStripPanel_SizeChanged );
            stripDDBtnQuantize04.Click += handlePositionQuantize;
            stripDDBtnQuantize08.Click += handlePositionQuantize;
            stripDDBtnQuantize16.Click += handlePositionQuantize;
            stripDDBtnQuantize32.Click += handlePositionQuantize;
            stripDDBtnQuantize64.Click += handlePositionQuantize;
            stripDDBtnQuantize128.Click += handlePositionQuantize;
            stripDDBtnQuantizeOff.Click += handlePositionQuantize;
            stripDDBtnQuantizeTriplet.Click += handlePositionQuantizeTriplet_Click;
            toolBarFile.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler( toolBarFile_ButtonClick );
            toolBarPosition.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler( toolBarPosition_ButtonClick );
            toolBarMeasure.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler( toolBarMeasure_ButtonClick );
            toolBarMeasure.MouseDown += new BMouseEventHandler( toolBarMeasure_MouseDown );
#endif
            stripBtnStepSequencer.CheckedChanged += new BEventHandler( stripBtnStepSequencer_CheckedChanged );
            this.Deactivate += new BEventHandler( FormMain_Deactivate );
            this.Activated += new BEventHandler( FormMain_Activated );
            this.FormClosed += new BFormClosedEventHandler( FormMain_FormClosed );
            this.FormClosing += new BFormClosingEventHandler( FormMain_FormClosing );
            this.PreviewKeyDown += new BPreviewKeyDownEventHandler( FormMain_PreviewKeyDown );
            panelOverview.Enter += new BEventHandler( panelOverview_Enter );
        }

        public void setResources()
        {
            try {
#if !JAVA
                this.stripLblGameCtrlMode.setIcon( new ImageIcon( Resources.get_slash() ) );
                this.stripLblMidiIn.setIcon( new ImageIcon( Resources.get_slash() ) );
#endif

#if JAVA
                stripBtnStepSequencer.setIcon( new ImageIcon( Resources.get_piano() ) );
#else
                this.stripBtnStepSequencer.Image = Resources.get_piano().image;
#endif
#if JAVA
                stripBtnFileNew.setIcon( new ImageIcon( Resources.get_disk__plus() ) );
                stripBtnFileOpen.setIcon( new ImageIcon( Resources.get_folder_horizontal_open() ) );
                stripBtnFileSave.setIcon( new ImageIcon( Resources.get_disk() ) );
                stripBtnCut.setIcon( new ImageIcon( Resources.get_scissors() ) );
                stripBtnCopy.setIcon( new ImageIcon( Resources.get_documents() ) );
                stripBtnPaste.setIcon( new ImageIcon( Resources.get_clipboard_paste() ) );
                stripBtnUndo.setIcon( new ImageIcon( Resources.get_arrow_skip_180() ) );
                stripBtnRedo.setIcon( new ImageIcon( Resources.get_arrow_skip() ) );

                stripBtnMoveTop.setIcon( new ImageIcon( Resources.get_control_stop_180() ) );
                stripBtnRewind.setIcon( new ImageIcon( Resources.get_control_double_180() ) );
                stripBtnForward.setIcon( new ImageIcon( Resources.get_control_double() ) );
                stripBtnMoveEnd.setIcon( new ImageIcon( Resources.get_control_stop() ) );
                stripBtnPlay.setIcon( new ImageIcon( Resources.get_control() ) );
                stripBtnScroll.setIcon( new ImageIcon( Resources.get_arrow_circle_double() ) );
                stripBtnLoop.setIcon( new ImageIcon( Resources.get_arrow_return() ) );

                stripBtnPointer.setIcon( new ImageIcon( Resources.get_arrow_135() ) );
                stripBtnPencil.setIcon( new ImageIcon( Resources.get_pencil() ) );
                stripBtnLine.setIcon( new ImageIcon( Resources.get_layer_shape_line() ) );
                stripBtnEraser.setIcon( new ImageIcon( Resources.get_eraser() ) );
                stripBtnGrid.setIcon( new ImageIcon( Resources.get_ruler_crop() ) );
                stripBtnCurve.setIcon( new ImageIcon( Resources.get_layer_shape_curve() ) );

                buttonVZoom.setIcon( new ImageIcon( Resources.get_plus8x8() ) );
                buttonVMooz.setIcon( new ImageIcon( Resources.get_minus8x8() ) );
#endif
                setIconImage( Resources.get_icon() );
            } catch ( Exception ex ) {
                Logger.write( typeof( FormMain ) + ".setResources; ex=" + ex + "\n" );
                serr.println( "FormMain#setResources; ex=" + ex );
            }
        }
        #endregion // public methods

        #region event handlers
        public void menuWindowMinimize_Click( Object sender, BEventArgs e )
        {
            int state = this.getExtendedState();
            if( state != BForm.ICONIFIED ){
                setExtendedState( BForm.ICONIFIED );
            }
        }
        
        //BOOKMARK: panelOverview
        #region panelOverview
        public void panelOverview_Enter( Object sender, EventArgs e )
        {
            controller.navigationPanelGotFocus();
        }
        #endregion

        //BOOKMARK: inputTextBox
        #region AppManager.mInputTextBox
        public void mInputTextBox_KeyDown( Object sender, BKeyEventArgs e )
        {
#if DEBUG
            sout.println( "FormMain#mInputTextBox_KeyDown" );
#endif
#if JAVA
            int keycode = e.getKeyCode();
            int modifiers = e.getModifiers();
            boolean shift = (modifiers & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK;
            boolean tab = keycode == KeyEvent.VK_TAB;
            boolean enter = keycode == KeyEvent.VK_ENTER; 
#else
            boolean shift = (e.Modifiers & System.Windows.Forms.Keys.Shift) == System.Windows.Forms.Keys.Shift;
            boolean tab = e.KeyCode == System.Windows.Forms.Keys.Tab;
            boolean enter = e.KeyCode == System.Windows.Forms.Keys.Return;
#endif
            if ( tab || enter ) {
                executeLyricChangeCommand();
                int selected = AppManager.getSelected();
                int index = -1;
                int width = pictPianoRoll.getWidth();
                int height = pictPianoRoll.getHeight();
                int key_width = AppManager.keyWidth;
                VsqTrack track = AppManager.getVsqFile().Track.get( selected );
                track.sortEvent();
                if( tab ) {
                    int clock = 0;
                    int search_index = AppManager.itemSelection.getLastEvent().original.InternalID;
                    int c = track.getEventCount();
                    for ( int i = 0; i < c; i++ ) {
                        VsqEvent item = track.getEvent( i );
                        if ( item.InternalID == search_index ) {
                            index = i;
                            clock = item.Clock;
                            break;
                        }
                    }
                    if( shift ) {
                        // 1個前の音符イベントを検索
                        int tindex = -1;
                        for ( int i = track.getEventCount() - 1; i >= 0; i-- ) {
                            VsqEvent ve = track.getEvent( i );
                            if ( ve.ID.type == VsqIDType.Anote && i != index && ve.Clock <= clock ) {
                                tindex = i;
                                break;
                            }
                        }
                        index = tindex;
                    } else {
                        // 1個後の音符イベントを検索
                        int tindex = -1;
                        int c2 = track.getEventCount();
                        for ( int i = 0; i < c2; i++ ) {
                            VsqEvent ve = track.getEvent( i );
                            if ( ve.ID.type == VsqIDType.Anote && i != index && ve.Clock >= clock ) {
                                tindex = i;
                                break;
                            }
                        }
                        index = tindex;
                    }
                }
                if ( 0 <= index && index < track.getEventCount() ) {
                    AppManager.itemSelection.clearEvent();
                    VsqEvent item = track.getEvent( index );
                    AppManager.itemSelection.addEvent( item.InternalID );
                    int x = AppManager.xCoordFromClocks( item.Clock );
                    int y = AppManager.yCoordFromNote( item.ID.Note );
                    boolean phonetic_symbol_edit_mode = AppManager.mInputTextBox.isPhoneticSymbolEditMode();
                    showInputTextBox(
                        item.ID.LyricHandle.L0.Phrase,
                        item.ID.LyricHandle.L0.getPhoneticSymbol(),
                        new Point( x, y ),
                        phonetic_symbol_edit_mode );
                    int clWidth = (int)(AppManager.mInputTextBox.getWidth() * controller.getScaleXInv());

                    // 画面上にAppManager.mInputTextBoxが見えるように,移動
                    int SPACE = 20;
                    // vScrollやhScrollをいじった場合はfalseにする.
                    boolean refresh_screen = true;
                    // X軸方向について,見えるように移動
                    if ( x < key_width || width < x + AppManager.mInputTextBox.getWidth() ) {
                        int clock, clock_x;
                        if ( x < key_width ) {
                            // 左に隠れてしまう場合
                            clock = item.Clock;
                        } else {
                            // 右に隠れてしまう場合
                            clock = item.Clock + clWidth;
                        }
                        if( shift ){
                            // 左方向に移動していた場合
                            // 右から3分の1の位置に移動させる
                            clock_x = width - (width - key_width) / 3;
                        }else{
                            // 右方向に移動していた場合
                            clock_x = key_width + (width - key_width) / 3;
                        }
                        double draft_d = (key_width + AppManager.keyOffset - clock_x) * controller.getScaleXInv() + clock;
                        if ( draft_d < 0.0 ) {
                            draft_d = 0.0;
                        }
                        int draft = (int)draft_d;
                        if ( draft < hScroll.getMinimum() ) {
                            draft = hScroll.getMinimum();
                        } else if ( hScroll.getMaximum() < draft ) {
                            draft = hScroll.getMaximum();
                        }
                        refresh_screen = false;
                        hScroll.setValue( draft );
                    }
                    // y軸方向について,見えるように移動
                    int track_height = (int)(100 * controller.getScaleY());
                    if( y <= 0 || height - track_height  <= y ){
                        int note = item.ID.Note;
                        if( y <= 0 ){
                            // 上にはみ出してしまう場合
                            note = item.ID.Note + 1;
                        }else{
                            // 下にはみ出してしまう場合
                            note = item.ID.Note - 2;
                        }
                        if( 127 < note ){
                            note = 127;
                        }
                        if( note < 0 ){
                            note = 0;
                        }
                        ensureVisibleY( note );
                    }
                    if ( refresh_screen ) {
                        refreshScreen();
                    }
                } else {
                    int id = AppManager.itemSelection.getLastEvent().original.InternalID;
                    AppManager.itemSelection.clearEvent();
                    AppManager.itemSelection.addEvent( id );
                    hideInputTextBox();
                }
            }
        }

        public void mInputTextBox_KeyUp( Object sender, BKeyEventArgs e )
        {
#if DEBUG
            sout.println( "FormMain#mInputTextBox_KeyUp" );
#endif
#if JAVA
            boolean flip = (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN) && ((e.getModifiers() & InputEvent.ALT_MASK) == InputEvent.ALT_MASK);
            boolean hide = (e.getKeyCode() == KeyEvent.VK_ESCAPE);
#else
            bool flip = (e.KeyCode == System.Windows.Forms.Keys.Up || e.KeyCode == System.Windows.Forms.Keys.Down) && (PortUtil.getCurrentModifierKey() == InputEvent.ALT_MASK);
            bool hide = e.KeyCode == System.Windows.Forms.Keys.Escape;
#endif

            if ( flip ) {
                if ( AppManager.mInputTextBox.isVisible() ) {
                    flipInputTextBoxMode();
                }
            } else if ( hide ) {
                hideInputTextBox();
            }
        }

        public void mInputTextBox_ImeModeChanged( Object sender, EventArgs e )
        {
            mLastIsImeModeOn = AppManager.mInputTextBox.isImeModeOn();
        }

        public void mInputTextBox_KeyPress( Object sender, BKeyPressEventArgs e )
        {
#if DEBUG
            sout.println( "FormMain#mInputTextBox_KeyPress" );
#endif
#if !JAVA
            //           Enter                                  Tab
            e.Handled = (e.KeyChar == Convert.ToChar( 13 )) || (e.KeyChar == Convert.ToChar( 09 ));
#endif
        }
        #endregion

        //BOOKMARK: AppManager
        #region AppManager
        public void AppManager_EditedStateChanged( Object sender, boolean edited )
        {
            setEdited( edited );
        }

        public void AppManager_GridVisibleChanged( Object sender, EventArgs e )
        {
            menuVisualGridline.setSelected( AppManager.isGridVisible() );
#if JAVA
            stripBtnGrid.setSelected( AppManager.isGridVisible() );
#else
            stripBtnGrid.Pushed = AppManager.isGridVisible();
#endif
            cMenuPianoGrid.setSelected( AppManager.isGridVisible() );
        }

        public void AppManager_MainWindowFocusRequired( Object sender, EventArgs e )
        {
            this.requestFocus();
        }

        public void AppManager_PreviewAborted( Object sender, EventArgs e )
        {
#if DEBUG
            sout.println( "FormMain#AppManager_PreviewAborted" );
#endif
#if JAVA
            stripBtnPlay.setIcon( new ImageIcon( Resources.get_control() ) );
            stripBtnPlay.setText( _( "Play" ) );
#else
            stripBtnPlay.ImageKey = "control.png";
            stripBtnPlay.Text = _( "Play" );
#endif
            timer.stop();

            for ( int i = 0; i < AppManager.mDrawStartIndex.Length; i++ ) {
                AppManager.mDrawStartIndex[i] = 0;
            }
#if ENABLE_MIDI
            //MidiPlayer.stop();
#endif // ENABLE_MIDI
        }

        public void AppManager_PreviewStarted( Object sender, EventArgs e )
        {
#if DEBUG
            sout.println( "FormMain#AppManager_PreviewStarted" );
#endif
            AppManager.mAddingEvent = null;
            int selected = AppManager.getSelected();
            VsqFileEx vsq = AppManager.getVsqFile();
            RendererKind renderer = VsqFileEx.getTrackRendererKind( vsq.Track.get( selected ) );
            int clock = AppManager.getCurrentClock();
            mLastClock = clock;
            double now = PortUtil.getCurrentTime();
            AppManager.mPreviewStartedTime = now;
            timer.start();
#if JAVA
            stripBtnPlay.setIcon( new ImageIcon( Resources.get_control_pause() ) );
            stripBtnPlay.setText( _( "Stop" ) );
#else
            stripBtnPlay.ImageKey = "control_pause.png";
            stripBtnPlay.Text = _( "Stop" );
#endif
        }

        public void AppManager_SelectedToolChanged( Object sender, EventArgs e )
        {
            applySelectedTool();
        }

        public void ItemSelectionModel_SelectedEventChanged( Object sender, boolean selected_event_is_null )
        {
            menuEditCut.setEnabled( !selected_event_is_null );
            menuEditPaste.setEnabled( !selected_event_is_null );
            menuEditDelete.setEnabled( !selected_event_is_null );
            cMenuPianoCut.setEnabled( !selected_event_is_null );
            cMenuPianoCopy.setEnabled( !selected_event_is_null );
            cMenuPianoDelete.setEnabled( !selected_event_is_null );
            cMenuPianoExpressionProperty.setEnabled( !selected_event_is_null );
            menuLyricVibratoProperty.setEnabled( !selected_event_is_null );
            menuLyricExpressionProperty.setEnabled( !selected_event_is_null );
#if JAVA
            stripBtnCut.setEnabled( !selected_event_is_null );
            stripBtnCopy.setEnabled( !selected_event_is_null );
#else
            stripBtnCut.Enabled = !selected_event_is_null;
            stripBtnCopy.Enabled = !selected_event_is_null;
#endif
        }

        public void AppManager_UpdateBgmStatusRequired( Object sender, EventArgs e )
        {
            updateBgmMenuState();
        }

        public void AppManager_WaveViewRealoadRequired( Object sender, WaveViewRealoadRequiredEventArgs arg )
        {
            int track = arg.track;
            String file = arg.file;
            double sec_start = arg.secStart;
            double sec_end = arg.secEnd;
            if ( sec_start <= sec_end ) {
                waveView.reloadPartial( track - 1, file, sec_start, sec_end );
            } else {
                waveView.load( track - 1, file );
            }
        }
        #endregion

        //BOOKMARK: pictPianoRoll
        #region pictPianoRoll
        public void pictPianoRoll_KeyUp( Object sender, BKeyEventArgs e )
        {
            processSpecialShortcutKey( e, false );
        }

        public void pictPianoRoll_MouseClick( Object sender, BMouseEventArgs e )
        {
#if DEBUG
            AppManager.debugWriteLine( "pictPianoRoll_MouseClick" );
#endif
            int modefiers = PortUtil.getCurrentModifierKey();
            EditMode edit_mode = AppManager.getEditMode();

            boolean is_button_left = e.Button == BMouseButtons.Left;
            int selected = AppManager.getSelected();

            if ( e.Button == BMouseButtons.Left ) {
#if ENABLE_MOUSEHOVER
                if ( mMouseHoverThread != null ) {
                    mMouseHoverThread.Abort();
                }
#endif

                // クリック位置にIDが無いかどうかを検査
                ByRef<Rectangle> out_id_rect = new ByRef<Rectangle>( new Rectangle() );
                VsqEvent item = getItemAtClickedPosition( new Point( e.X, e.Y ), out_id_rect );
                Rectangle id_rect = out_id_rect.value;
#if DEBUG
                AppManager.debugWriteLine( "    (item==null)=" + (item == null) );
#endif
                if ( item != null &&
                     edit_mode != EditMode.MOVE_ENTRY_WAIT_MOVE &&
                     edit_mode != EditMode.MOVE_ENTRY &&
                     edit_mode != EditMode.MOVE_ENTRY_WHOLE_WAIT_MOVE &&
                     edit_mode != EditMode.MOVE_ENTRY_WHOLE &&
                     edit_mode != EditMode.EDIT_LEFT_EDGE &&
                     edit_mode != EditMode.EDIT_RIGHT_EDGE &&
                     edit_mode != EditMode.MIDDLE_DRAG &&
                     edit_mode != EditMode.CURVE_ON_PIANOROLL ) {
                    if ( (modefiers & InputEvent.SHIFT_MASK) != InputEvent.SHIFT_MASK && (modefiers & s_modifier_key) != s_modifier_key ) {
                        AppManager.itemSelection.clearEvent();
                    }
                    AppManager.itemSelection.addEvent( item.InternalID );
                    int internal_id = item.InternalID;
                    hideInputTextBox();
                    if ( AppManager.getSelectedTool() == EditTool.ERASER ) {
                        CadenciiCommand run = new CadenciiCommand( VsqCommand.generateCommandEventDelete( selected, internal_id ) );
                        AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                        setEdited( true );
                        AppManager.itemSelection.clearEvent();
                        return;
#if ENABLE_SCRIPT
                    } else if ( AppManager.getSelectedTool() == EditTool.PALETTE_TOOL ) {
                        Vector<Integer> internal_ids = new Vector<Integer>();
                        for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                            SelectedEventEntry see = itr.next();
                            internal_ids.add( see.original.InternalID );
                        }
                        BMouseButtons btn = e.Button;
                        if ( isMouseMiddleButtonDowned( btn ) ) {
                            btn = BMouseButtons.Middle;
                        }
                        boolean result = PaletteToolServer.invokePaletteTool( AppManager.mSelectedPaletteTool,
                                                                              selected,
                                                                              internal_ids.toArray( new Integer[] { } ),
                                                                              btn );
                        if ( result ) {
                            setEdited( true );
                            AppManager.itemSelection.clearEvent();
                            return;
                        }
#endif
                    }
                } else {
                    if ( edit_mode != EditMode.MOVE_ENTRY_WAIT_MOVE &&
                         edit_mode != EditMode.MOVE_ENTRY &&
                         edit_mode != EditMode.MOVE_ENTRY_WHOLE_WAIT_MOVE &&
                         edit_mode != EditMode.MOVE_ENTRY_WHOLE &&
                         edit_mode != EditMode.EDIT_LEFT_EDGE &&
                         edit_mode != EditMode.EDIT_RIGHT_EDGE &&
                         edit_mode != EditMode.EDIT_VIBRATO_DELAY ) {
                        if ( !AppManager.mIsPointerDowned ) {
                            AppManager.itemSelection.clearEvent();
                        }
                        hideInputTextBox();
                    }
                    if ( AppManager.getSelectedTool() == EditTool.ERASER ) {
                        // マウス位置にビブラートの波波があったら削除する
                        int stdx = controller.getStartToDrawX();
                        int stdy = controller.getStartToDrawY();
                        for ( int i = 0; i < AppManager.mDrawObjects.get( selected - 1 ).size(); i++ ) {
                            DrawObject dobj = AppManager.mDrawObjects.get( selected - 1 ).get( i );
                            if ( dobj.mRectangleInPixel.x + controller.getStartToDrawX() + dobj.mRectangleInPixel.width - stdx < 0 ) {
                                continue;
                            } else if ( pictPianoRoll.getWidth() < dobj.mRectangleInPixel.x + AppManager.keyWidth - stdx ) {
                                break;
                            }
                            Rectangle rc = new Rectangle( dobj.mRectangleInPixel.x + AppManager.keyWidth + dobj.mVibratoDelayInPixel - stdx,
                                                          dobj.mRectangleInPixel.y + (int)(100 * controller.getScaleY()) - stdy,
                                                          dobj.mRectangleInPixel.width - dobj.mVibratoDelayInPixel,
                                                          (int)(100 * controller.getScaleY()) );
                            if ( Utility.isInRect( new Point( e.X, e.Y ), rc ) ) {
                                //ビブラートの範囲なのでビブラートを消す
                                VsqEvent item3 = null;
                                VsqID item2 = null;
                                int internal_id = -1;
                                internal_id = dobj.mInternalID;
                                for ( Iterator<VsqEvent> itr = AppManager.getVsqFile().Track.get( selected ).getNoteEventIterator(); itr.hasNext(); ) {
                                    VsqEvent ve = itr.next();
                                    if ( ve.InternalID == dobj.mInternalID ) {
                                        item2 = (VsqID)ve.ID.clone();
                                        item3 = ve;
                                        break;
                                    }
                                }
                                if ( item2 != null ) {
                                    item2.VibratoHandle = null;
                                    CadenciiCommand run = new CadenciiCommand(
                                        VsqCommand.generateCommandEventChangeIDContaints( selected,
                                                                                          internal_id,
                                                                                          item2 ) );
                                    AppManager.editHistory.register( AppManager.getVsqFile().executeCommand( run ) );
                                    setEdited( true );
                                }
                                break;
                            }
                        }
                    }
                }
            } else if ( e.Button == BMouseButtons.Right ) {
                boolean show_context_menu = (e.X > AppManager.keyWidth);
#if ENABLE_MOUSEHOVER
                if ( mMouseHoverThread != null ) {
                    if ( !mMouseHoverThread.IsAlive && AppManager.editorConfig.PlayPreviewWhenRightClick ) {
                        show_context_menu = false;
                    }
                } else {
                    if ( AppManager.editorConfig.PlayPreviewWhenRightClick ) {
                        show_context_menu = false;
                    }
                }
#endif
                show_context_menu = AppManager.showContextMenuWhenRightClickedOnPianoroll ? (show_context_menu && !mMouseMoved) : false;
                if ( show_context_menu ) {
#if ENABLE_MOUSEHOVER
                    if ( mMouseHoverThread != null ) {
                        mMouseHoverThread.Abort();
                    }
#endif
                    ByRef<Rectangle> out_id_rect = new ByRef<Rectangle>();
                    VsqEvent item = getItemAtClickedPosition( new Point( e.X, e.Y ), out_id_rect );
                    Rectangle id_rect = out_id_rect.value;
                    if ( item != null ) {
                        if ( !AppManager.itemSelection.isEventContains( AppManager.getSelected(), item.InternalID ) ) {
                            AppManager.itemSelection.clearEvent();
                        }
                        AppManager.itemSelection.addEvent( item.InternalID );
                    }
                    boolean item_is_null = (item == null);
                    cMenuPianoCopy.setEnabled( !item_is_null );
                    cMenuPianoCut.setEnabled( !item_is_null );
                    cMenuPianoDelete.setEnabled( !item_is_null );
                    cMenuPianoImportLyric.setEnabled( !item_is_null );
                    cMenuPianoExpressionProperty.setEnabled( !item_is_null );

                    int clock = AppManager.clockFromXCoord( e.X );
                    cMenuPianoPaste.setEnabled( ((AppManager.clipboard.getCopiedItems().events.size() != 0) && (clock >= AppManager.getVsqFile().getPreMeasureClocks())) );
                    refreshScreen();

                    mContextMenuOpenedPosition = new Point( e.X, e.Y );
                    cMenuPiano.show( pictPianoRoll, e.X, e.Y );
                } else {
                    ByRef<Rectangle> out_id_rect = new ByRef<Rectangle>();
                    VsqEvent item = getItemAtClickedPosition( mButtonInitial, out_id_rect );
                    Rectangle id_rect = out_id_rect.value;
#if DEBUG
                    AppManager.debugWriteLine( "pitcPianoRoll_MouseClick; button is right; (item==null)=" + (item == null) );
#endif
                    if ( item != null ) {
                        int itemx = AppManager.xCoordFromClocks( item.Clock );
                        int itemy = AppManager.yCoordFromNote( item.ID.Note );
                    }
                }
            } else if ( e.Button == BMouseButtons.Middle ) {
#if ENABLE_SCRIPT
                if ( AppManager.getSelectedTool() == EditTool.PALETTE_TOOL ) {
                    ByRef<Rectangle> out_id_rect = new ByRef<Rectangle>();
                    VsqEvent item = getItemAtClickedPosition( new Point( e.X, e.Y ), out_id_rect );
                    Rectangle id_rect = out_id_rect.value;
                    if ( item != null ) {
                        AppManager.itemSelection.clearEvent();
                        AppManager.itemSelection.addEvent( item.InternalID );
                        Vector<Integer> internal_ids = new Vector<Integer>();
                        for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                            SelectedEventEntry see = itr.next();
                            internal_ids.add( see.original.InternalID );
                        }
                        boolean result = PaletteToolServer.invokePaletteTool( AppManager.mSelectedPaletteTool,
                                                                           AppManager.getSelected(),
                                                                           internal_ids.toArray( new Integer[] { } ),
                                                                           e.Button );
                        if ( result ) {
                            setEdited( true );
                            AppManager.itemSelection.clearEvent();
                            return;
                        }
                    }
                }
#endif
            }
        }

        public void pictPianoRoll_MouseDoubleClick( Object sender, BMouseEventArgs e )
        {
#if DEBUG
            AppManager.debugWriteLine( "FormMain#pictPianoRoll_MouseDoubleClick" );
#endif
            ByRef<Rectangle> out_rect = new ByRef<Rectangle>();
            VsqEvent item = getItemAtClickedPosition( new Point( e.X, e.Y ), out_rect );
            Rectangle rect = out_rect.value;
            int selected = AppManager.getSelected();
            VsqFileEx vsq = AppManager.getVsqFile();
            if ( item != null && item.ID.type == VsqIDType.Anote ) {
#if ENABLE_SCRIPT
                if ( AppManager.getSelectedTool() != EditTool.PALETTE_TOOL )
#endif

                {
                    AppManager.itemSelection.clearEvent();
                    AppManager.itemSelection.addEvent( item.InternalID );
#if ENABLE_MOUSEHOVER
                    mMouseHoverThread.Abort();
#endif
                    if ( !AppManager.editorConfig.KeepLyricInputMode ) {
                        mLastSymbolEditMode = false;
                    }
                    showInputTextBox(
                        item.ID.LyricHandle.L0.Phrase,
                        item.ID.LyricHandle.L0.getPhoneticSymbol(),
                        new Point( rect.x, rect.y ),
                        mLastSymbolEditMode );
                    refreshScreen();
                    return;
                }
            } else {
                AppManager.itemSelection.clearEvent();
                hideInputTextBox();
                if ( AppManager.editorConfig.ShowExpLine && AppManager.keyWidth <= e.X ) {
                    int stdx = controller.getStartToDrawX();
                    int stdy = controller.getStartToDrawY();
                    for ( Iterator<DrawObject> itr = AppManager.mDrawObjects.get( selected - 1 ).iterator(); itr.hasNext(); ) {
                        DrawObject dobj = itr.next();
                        // 表情コントロールプロパティを表示するかどうかを決める
                        rect = new Rectangle(
                            dobj.mRectangleInPixel.x + AppManager.keyWidth - stdx,
                            dobj.mRectangleInPixel.y - stdy + (int)(100 * controller.getScaleY()),
                            21,
                            (int)(100 * controller.getScaleY()) );
                        if ( Utility.isInRect( new Point( e.X, e.Y ), rect ) ) {
                            VsqEvent selectedEvent = null;
                            for ( Iterator<VsqEvent> itr2 = vsq.Track.get( selected ).getEventIterator(); itr2.hasNext(); ) {
                                VsqEvent ev = itr2.next();
                                if ( ev.InternalID == dobj.mInternalID ) {
                                    selectedEvent = ev;
                                    break;
                                }
                            }
                            if ( selectedEvent != null ) {
#if ENABLE_MOUSEHOVER
                                if ( mMouseHoverThread != null ) {
                                    mMouseHoverThread.Abort();
                                }
#endif
                                SynthesizerType type = SynthesizerType.VOCALOID2;
                                RendererKind kind = VsqFileEx.getTrackRendererKind( vsq.Track.get( selected ) );
                                if ( kind == RendererKind.VOCALOID1 ) {
                                    type = SynthesizerType.VOCALOID1;
                                }
                                FormNoteExpressionConfig dlg = null;
                                try {
                                    dlg = new FormNoteExpressionConfig( type, selectedEvent.ID.NoteHeadHandle );
                                    dlg.setPMBendDepth( selectedEvent.ID.PMBendDepth );
                                    dlg.setPMBendLength( selectedEvent.ID.PMBendLength );
                                    dlg.setPMbPortamentoUse( selectedEvent.ID.PMbPortamentoUse );
                                    dlg.setDEMdecGainRate( selectedEvent.ID.DEMdecGainRate );
                                    dlg.setDEMaccent( selectedEvent.ID.DEMaccent );
                                    dlg.setLocation( getFormPreferedLocation( dlg ) );
                                    BDialogResult dr = AppManager.showModalDialog( dlg, this );
                                    if ( dr == BDialogResult.OK ) {
                                        VsqID id = (VsqID)selectedEvent.ID.clone();
                                        id.PMBendDepth = dlg.getPMBendDepth();
                                        id.PMBendLength = dlg.getPMBendLength();
                                        id.PMbPortamentoUse = dlg.getPMbPortamentoUse();
                                        id.DEMdecGainRate = dlg.getDEMdecGainRate();
                                        id.DEMaccent = dlg.getDEMaccent();
                                        id.NoteHeadHandle = dlg.getEditedNoteHeadHandle();
                                        CadenciiCommand run = new CadenciiCommand(
                                            VsqCommand.generateCommandEventChangeIDContaints( selected, selectedEvent.InternalID, id ) );
                                        AppManager.editHistory.register( vsq.executeCommand( run ) );
                                        setEdited( true );
                                        refreshScreen();
                                    }
                                } catch ( Exception ex ) {
                                    Logger.write( typeof( FormMain ) + ".pictPianoRoll_MouseDoubleClick; ex=" + ex + "\n" );
                                    serr.println( typeof( FormMain ) + ".pictPianoRoll_MouseDoubleClick" + ex );
                                } finally {
                                    if ( dlg != null ) {
                                        try {
                                            dlg.close();
                                        } catch ( Exception ex2 ) {
                                            Logger.write( typeof( FormMain ) + ".pictPianoRoll_MouseDoubleClick; ex=" + ex2 + "\n" );
                                            serr.println( typeof( FormMain ) + ".pictPianoRoll_MouseDoubleClick" );
                                        }
                                    }
                                }
                                return;
                            }
                            break;
                        }

                        // ビブラートプロパティダイアログを表示するかどうかを決める
                        rect = new Rectangle(
                            dobj.mRectangleInPixel.x + AppManager.keyWidth - stdx + 21,
                            dobj.mRectangleInPixel.y - stdy + (int)(100 * controller.getScaleY()),
                            dobj.mRectangleInPixel.width - 21,
                            (int)(100 * controller.getScaleY()) );
                        if ( Utility.isInRect( new Point( e.X, e.Y ), rect ) ) {
                            VsqEvent selectedEvent = null;
                            for ( Iterator<VsqEvent> itr2 = vsq.Track.get( selected ).getEventIterator(); itr2.hasNext(); ) {
                                VsqEvent ev = itr2.next();
                                if ( ev.InternalID == dobj.mInternalID ) {
                                    selectedEvent = ev;
                                    break;
                                }
                            }
                            if ( selectedEvent != null ) {
#if ENABLE_MOUSEHOVER
                                if ( mMouseHoverThread != null ) {
                                    mMouseHoverThread.Abort();
                                }
#endif
                                SynthesizerType type = SynthesizerType.VOCALOID2;
                                RendererKind kind = VsqFileEx.getTrackRendererKind( vsq.Track.get( selected ) );
#if DEBUG
                                sout.println( "FormMain#pictPianoRoll_MouseDoubleClick; kind=" + kind );
#endif
                                if ( kind == RendererKind.VOCALOID1 ) {
                                    type = SynthesizerType.VOCALOID1;
                                }
                                FormVibratoConfig dlg = null;
                                try {
                                    dlg = new FormVibratoConfig(
                                        selectedEvent.ID.VibratoHandle,
                                        selectedEvent.ID.getLength(),
                                        AppManager.editorConfig.DefaultVibratoLength,
                                        type,
                                        AppManager.editorConfig.UseUserDefinedAutoVibratoType );
                                    dlg.setLocation( getFormPreferedLocation( dlg ) );
                                    BDialogResult dr = AppManager.showModalDialog( dlg, this );
                                    if ( dr == BDialogResult.OK ) {
                                        VsqID t = (VsqID)selectedEvent.ID.clone();
                                        VibratoHandle handle = dlg.getVibratoHandle();
#if DEBUG
                                        sout.println( "FormMain#pictPianoRoll_MouseDoubleClick; (handle==null)=" + (handle == null) );
#endif
                                        if ( handle != null ) {
                                            String iconid = handle.IconID;
                                            int vibrato_length = handle.getLength();
                                            int note_length = selectedEvent.ID.getLength();
                                            t.VibratoDelay = note_length - vibrato_length;
                                            t.VibratoHandle = handle;
                                        } else {
                                            t.VibratoHandle = null;
                                        }
                                        CadenciiCommand run = new CadenciiCommand(
                                            VsqCommand.generateCommandEventChangeIDContaints( 
                                                selected,
                                                selectedEvent.