OSDN Git Service

1e33cd8cb55fccf842cb0dd81e1ea12710925e01
[midichordhelper/MIDIChordHelper.git] / src / camidion / chordhelper / midieditor / Base64Dialog.java
1 package camidion.chordhelper.midieditor;
2 import java.awt.Dimension;
3 import java.awt.event.ActionEvent;
4 import java.util.Base64;
5 import java.util.regex.Pattern;
6
7 import javax.swing.AbstractAction;
8 import javax.swing.Action;
9 import javax.swing.Box;
10 import javax.swing.BoxLayout;
11 import javax.swing.JButton;
12 import javax.swing.JDialog;
13 import javax.swing.JOptionPane;
14 import javax.swing.JPanel;
15 import javax.swing.JScrollPane;
16 import javax.swing.JTextArea;
17 import javax.swing.event.DocumentEvent;
18 import javax.swing.event.DocumentListener;
19
20 import camidion.chordhelper.ButtonIcon;
21 import camidion.chordhelper.ChordHelperApplet;
22
23 /**
24  * Base64テキスト入力ダイアログ
25  */
26 public class Base64Dialog extends JDialog implements DocumentListener {
27         public static final Pattern HEADER_PATTERN = Pattern.compile("^.*:.*$", Pattern.MULTILINE);
28         private JTextArea base64TextArea = new JTextArea(8,56);
29         private MidiSequenceEditorDialog midiEditor;
30         private void error(String message) {
31                 JOptionPane.showMessageDialog(base64TextArea, (Object)message,
32                                 ChordHelperApplet.VersionInfo.NAME, JOptionPane.WARNING_MESSAGE);
33                 base64TextArea.requestFocusInWindow();
34         }
35         /**
36          * Base64デコードアクション
37          */
38         public Action addBase64Action = new AbstractAction("Add to PlayList", new ButtonIcon(ButtonIcon.EJECT_ICON)) {
39                 { putValue(Action.SHORT_DESCRIPTION, "Base64デコードして、プレイリストへ追加"); }
40                 @Override
41                 public void actionPerformed(ActionEvent event) {
42                         byte[] midiData = null;
43                         try {
44                                 midiData = getMIDIData();
45                         } catch(Exception e) {
46                                 error("Base64デコードに失敗しました。\n"+e);
47                                 return;
48                         }
49                         try {
50                                 midiEditor.sequenceListTable.getModel().addSequence(midiData, null);
51                         } catch(Exception e) {
52                                 error("Base64デコードされたデータが正しいMIDI形式になっていません。\n"+e);
53                                 return;
54                         }
55                         setVisible(false);
56                 }
57         };
58         /**
59          * Base64テキストクリアアクション
60          */
61         public Action clearAction = new AbstractAction("Clear", new ButtonIcon(ButtonIcon.X_ICON)) {
62                 @Override
63                 public void actionPerformed(ActionEvent e) { base64TextArea.setText(null); }
64         };
65         /**
66          * Base64テキスト入力ダイアログを構築します。
67          * @param midiEditor 親画面となるMIDIエディタ
68          */
69         public Base64Dialog(MidiSequenceEditorDialog midiEditor) {
70                 this.midiEditor = midiEditor;
71                 setTitle("Base64-encoded MIDI sequence - " + ChordHelperApplet.VersionInfo.NAME);
72                 add(new JPanel() {{
73                         setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
74                         add(new JPanel() {{
75                                 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
76                                 add(Box.createRigidArea(new Dimension(10, 0)));
77                                 add(new JButton(addBase64Action){{setMargin(ChordHelperApplet.ZERO_INSETS);}});
78                                 add(new JButton(clearAction){{setMargin(ChordHelperApplet.ZERO_INSETS);}});
79                         }});
80                         add(new JScrollPane(base64TextArea));
81                 }});
82                 setBounds( 300, 250, 660, 300 );
83                 base64TextArea.setToolTipText("Paste Base64-encoded MIDI sequence here");
84                 base64TextArea.getDocument().addDocumentListener(this);
85                 addBase64Action.setEnabled(false);
86                 clearAction.setEnabled(false);
87         }
88         @Override
89         public void insertUpdate(DocumentEvent e) {
90                 addBase64Action.setEnabled(true);
91                 clearAction.setEnabled(true);
92         }
93         @Override
94         public void removeUpdate(DocumentEvent e) {
95                 if( e.getDocument().getLength() > 0 ) return;
96                 addBase64Action.setEnabled(false);
97                 clearAction.setEnabled(false);
98         }
99         @Override
100         public void changedUpdate(DocumentEvent e) { }
101         /**
102          * バイナリー形式でMIDIデータを返します。
103          * @return バイナリー形式のMIDIデータ
104          * @throws IllegalArgumentException 入力されているテキストが有効なBase64スキームになっていない場合
105          */
106         public byte[] getMIDIData() {
107                 String body = HEADER_PATTERN.matcher(base64TextArea.getText()).replaceAll("");
108                 return Base64.getMimeDecoder().decode(body.getBytes());
109         }
110         /**
111          * バイナリー形式のMIDIデータを設定します。
112          * @param midiData バイナリー形式のMIDIデータ
113          */
114         public void setMIDIData(byte[] midiData) { setMIDIData(midiData, null); }
115         /**
116          * バイナリー形式のMIDIデータを、ファイル名をつけて設定します。
117          * @param midiData バイナリー形式のMIDIデータ
118          * @param filename ファイル名
119          */
120         public void setMIDIData(byte[] midiData, String filename) {
121                 if( midiData == null || midiData.length == 0 ) return;
122                 if( filename == null ) filename = "";
123                 String text =
124                                 "Content-Type: audio/midi; name=\"" + filename + "\"\n"
125                                                 + "Content-Transfer-Encoding: base64\n\n" +
126                                                 Base64.getMimeEncoder().encodeToString(midiData) + "\n";
127                 base64TextArea.setText(text);
128                 base64TextArea.selectAll();
129         }
130         /**
131          * Base64形式でMIDIデータを返します。
132          * @return  Base64形式のMIDIデータ
133          */
134         public String getBase64Data() { return base64TextArea.getText(); }
135         /**
136          * Base64形式のMIDIデータを設定します。
137          * @param base64Data Base64形式のMIDIデータ
138          */
139         public void setBase64Data( String base64Data ) {
140                 base64TextArea.setText(null);
141                 base64TextArea.append(base64Data);
142         }
143 }