OSDN Git Service

c2fa1ff4519b2753876099dba7ebff2a3f614c1e
[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.io.IOException;
5 import java.util.regex.Pattern;
6
7 import javax.sound.midi.InvalidMidiDataException;
8 import javax.swing.AbstractAction;
9 import javax.swing.Action;
10 import javax.swing.Box;
11 import javax.swing.BoxLayout;
12 import javax.swing.JButton;
13 import javax.swing.JDialog;
14 import javax.swing.JLabel;
15 import javax.swing.JOptionPane;
16 import javax.swing.JPanel;
17 import javax.swing.JScrollPane;
18 import javax.swing.JTextArea;
19
20 import org.apache.commons.codec.binary.Base64;
21
22 import camidion.chordhelper.ButtonIcon;
23 import camidion.chordhelper.ChordHelperApplet;
24
25 /**
26  * Base64テキスト入力ダイアログ
27  */
28 public class Base64Dialog extends JDialog {
29         private Base64TextArea base64TextArea = new Base64TextArea(8,56);
30         private MidiSequenceEditorDialog midiEditor;
31         /**
32          * Base64デコードアクション
33          */
34         public Action addBase64Action = new AbstractAction(
35                 "Base64 Decode & Add to PlayList",
36                 new ButtonIcon(ButtonIcon.EJECT_ICON)
37         ) {
38                 {
39                         putValue(
40                                 Action.SHORT_DESCRIPTION,
41                                 "Base64デコードして、プレイリストへ追加"
42                         );
43                 }
44                 @Override
45                 public void actionPerformed(ActionEvent event) {
46                         byte[] data = getMIDIData();
47                         if( data == null || data.length == 0 ) {
48                                 String message = "No data entered - データが入力されていません。";
49                                 JOptionPane.showMessageDialog(
50                                         Base64Dialog.this, message,
51                                         ChordHelperApplet.VersionInfo.NAME,
52                                         JOptionPane.WARNING_MESSAGE
53                                 );
54                                 base64TextArea.requestFocusInWindow();
55                                 return;
56                         }
57                         PlaylistTableModel sltm = midiEditor.sequenceListTable.getModel();
58                         try {
59                                 sltm.addSequence(data, null);
60                         } catch(IOException | InvalidMidiDataException e) {
61                                 String message = "例外 "+e+" が発生しました。"+e.getMessage();
62                                 e.printStackTrace();
63                                 midiEditor.showWarning(message);
64                                 base64TextArea.requestFocusInWindow();
65                                 return;
66                         }
67                         setVisible(false);
68                 }
69         };
70         /**
71          * Base64テキストクリアアクション
72          */
73         public Action clearAction = new AbstractAction("Clear") {
74                 @Override
75                 public void actionPerformed(ActionEvent e) {
76                         base64TextArea.setText(null);
77                 }
78         };
79         private static class Base64TextArea extends JTextArea {
80                 private static final Pattern headerLine =
81                         Pattern.compile( "^.*:.*$", Pattern.MULTILINE );
82                 public Base64TextArea(int rows, int columns) {
83                         super(rows,columns);
84                 }
85                 public byte[] getBinary() {
86                         String text = headerLine.matcher(getText()).replaceAll("");
87                         return Base64.decodeBase64(text.getBytes());
88                 }
89                 public void setBinary(byte[] binary_data, String content_type, String filename) {
90                         if( binary_data != null && binary_data.length > 0 ) {
91                                 String header = "";
92                                 if( content_type != null && filename != null ) {
93                                         header += "Content-Type: " + content_type + "; name=\"" + filename + "\"\n";
94                                         header += "Content-Transfer-Encoding: base64\n";
95                                         header += "\n";
96                                 }
97                                 setText(header + new String(Base64.encodeBase64Chunked(binary_data)) + "\n");
98                         }
99                 }
100         }
101         /**
102          * Base64テキスト入力ダイアログを構築します。
103          * @param midiEditor 親画面となるMIDIエディタ
104          */
105         public Base64Dialog(MidiSequenceEditorDialog midiEditor) {
106                 this.midiEditor = midiEditor;
107                 setTitle("Base64-encoded MIDI sequence - " + ChordHelperApplet.VersionInfo.NAME);
108                 try {
109                         Base64.decodeBase64("".getBytes());
110                         base64Available = true;
111                 } catch( NoClassDefFoundError e ) {
112                         base64Available = false;
113                 }
114                 if( base64Available ) {
115                         add(new JPanel() {{
116                                 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
117                                 add(new JPanel() {{
118                                         setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
119                                         add(new JLabel("Base64-encoded MIDI sequence:"));
120                                         add(Box.createRigidArea(new Dimension(10, 0)));
121                                         add(new JButton(addBase64Action){{setMargin(ChordHelperApplet.ZERO_INSETS);}});
122                                         add(new JButton(clearAction){{setMargin(ChordHelperApplet.ZERO_INSETS);}});
123                                 }});
124                                 add(new JScrollPane(base64TextArea));
125                         }});
126                 }
127                 setBounds( 300, 250, 660, 300 );
128         }
129         private boolean base64Available;
130         /**
131          * {@link Base64} が使用できるかどうかを返します。
132          * @return Apache Commons Codec ライブラリが利用できる状態ならtrue
133          */
134         public boolean isBase64Available() {
135                 return base64Available;
136         }
137         /**
138          * バイナリー形式でMIDIデータを返します。
139          * @return バイナリー形式のMIDIデータ
140          */
141         public byte[] getMIDIData() {
142                 return base64TextArea.getBinary();
143         }
144         /**
145          * バイナリー形式のMIDIデータを設定します。
146          * @param midiData バイナリー形式のMIDIデータ
147          */
148         public void setMIDIData( byte[] midiData ) {
149                 base64TextArea.setBinary(midiData, null, null);
150         }
151         /**
152          * バイナリー形式のMIDIデータを、ファイル名をつけて設定します。
153          * @param midiData バイナリー形式のMIDIデータ
154          * @param filename ファイル名
155          */
156         public void setMIDIData( byte[] midiData, String filename ) {
157                 base64TextArea.setBinary(midiData, "audio/midi", filename);
158                 base64TextArea.selectAll();
159         }
160         /**
161          * Base64形式でMIDIデータを返します。
162          * @return  Base64形式のMIDIデータ
163          */
164         public String getBase64Data() {
165                 return base64TextArea.getText();
166         }
167         /**
168          * Base64形式のMIDIデータを設定します。
169          * @param base64Data Base64形式のMIDIデータ
170          */
171         public void setBase64Data( String base64Data ) {
172                 base64TextArea.setText(null);
173                 base64TextArea.append(base64Data);
174         }
175 }