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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1767 - (hide annotations) (download)
Mon Sep 8 00:19:27 2008 UTC (15 years, 8 months ago) by iliev
File size: 26863 byte(s)
* Added `Copy To' and `Move To' commands to the MIDI bank context menu
  and to the MIDI instrument context menu
* Added commands to the MIDI instrument context menu for moving
  a MIDI instrument to another program
  (right-click on a MIDI instrument and choose `Change Program')
* Added option to choose between zero-based and one-based
  MIDI bank/program numbering
  (choose Edit/Preferences, then click the `Advanced' button)
* Added option to choose whether to include MIDI instrument
  mappings when exporting a sampler configuration to LSCP script.
  (choose Edit/Preferences, then click the `Advanced' button)
* Added option to set the MIDI instrument loading in background
  when exporting MIDI instrument mappings to LSCP script.
  (choose Edit/Preferences, then click the `Advanced' button)
* Implemented an option to change the socket read timeout
  (choose Edit/Preferences, then click the `Backend' tab)
* Updated LscpTree
* Fantasia: Added option to hide the active stream/voice count statistic
  in the sampler channel's small view
  (choose Edit/Preferences, then click the `Channels' tab)
* Fantasia: `Turn off animation effects' checkbox moved to the `View' tab

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

  ViewVC Help
Powered by ViewVC