/[svn]/jsampler/trunk/src/org/jsampler/view/std/JSMidiInstrumentTree.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/view/std/JSMidiInstrumentTree.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1866 - (show annotations) (download)
Sun Mar 15 19:40:29 2009 UTC (15 years ago) by iliev
File size: 27009 byte(s)
* show controller names in fx sends dialogs
* save send levels when exporting sampler configuration
* ask when removing nonempty map
* fixed compilation error

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2009 Grigor Iliev <grigor@grigoriliev.com>
5 *
6 * This file is part of JSampler.
7 *
8 * JSampler is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * JSampler is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with JSampler; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23 package org.jsampler.view.std;
24
25 import java.awt.Dimension;
26
27 import java.beans.PropertyChangeEvent;
28 import java.beans.PropertyChangeListener;
29
30 import java.awt.event.ActionEvent;
31 import java.awt.event.ActionListener;
32 import java.awt.event.KeyEvent;
33 import java.awt.event.MouseAdapter;
34 import java.awt.event.MouseEvent;
35
36 import java.util.Vector;
37
38 import javax.swing.AbstractAction;
39 import javax.swing.Action;
40 import javax.swing.Box;
41 import javax.swing.BoxLayout;
42 import javax.swing.JComponent;
43 import javax.swing.JLabel;
44 import javax.swing.JMenu;
45 import javax.swing.JMenuItem;
46 import javax.swing.JPanel;
47 import javax.swing.JPopupMenu;
48 import javax.swing.JScrollPane;
49 import javax.swing.JTable;
50 import javax.swing.JTree;
51 import javax.swing.KeyStroke;
52
53 import javax.swing.event.TreeSelectionEvent;
54 import javax.swing.event.TreeSelectionListener;
55
56 import javax.swing.tree.DefaultMutableTreeNode;
57 import javax.swing.tree.DefaultTreeModel;
58 import javax.swing.tree.TreeSelectionModel;
59
60 import org.jsampler.CC;
61 import org.jsampler.HF;
62 import org.jsampler.MidiInstrument;
63 import org.jsampler.MidiInstrumentMap;
64
65 import org.jsampler.event.MidiInstrumentEvent;
66 import org.jsampler.event.MidiInstrumentListener;
67 import org.jsampler.event.MidiInstrumentMapEvent;
68 import org.jsampler.event.MidiInstrumentMapListener;
69
70 import org.linuxsampler.lscp.MidiInstrumentInfo;
71
72 import net.sf.juife.OkCancelDialog;
73
74 import static org.jsampler.JSPrefs.FIRST_MIDI_BANK_NUMBER;
75 import static org.jsampler.JSPrefs.FIRST_MIDI_PROGRAM_NUMBER;
76 import static org.jsampler.view.std.StdI18n.i18n;
77
78
79 /**
80 *
81 * @author Grigor Iliev
82 */
83 public class JSMidiInstrumentTree extends JTree {
84 private DefaultTreeModel model;
85 private MidiInstrumentMap midiInstrumentMap;
86 private final ContextMenu contextMenu;
87
88 /**
89 * Creates a new instance of <code>JSMidiInstrumentTree</code>
90 */
91 public
92 JSMidiInstrumentTree() {
93 setRootVisible(false);
94 setShowsRootHandles(true);
95 setEditable(false);
96
97 addMouseListener(new MouseAdapter() {
98 public void
99 mousePressed(MouseEvent e) {
100 if(e.getButton() != e.BUTTON3) return;
101 setSelectionPath(getClosestPathForLocation(e.getX(), e.getY()));
102 }
103
104 public void
105 mouseClicked(MouseEvent e) {
106 if(e.getButton() != e.BUTTON1) return;
107 if(e.getClickCount() > 1) editSelectedInstrument();
108 }
109 });
110
111 setMidiInstrumentMap(null);
112
113 getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
114 contextMenu = new ContextMenu();
115 addMouseListener(contextMenu);
116
117 addTreeSelectionListener(getHandler());
118
119 Action a = new AbstractAction() {
120 public void
121 actionPerformed(ActionEvent e) {
122 removeSelectedInstrumentOrBank();
123 }
124 };
125
126 KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
127 getInputMap(JComponent.WHEN_FOCUSED).put(k, "removeSelectedInstrumentOrBank");
128 getActionMap().put("removeSelectedInstrumentOrBank", a);
129
130 String s = FIRST_MIDI_BANK_NUMBER;
131 CC.preferences().addPropertyChangeListener(s, new PropertyChangeListener() {
132 public void
133 propertyChange(PropertyChangeEvent e) {
134 model.reload();
135 }
136 });
137
138 s = FIRST_MIDI_PROGRAM_NUMBER;
139 CC.preferences().addPropertyChangeListener(s, new PropertyChangeListener() {
140 public void
141 propertyChange(PropertyChangeEvent e) {
142 model.reload();
143 contextMenu.updateChangeProgramMenu();
144 }
145 });
146 }
147
148 /**
149 * Gets the MIDI instrument map that is represented by this MIDI instrument tree.
150 * @return The MIDI instrument map that is represented by this MIDI instrument tree.
151 */
152 public MidiInstrumentMap
153 getMidiInstrumentMap() { return midiInstrumentMap; }
154
155 /**
156 * Sets the MIDI instrument map to be represented by this MIDI instrument tree.
157 * @param map The MIDI instrument map to be represented by this MIDI instrument tree.
158 */
159 public void
160 setMidiInstrumentMap(MidiInstrumentMap map) {
161 if(getMidiInstrumentMap() != null) {
162 for(MidiInstrument instr : getMidiInstrumentMap().getAllMidiInstruments()) {
163 instr.removeMidiInstrumentListener(getHandler());
164 }
165
166 getMidiInstrumentMap().removeMidiInstrumentMapListener(getHandler());
167 }
168
169 midiInstrumentMap = map;
170
171 DefaultMutableTreeNode root = new DefaultMutableTreeNode() {
172 public boolean
173 isLeaf() { return false; }
174
175 public Object
176 getUserObject() { return "/"; }
177 };
178
179 model = new DefaultTreeModel(root);
180
181 if(map != null) {
182 for(MidiInstrument instr : map.getAllMidiInstruments()) {
183 mapInstrument(instr);
184 instr.addMidiInstrumentListener(getHandler());
185 }
186
187 map.addMidiInstrumentMapListener(getHandler());
188 }
189
190 setEnabled(map != null);
191
192 setModel(model);
193 }
194
195 /**
196 * Adds the specified MIDI instrument to this tree.
197 * @param instr The MIDI instrument to add.
198 */
199 public void
200 mapInstrument(MidiInstrument instr) {
201 MidiBank bank = new MidiBank(instr.getInfo().getMidiBank());
202 DefaultMutableTreeNode bankNode = findBank(bank);
203
204 if(bankNode == null) {
205 bankNode = new BankTreeNode(bank);
206
207 model.insertNodeInto (
208 bankNode,
209 (DefaultMutableTreeNode)model.getRoot(),
210 findBankPosition(bank.getId())
211 );
212 }
213
214 model.insertNodeInto (
215 new InstrTreeNode(instr),
216 bankNode,
217 removeProgram(bankNode, instr.getInfo().getMidiProgram())
218 );
219 }
220
221 /**
222 * Removes the specified MIDI instrument from the tree.
223 * @param instr The MIDI instrument to remove.
224 * @throws IllegalArgumentException If the specified instrument is not found.
225 */
226 public void
227 unmapInstrument(MidiInstrument instr) {
228 MidiBank bank = new MidiBank(instr.getInfo().getMidiBank());
229 DefaultMutableTreeNode bankNode = findBank(bank);
230
231 if(bankNode == null)
232 throw new IllegalArgumentException("Missing MIDI bank: " + bank.getId());
233
234 removeProgram(bankNode, instr.getInfo().getMidiProgram());
235 if(bankNode.getChildCount() == 0) model.removeNodeFromParent(bankNode);
236 }
237
238 /**
239 * Gets the selected MIDI instrument.
240 * @return The selected MIDI instrument, or
241 * <code>null</code> if there is no MIDI instrument selected.
242 */
243 public MidiInstrument
244 getSelectedInstrument() {
245 if(getSelectionCount() == 0) return null;
246 Object obj = getSelectionPath().getLastPathComponent();
247 if(!(obj instanceof InstrTreeNode)) return null;
248 obj = ((InstrTreeNode)obj).getUserObject();
249 return (MidiInstrument)obj;
250 }
251
252 /**
253 * Gets the selected MIDI bank.
254 * @return The selected MIDI bank, or
255 * <code>null</code> if there is no MIDI bank selected.
256 */
257 public MidiBank
258 getSelectedMidiBank() {
259 if(getSelectionCount() == 0) return null;
260
261 Object obj = getSelectionPath().getLastPathComponent();
262 if(!(obj instanceof BankTreeNode)) return null;
263
264 BankTreeNode n = (BankTreeNode)obj;
265 return (MidiBank)n.getUserObject();
266 }
267
268 /**
269 * Removes (on the backend side) the selected MIDI instrument or MIDI bank.
270 */
271 public void
272 removeSelectedInstrumentOrBank() {
273 if(getSelectionCount() == 0) return;
274
275 Object obj = getSelectionPath().getLastPathComponent();
276 if(obj instanceof InstrTreeNode) {
277 obj = ((InstrTreeNode)obj).getUserObject();
278 removeInstrument((MidiInstrument)obj);
279 } else if(obj instanceof BankTreeNode) {
280 BankTreeNode n = (BankTreeNode)obj;
281 int c = n.getChildCount();
282 if(c > 1) {
283 String s;
284 s = i18n.getMessage("JSMidiInstrumentTree.removeInstruments?", c);
285 if(!HF.showYesNoDialog(CC.getMainFrame(), s)) return;
286 }
287
288 for(int i = c - 1; i >= 0; i--) {
289 obj = ((InstrTreeNode)n.getChildAt(i)).getUserObject();
290 removeInstrument((MidiInstrument)obj);
291 }
292 }
293 }
294
295 /**
296 * Removes (on the backend side) the specified MIDI instrument.
297 */
298 private void
299 removeInstrument(MidiInstrument instr) {
300 MidiInstrumentInfo i = instr.getInfo();
301 CC.getSamplerModel().unmapBackendMidiInstrument (
302 i.getMapId(), i.getMidiBank(), i.getMidiProgram()
303 );
304 }
305
306 /**
307 * Returns the position, where the specified bank should be inserted.
308 */
309 private int
310 findBankPosition(int bankID) {
311 DefaultMutableTreeNode root = (DefaultMutableTreeNode)model.getRoot();
312
313 for(int i = 0; i < root.getChildCount(); i++) {
314 DefaultMutableTreeNode node = (DefaultMutableTreeNode)root.getChildAt(i);
315 MidiBank bank = (MidiBank)node.getUserObject();
316 if(bank.getId() > bankID) return i;
317 }
318
319 return root.getChildCount();
320 }
321
322 /**
323 * If there is already an instrument with MIDI program <code>program</code>,
324 * those instrument is removed from the tree.
325 * @return The position, where the instrument of the specified program should be inserted.
326 */
327 private int
328 removeProgram(DefaultMutableTreeNode bankNode, int program) {
329
330 for(int i = 0; i < bankNode.getChildCount(); i++) {
331 DefaultMutableTreeNode n = (DefaultMutableTreeNode)bankNode.getChildAt(i);
332 MidiInstrument instr = (MidiInstrument)n.getUserObject();
333
334 if(instr.getInfo().getMidiProgram() == program) {
335 model.removeNodeFromParent(n);
336 return i;
337 }
338
339 if(instr.getInfo().getMidiProgram() > program) return i;
340 }
341
342 return bankNode.getChildCount();
343 }
344
345 private DefaultMutableTreeNode
346 findNode(DefaultMutableTreeNode parent, Object obj) {
347 for(int i = 0; i < parent.getChildCount(); i++) {
348 DefaultMutableTreeNode node = (DefaultMutableTreeNode)parent.getChildAt(i);
349 if(node.getUserObject().equals(obj)) return node;
350 }
351
352 return null;
353 }
354
355 private DefaultMutableTreeNode
356 findBank(Object obj) {
357 return findNode((DefaultMutableTreeNode)model.getRoot(), obj);
358 }
359
360 private DefaultMutableTreeNode
361 findInstrument(Object obj) {
362 if(obj == null || !(obj instanceof MidiInstrument)) return null;
363 MidiInstrument i = (MidiInstrument) obj;
364 DefaultMutableTreeNode bank = findBank(new MidiBank(i.getInfo().getMidiBank()));
365 if(bank == null) return null;
366 return findNode(bank, obj);
367 }
368
369
370 private class MidiBank {
371 private int id;
372
373 MidiBank(int id) {
374 this.id = id;
375 }
376
377 public int
378 getId() { return id; }
379
380 @Override
381 public boolean
382 equals(Object obj) {
383 if(obj == null) return false;
384 if(!(obj instanceof MidiBank)) return false;
385 if(getId() == ((MidiBank)obj).getId()) return true;
386 return false;
387 }
388
389 @Override
390 public String
391 toString() {
392 int i = CC.getViewConfig().getFirstMidiBankNumber();
393 return i18n.getLabel("JSMidiInstrumentTree.MidiBank.name", i + id);
394 }
395 }
396
397 protected class BankTreeNode extends DefaultMutableTreeNode {
398 BankTreeNode(Object obj) {
399 super(obj);
400 }
401
402 @Override
403 public void
404 setUserObject(Object userObject) {
405 if(userObject instanceof MidiBank) {
406 super.setUserObject(userObject);
407 return;
408 }
409
410 // If we are here, this means that tree editing occurs.
411 CC.getLogger().info("MidiInstrumentTree: editing not supported");
412 }
413
414 @Override
415 public boolean
416 isLeaf() { return false; }
417 }
418
419 protected class InstrTreeNode extends DefaultMutableTreeNode {
420 InstrTreeNode(Object obj) {
421 super(obj);
422 }
423
424 @Override
425 public void
426 setUserObject(Object userObject) {
427 if(userObject instanceof MidiInstrument) {
428 super.setUserObject(userObject);
429 return;
430 }
431
432 // If we are here, this means that tree editing occurs.
433 CC.getLogger().info("MidiInstrumentTree: editing not supported");
434 }
435
436 @Override
437 public boolean
438 isLeaf() { return true; }
439 }
440
441 private void
442 editSelectedInstrument() {
443 MidiInstrument i = getSelectedInstrument();
444 if(i == null) return;
445 JSEditMidiInstrumentDlg dlg = new JSEditMidiInstrumentDlg(i.getInfo());
446 dlg.setVisible(true);
447
448 if(dlg.isCancelled()) return;
449
450 MidiInstrumentInfo info = dlg.getInstrument();
451 CC.getSamplerModel().mapBackendMidiInstrument (
452 info.getMapId(), info.getMidiBank(), info.getMidiProgram(), info
453 );
454 }
455
456 private void
457 copyMidiBankTo() { copyOrMoveMidiBankTo(true); }
458
459 private void
460 moveMidiBankTo() { copyOrMoveMidiBankTo(false); }
461
462 private void
463 copyOrMoveMidiBankTo(boolean copy) {
464 MidiBank bank = getSelectedMidiBank();
465 if(bank == null) return;
466
467 JSMidiBankChooser dlg = new JSMidiBankChooser();
468
469 if(copy) dlg.setTitle(i18n.getLabel("JSMidiInstrumentTree.copyTo"));
470 else dlg.setTitle(i18n.getLabel("JSMidiInstrumentTree.moveTo"));
471
472 dlg.setSelectedMidiInstrumentMap(getMidiInstrumentMap());
473 dlg.setVisible(true);
474 if(dlg.isCancelled()) return;
475
476 MidiInstrumentMap smap = dlg.getSelectedMidiInstrumentMap();
477
478 if(smap == null) {
479 HF.showErrorMessage(i18n.getMessage("JSMidiInstrumentTree.noMap!"), this);
480 return;
481 }
482
483 if(dlg.getMidiBank() == bank.getId() && smap.getMapId() == getMidiInstrumentMap().getMapId()) {
484 String s = "JSMidiInstrumentTree.sameSourceAndDestination!";
485 HF.showErrorMessage(i18n.getMessage(s), this);
486 return;
487 }
488
489 MidiInstrument[] instrs = getMidiInstrumentMap().getMidiInstruments(bank.getId());
490 int mapId = smap.getMapId();
491 int bnkId = dlg.getMidiBank();
492
493 Vector<MidiInstrument> v = new Vector<MidiInstrument>();
494 for(MidiInstrument i : instrs) {
495 MidiInstrument instr;
496 instr = smap.getMidiInstrument(bnkId, i.getInfo().getMidiProgram());
497 if(instr != null) v.add(instr);
498 }
499
500 if(!v.isEmpty()) {
501 String[] instrumentNames = new String[v.size()];
502 for(int i = 0; i < v.size(); i++) {
503 int base = CC.getViewConfig().getFirstMidiProgramNumber();
504 int p = v.get(i).getInfo().getMidiProgram();
505 instrumentNames[i] = (base + p) + ". " + v.get(i).getName();
506 }
507 JSOverrideInstrumentsConfirmDlg dlg2;
508 dlg2 = new JSOverrideInstrumentsConfirmDlg(instrumentNames);
509 dlg2.setVisible(true);
510 if(dlg2.isCancelled()) return;
511 }
512
513 for(MidiInstrument i : instrs) {
514 int p = i.getInfo().getMidiProgram();
515 CC.getSamplerModel().mapBackendMidiInstrument(mapId, bnkId, p, i.getInfo());
516 }
517
518 if(copy) return;
519
520 mapId = getMidiInstrumentMap().getMapId();
521 bnkId = bank.getId();
522
523 for(MidiInstrument i : instrs) {
524 int p = i.getInfo().getMidiProgram();
525 CC.getSamplerModel().unmapBackendMidiInstrument(mapId, bnkId, p);
526 }
527 }
528
529 private void
530 copyMidiInstrumentTo() { copyOrMoveMidiInstrumentTo(true); }
531
532 private void
533 moveMidiInstrumentTo() { copyOrMoveMidiInstrumentTo(false); }
534
535 private void
536 copyOrMoveMidiInstrumentTo(boolean copy) {
537 MidiInstrument instr = getSelectedInstrument();
538 if(instr == null) return;
539
540 JSMidiBankChooser dlg = new JSMidiBankChooser();
541
542 if(copy) dlg.setTitle(i18n.getLabel("JSMidiInstrumentTree.copyTo"));
543 else dlg.setTitle(i18n.getLabel("JSMidiInstrumentTree.moveTo"));
544
545 dlg.setSelectedMidiInstrumentMap(getMidiInstrumentMap());
546 dlg.setVisible(true);
547 if(dlg.isCancelled()) return;
548
549 MidiInstrumentMap smap = dlg.getSelectedMidiInstrumentMap();
550
551 if(smap == null) {
552 HF.showErrorMessage(i18n.getMessage("JSMidiInstrumentTree.noMap!"), this);
553 return;
554 }
555
556 int bank = instr.getInfo().getMidiBank();
557 if(dlg.getMidiBank() == bank && smap.getMapId() == getMidiInstrumentMap().getMapId()) {
558 String s = "JSMidiInstrumentTree.sameSourceAndDestination!";
559 HF.showErrorMessage(i18n.getMessage(s), this);
560 return;
561 }
562
563 int mapId = smap.getMapId();
564 int bnkId = dlg.getMidiBank();
565 int prgId = instr.getInfo().getMidiProgram();
566 MidiInstrument oldInstr = smap.getMidiInstrument(bnkId, prgId);
567
568 if(oldInstr != null) {
569 String[] iS = new String [1];
570 int base = CC.getViewConfig().getFirstMidiProgramNumber();
571 iS[0] = (base + prgId) + ". " + oldInstr.getName();
572 JSOverrideInstrumentsConfirmDlg dlg2;
573 dlg2 = new JSOverrideInstrumentsConfirmDlg(iS);
574 dlg2.setVisible(true);
575 if(dlg2.isCancelled()) return;
576 }
577
578 CC.getSamplerModel().mapBackendMidiInstrument(mapId, bnkId, prgId, instr.getInfo());
579
580 if(copy) return;
581
582 mapId = getMidiInstrumentMap().getMapId();
583
584 CC.getSamplerModel().unmapBackendMidiInstrument(mapId, bank, prgId);
585 }
586
587 private void
588 moveSelectedInstrumentUp() {
589 MidiInstrument instr = getSelectedInstrument();
590 if(instr == null) return;
591 moveSelectedInstrument(instr.getInfo().getMidiProgram() - 1);
592 }
593
594 private void
595 moveSelectedInstrumentDown() {
596 MidiInstrument instr = getSelectedInstrument();
597 if(instr == null) return;
598 moveSelectedInstrument(instr.getInfo().getMidiProgram() + 1);
599 }
600
601 private void
602 moveSelectedInstrument(int newProgram) {
603 if(newProgram < 0 || newProgram > 127) return;
604 MidiInstrument instr = getSelectedInstrument();
605 if(instr == null) return;
606
607 int bnk = instr.getInfo().getMidiBank();
608 int prg = instr.getInfo().getMidiProgram();
609
610 MidiInstrument oldInstr = getMidiInstrumentMap().getMidiInstrument(bnk, newProgram);
611 if(oldInstr != null) {
612 String[] iS = new String [1];
613 int base = CC.getViewConfig().getFirstMidiProgramNumber();
614 iS[0] = (base + newProgram) + ". " + oldInstr.getName();
615 JSOverrideInstrumentsConfirmDlg dlg;
616 dlg = new JSOverrideInstrumentsConfirmDlg(iS);
617 dlg.setVisible(true);
618 if(dlg.isCancelled()) return;
619 }
620
621 int map = this.getMidiInstrumentMap().getMapId();
622 CC.getSamplerModel().mapBackendMidiInstrument(map, bnk, newProgram, instr.getInfo());
623 CC.getSamplerModel().unmapBackendMidiInstrument(map, bnk, prg);
624 }
625
626 private final EventHandler eventHandler = new EventHandler();
627
628 private EventHandler
629 getHandler() { return eventHandler; }
630
631 private class EventHandler implements MidiInstrumentListener, MidiInstrumentMapListener,
632 TreeSelectionListener {
633
634 /** Invoked when a MIDI instrument in a MIDI instrument map is changed. */
635 @Override
636 public void
637 instrumentInfoChanged(MidiInstrumentEvent e) {
638 DefaultMutableTreeNode n = findInstrument(e.getSource());
639 if(n != null) model.nodeChanged(n);
640 }
641
642 /** Invoked when the name of MIDI instrument map is changed. */
643 @Override
644 public void nameChanged(MidiInstrumentMapEvent e) { }
645
646 /** Invoked when an instrument is added to a MIDI instrument map. */
647 @Override
648 public void
649 instrumentAdded(MidiInstrumentMapEvent e) {
650 e.getInstrument().addMidiInstrumentListener(getHandler());
651 mapInstrument(e.getInstrument());
652
653 }
654
655 /** Invoked when an instrument is removed from a MIDI instrument map. */
656 @Override
657 public void
658 instrumentRemoved(MidiInstrumentMapEvent e) {
659 unmapInstrument(e.getInstrument());
660 e.getInstrument().removeMidiInstrumentListener(getHandler());
661 }
662
663 @Override
664 public void
665 valueChanged(TreeSelectionEvent e) {
666 MidiInstrument instr = getSelectedInstrument();
667 if(instr != null) {
668 int p = instr.getInfo().getMidiProgram();
669 contextMenu.miMoveInstrumentDown.setEnabled(p < 127);
670 contextMenu.miMoveInstrumentUp.setEnabled(p > 0);
671 }
672 }
673 }
674
675 class ContextMenu extends MouseAdapter {
676 private final JPopupMenu bankMenu = new JPopupMenu();
677
678 private final JPopupMenu instrumentMenu = new JPopupMenu();
679
680 private final JMenu changeProgramMenu =
681 new JMenu(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.changeProgram"));
682
683 private final JMenuItem miMoveInstrumentUp =
684 new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.moveUp"));
685
686 private final JMenuItem miMoveInstrumentDown =
687 new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.moveDown"));
688
689 private final JMenu programGroup1Menu = new JMenu();
690 private final JMenu programGroup2Menu = new JMenu();
691 private final JMenu programGroup3Menu = new JMenu();
692 private final JMenu programGroup4Menu = new JMenu();
693 private final JMenu programGroup5Menu = new JMenu();
694 private final JMenu programGroup6Menu = new JMenu();
695 private final JMenu programGroup7Menu = new JMenu();
696 private final JMenu programGroup8Menu = new JMenu();
697
698
699 ContextMenu() {
700 JMenuItem mi = new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.moveTo"));
701 bankMenu.add(mi);
702 mi.addActionListener(new ActionListener() {
703 public void
704 actionPerformed(ActionEvent e) {
705 moveMidiBankTo();
706 }
707 });
708
709 mi = new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.copyTo"));
710 bankMenu.add(mi);
711 mi.addActionListener(new ActionListener() {
712 public void
713 actionPerformed(ActionEvent e) {
714 copyMidiBankTo();
715 }
716 });
717
718 bankMenu.addSeparator();
719
720 mi = new JMenuItem(i18n.getMenuLabel("ContextMenu.delete"));
721 bankMenu.add(mi);
722 mi.addActionListener(new ActionListener() {
723 public void
724 actionPerformed(ActionEvent e) {
725 removeSelectedInstrumentOrBank();
726 }
727 });
728
729 // MIDI Instrument Menu
730
731 mi = new JMenuItem(i18n.getMenuLabel("ContextMenu.edit"));
732 instrumentMenu.add(mi);
733 mi.addActionListener(new ActionListener() {
734 public void
735 actionPerformed(ActionEvent e) {
736 editSelectedInstrument();
737 }
738 });
739
740 instrumentMenu.addSeparator();
741
742 mi = new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.moveTo"));
743 instrumentMenu.add(mi);
744 mi.addActionListener(new ActionListener() {
745 public void
746 actionPerformed(ActionEvent e) {
747 moveMidiInstrumentTo();
748 }
749 });
750
751 mi = new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.copyTo"));
752 instrumentMenu.add(mi);
753 mi.addActionListener(new ActionListener() {
754 public void
755 actionPerformed(ActionEvent e) {
756 copyMidiInstrumentTo();
757 }
758 });
759
760 instrumentMenu.add(changeProgramMenu);
761
762 changeProgramMenu.add(miMoveInstrumentUp);
763 miMoveInstrumentUp.addActionListener(new ActionListener() {
764 public void
765 actionPerformed(ActionEvent e) {
766 moveSelectedInstrumentUp();
767 }
768 });
769
770 changeProgramMenu.add(miMoveInstrumentDown);
771 miMoveInstrumentDown.addActionListener(new ActionListener() {
772 public void
773 actionPerformed(ActionEvent e) {
774 moveSelectedInstrumentDown();
775 }
776 });
777
778 changeProgramMenu.addSeparator();
779
780 changeProgramMenu.add(programGroup1Menu);
781 addProgramMenuItems(programGroup1Menu, 0, 15);
782 changeProgramMenu.add(programGroup2Menu);
783 addProgramMenuItems(programGroup2Menu, 16, 31);
784 changeProgramMenu.add(programGroup3Menu);
785 addProgramMenuItems(programGroup3Menu, 32, 47);
786 changeProgramMenu.add(programGroup4Menu);
787 addProgramMenuItems(programGroup4Menu, 48, 63);
788 changeProgramMenu.add(programGroup5Menu);
789 addProgramMenuItems(programGroup5Menu, 64, 79);
790 changeProgramMenu.add(programGroup6Menu);
791 addProgramMenuItems(programGroup6Menu, 80, 95);
792 changeProgramMenu.add(programGroup7Menu);
793 addProgramMenuItems(programGroup7Menu, 96, 111);
794 changeProgramMenu.add(programGroup8Menu);
795 addProgramMenuItems(programGroup8Menu, 112, 127);
796
797 instrumentMenu.addSeparator();
798 updateChangeProgramMenu();
799
800 mi = new JMenuItem(i18n.getMenuLabel("ContextMenu.delete"));
801 instrumentMenu.add(mi);
802 mi.addActionListener(new ActionListener() {
803 public void
804 actionPerformed(ActionEvent e) {
805 removeSelectedInstrumentOrBank();
806 }
807 });
808
809 }
810
811 private void
812 addProgramMenuItems(JMenu menu, int prgStart, int prgEnd) {
813 for(int i = prgStart; i <= prgEnd; i++) {
814 menu.add(new ProgramMenuItem(i));
815 }
816 }
817
818 private void
819 updateChangeProgramMenu() {
820 updateProgramGroupMenu(programGroup1Menu, 0, 15);
821 updateProgramGroupMenu(programGroup2Menu, 16, 31);
822 updateProgramGroupMenu(programGroup3Menu, 32, 47);
823 updateProgramGroupMenu(programGroup4Menu, 48, 63);
824 updateProgramGroupMenu(programGroup5Menu, 64, 79);
825 updateProgramGroupMenu(programGroup6Menu, 80, 95);
826 updateProgramGroupMenu(programGroup7Menu, 96, 111);
827 updateProgramGroupMenu(programGroup8Menu, 112, 127);
828 }
829
830 private void
831 updateProgramGroupMenu(JMenu menu, int prgStart, int prgEnd) {
832 int base = CC.getViewConfig().getFirstMidiProgramNumber();
833 String s = "JSMidiInstrumentTree.ContextMenu.programGroup";
834 String grp = "(" + (base + prgStart) + "-" + (base + prgEnd) + ")";
835 menu.setText(i18n.getMenuLabel(s, grp));
836
837 updateProgramGroupMenuItems(menu);
838 }
839
840 private void
841 updateProgramGroupMenuItems(JMenu menu) {
842 for(int i = 0; i < menu.getItemCount(); i++) {
843 ((ProgramMenuItem)menu.getItem(i)).updateProgramNumber();
844 }
845 }
846
847 @Override
848 public void
849 mousePressed(MouseEvent e) {
850 if(e.isPopupTrigger()) show(e);
851 }
852
853 @Override
854 public void
855 mouseReleased(MouseEvent e) {
856 if(e.isPopupTrigger()) show(e);
857 }
858
859 void
860 show(MouseEvent e) {
861 if(getSelectionCount() == 0) return;
862
863 if(getSelectedInstrument() != null) {
864 instrumentMenu.show(e.getComponent(), e.getX(), e.getY());
865 } else {
866 bankMenu.show(e.getComponent(), e.getX(), e.getY());
867 }
868 }
869
870 private class ProgramMenuItem extends JMenuItem implements ActionListener {
871 int program;
872
873 ProgramMenuItem(int program) {
874 this.program = program;
875 updateProgramNumber();
876 addActionListener(this);
877 }
878
879 public void
880 updateProgramNumber() {
881 int base = CC.getViewConfig().getFirstMidiProgramNumber();
882 setText(String.valueOf(base + program));
883 }
884
885 @Override
886 public void
887 actionPerformed(ActionEvent e) {
888 moveSelectedInstrument(program);
889 }
890 }
891 }
892 }
893
894 class JSOverrideInstrumentsConfirmDlg extends OkCancelDialog {
895 private final JLabel lMsg = new JLabel(i18n.getMessage("JSOverrideInstrumentsConfirmDlg.lMsg"));
896 private final JTable table;
897
898 JSOverrideInstrumentsConfirmDlg(String[] instrumentNames) {
899 super(CC.getMainFrame());
900
901 JPanel mainPane = new JPanel();
902 mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS));
903
904 lMsg.setIcon(CC.getViewConfig().getBasicIconSet().getWarning32Icon());
905 lMsg.setAlignmentX(LEFT_ALIGNMENT);
906 mainPane.add(lMsg);
907
908 mainPane.add(Box.createRigidArea(new Dimension(0, 12)));
909
910 String[][] instrs = new String[instrumentNames.length][1];
911 for(int i = 0; i < instrumentNames.length; i++) {
912 instrs[i][0] = instrumentNames[i];
913 }
914
915 String[] columns = new String[1];
916 columns[0] = "";
917
918 table = new JTable(instrs, columns);
919 JScrollPane sp = new JScrollPane(table);
920 Dimension d = new Dimension(200, 200);
921 sp.setMinimumSize(d);
922 sp.setPreferredSize(d);
923 sp.setAlignmentX(LEFT_ALIGNMENT);
924 mainPane.add(sp);
925
926 setMainPane(mainPane);
927 setMinimumSize(getPreferredSize());
928 setResizable(true);
929 }
930
931 @Override
932 protected void
933 onOk() {
934 if(!btnOk.isEnabled()) return;
935
936 setVisible(false);
937 setCancelled(false);
938 }
939
940 @Override
941 protected void
942 onCancel() { setVisible(false); }
943 }

  ViewVC Help
Powered by ViewVC