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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2273 - (show annotations) (download)
Mon Sep 19 15:21:33 2011 UTC (12 years, 6 months ago) by iliev
File size: 36894 byte(s)
* Usе multicolumn menus for adding instruments to
  MIDI maps and to orchestras from the Instruments Database

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2010 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.Component;
26 import java.awt.Dialog;
27 import java.awt.Frame;
28 import java.awt.Window;
29
30 import java.awt.event.ActionEvent;
31 import java.awt.event.KeyEvent;
32 import java.awt.event.MouseAdapter;
33 import java.awt.event.MouseEvent;
34
35 import java.util.LinkedList;
36 import java.util.Vector;
37
38 import javax.swing.AbstractAction;
39 import javax.swing.Action;
40 import javax.swing.BorderFactory;
41 import javax.swing.Icon;
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.JTable;
49 import javax.swing.KeyStroke;
50
51 import javax.swing.event.ChangeEvent;
52 import javax.swing.event.ChangeListener;
53 import javax.swing.event.ListSelectionEvent;
54 import javax.swing.event.ListSelectionListener;
55 import javax.swing.event.TreeSelectionEvent;
56 import javax.swing.event.TreeSelectionListener;
57
58 import javax.swing.table.TableCellRenderer;
59
60 import net.sf.juife.InformationDialog;
61 import net.sf.juife.JuifeUtils;
62 import net.sf.juife.Task;
63
64 import net.sf.juife.event.TaskEvent;
65 import net.sf.juife.event.TaskListener;
66
67 import org.jsampler.CC;
68 import org.jsampler.HF;
69 import org.jsampler.OrchestraInstrument;
70 import org.jsampler.MidiInstrumentMap;
71 import org.jsampler.OrchestraModel;
72 import org.jsampler.SamplerChannelModel;
73
74 import org.jsampler.event.ListEvent;
75 import org.jsampler.event.ListListener;
76 import org.jsampler.event.SamplerChannelListEvent;
77 import org.jsampler.event.SamplerChannelListListener;
78
79 import org.jsampler.task.InstrumentsDb;
80 import org.jsampler.task.Midi;
81
82 import org.jsampler.view.DbClipboard;
83 import org.jsampler.view.DbDirectoryTreeNode;
84 import org.jsampler.view.InstrumentsDbTableModel;
85
86 import org.linuxsampler.lscp.DbDirectoryInfo;
87 import org.linuxsampler.lscp.DbInstrumentInfo;
88 import org.linuxsampler.lscp.MidiInstrumentEntry;
89 import org.linuxsampler.lscp.MidiInstrumentInfo;
90
91 import static org.jsampler.view.InstrumentsDbTableModel.ColumnType;
92 import static org.jsampler.view.std.StdI18n.i18n;
93
94 import static org.linuxsampler.lscp.Parser.*;
95
96 /**
97 *
98 * @author Grigor Iliev
99 */
100 public class JSInstrumentsDbTable extends org.jsampler.view.AbstractInstrumentsDbTable {
101 private JSInstrumentsDbTree instrumentsDbTree;
102 private InstrumentsDbCellRenderer cellRenderer = new InstrumentsDbCellRenderer();
103
104 public final Action reloadAction = new ReloadAction();
105 public final Action createDirectoryAction = new CreateDirectoryAction();
106 public final Action deleteAction = new DeleteAction();
107 public final AddInstrumentsFromFileAction addInstrumentsFromFileAction =
108 new AddInstrumentsFromFileAction();
109 public final AddInstrumentsFromDirAction addInstrumentsFromDirAction =
110 new AddInstrumentsFromDirAction();
111 public final Action propertiesAction = new PropertiesAction();
112 public final Action renameAction = new RenameAction();
113 public final Action changeDescriptionAction = new ChangeDescriptionAction();
114 public final Action cutAction = new CutAction();
115 public final Action copyAction = new CopyAction();
116 public final Action pasteAction;
117
118 private static final DbClipboard dbClipboard = new DbClipboard();
119
120 /**
121 * Creates a new instance of <code>JSInstrumentsDbTable</code>
122 */
123 public
124 JSInstrumentsDbTable(JSInstrumentsDbTree tree) {
125 this(tree, "");
126 }
127
128 /**
129 * Creates a new instance of <code>JSInstrumentsDbTable</code>
130 * @param columnPrefix Used to create unique property names for storing
131 * the column preferences for different tables e.g. for DbInstrumentChooser,
132 * InstrumentsDbFrame.
133 */
134 public
135 JSInstrumentsDbTable(JSInstrumentsDbTree tree, String columnPrefix) {
136 super(columnPrefix);
137
138 instrumentsDbTree = tree;
139
140 /*for(int i = 0; i < getColumnModel().getColumnCount(); i++) {
141 getColumnModel().getColumn(i).setMinWidth(50);
142 }*/
143
144 setShowGrid(false);
145 getColumnModel().setColumnMargin(0);
146 getTableHeader().setReorderingAllowed(false);
147
148 setFillsViewportHeight(true);
149
150 addMouseListener(new MouseAdapter() {
151 public void
152 mouseClicked(MouseEvent e) {
153 if(e.getButton() != e.BUTTON1) return;
154 int r = rowAtPoint(e.getPoint());
155 if(r == -1) {
156 clearSelection();
157 return;
158 }
159
160 if(e.getClickCount() < 2) return;
161
162 DbDirectoryTreeNode node = getSelectedDirectoryNode();
163 if(node == null) return;
164 if(!node.isDetached()) {
165 instrumentsDbTree.setSelectedDirectoryNode(node);
166 } else {
167 String s = node.getInfo().getDirectoryPath();
168 instrumentsDbTree.setSelectedDirectory(s);
169 }
170 }
171 });
172
173 addMouseListener(new MouseAdapter() {
174 public void
175 mousePressed(MouseEvent e) {
176 int r = rowAtPoint(e.getPoint());
177
178 if(e.getButton() != e.BUTTON1 && e.getButton() != e.BUTTON3) return;
179 if(r == -1) {
180 clearSelection();
181 return;
182 }
183
184 if(e.getButton() != e.BUTTON3) return;
185 if(getSelectionModel().isSelectedIndex(r)) {
186 getSelectionModel().addSelectionInterval(r, r);
187 } else {
188 getSelectionModel().setSelectionInterval(r, r);
189 }
190 }
191 });
192
193 getSelectionModel().addListSelectionListener(getHandler());
194
195 instrumentsDbTree.addTreeSelectionListener(getHandler());
196
197 PasteAction pasteAction = new PasteAction();
198 instrumentsDbTree.addTreeSelectionListener(pasteAction);
199 this.pasteAction = pasteAction;
200
201 ContextMenu contextMenu = new ContextMenu();
202 addMouseListener(contextMenu);
203
204 CC.getOrchestras().addOrchestraListListener(getHandler());
205 CC.getSamplerModel().addSamplerChannelListListener(getHandler());
206
207 CC.getMainFrame().addChannelsPaneSelectionListener(new ListSelectionListener() {
208 public void
209 valueChanged(ListSelectionEvent e) {
210 updateLoadInstrumentMenus();
211 }
212 });
213
214 ListListener<MidiInstrumentMap> l = new ListListener<MidiInstrumentMap>() {
215 public void
216 entryAdded(ListEvent<MidiInstrumentMap> e) { updateAddToMidiMapMenus(); }
217
218 public void
219 entryRemoved(ListEvent<MidiInstrumentMap> e) { updateAddToMidiMapMenus(); }
220 };
221
222 CC.getSamplerModel().addMidiInstrumentMapListListener(l);
223
224 installKeyboardListeners();
225 }
226
227 public static DbClipboard
228 getDbClipboard() { return dbClipboard; }
229
230 @Override
231 public TableCellRenderer
232 getCellRenderer(int row, int column) {
233 return cellRenderer;
234 }
235
236 private void
237 installKeyboardListeners() {
238 AbstractAction a = new AbstractAction() {
239 public void
240 actionPerformed(ActionEvent e) { }
241 };
242 a.setEnabled(false);
243 getActionMap().put("none", a);
244
245 int modKey = CC.getViewConfig().getDefaultModKey();
246
247 getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put (
248 KeyStroke.getKeyStroke(KeyEvent.VK_X, modKey),
249 "none"
250 );
251
252 getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put (
253 KeyStroke.getKeyStroke(KeyEvent.VK_C, modKey),
254 "none"
255 );
256
257 getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put (
258 KeyStroke.getKeyStroke(KeyEvent.VK_V, modKey),
259 "none"
260 );
261
262 getInputMap(JComponent.WHEN_FOCUSED).put (
263 KeyStroke.getKeyStroke(KeyEvent.VK_X, modKey),
264 "none"
265 );
266
267 getInputMap(JComponent.WHEN_FOCUSED).put (
268 KeyStroke.getKeyStroke(KeyEvent.VK_C, modKey),
269 "none"
270 );
271
272 getInputMap(JComponent.WHEN_FOCUSED).put (
273 KeyStroke.getKeyStroke(KeyEvent.VK_V, modKey),
274 "none"
275 );
276
277 getInputMap().put (
278 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
279 "OpenDirectory"
280 );
281
282 getActionMap().put ("OpenDirectory", new AbstractAction() {
283 public void
284 actionPerformed(ActionEvent e) {
285 DbDirectoryTreeNode node = getSelectedDirectoryNode();
286 if(node == null) return;
287 instrumentsDbTree.setSelectedDirectoryNode(node);
288 }
289 });
290 }
291
292 public String
293 getUniqueDirectoryName() {
294 DbDirectoryTreeNode node = getParentDirectoryNode();
295 if(node == null || node.isDetached()) return null;
296 if(node != instrumentsDbTree.getSelectedDirectoryNode()) return null;
297
298 boolean b = false;
299 int c = 2;
300 String dir = "New Folder";
301
302 while(true) {
303 for(int i = 0; i < node.getChildCount(); i++) {
304
305 if(dir.equals(node.getChildAt(i).getInfo().getName())) {
306 b = true;
307 break;
308 }
309 }
310
311 if(!b) break;
312
313 b = false;
314 dir = "New Folder[" + c++ + "]";
315 }
316
317 return dir;
318 }
319
320 private final Vector<JMenu> loadInstrumentMenus = new Vector<JMenu>();
321 private final Vector<JMenu> addToMidiMapMenus = new Vector<JMenu>();
322 private final Vector<JMenu> addToOrchestraMenus = new Vector<JMenu>();
323
324 public void
325 registerLoadInstrumentMenus(JMenu menu) {
326 loadInstrumentMenus.add(menu);
327 StdA4n.updateLoadInstrumentMenu(menu, loadInstrActionFactory);
328 updateLoadInstrumentMenuState(menu);
329 }
330
331 public void
332 registerAddToMidiMapMenu(JMenu menu) {
333 addToMidiMapMenus.add(menu);
334 updateAddToMidiMapMenu(menu);
335 }
336
337 public void
338 registerAddToOrchestraMenu(JMenu menu) {
339 addToOrchestraMenus.add(menu);
340 updateAddToOrchestraMenu(menu);
341 }
342
343 private void
344 updateLoadInstrumentMenus() {
345 for(JMenu menu : loadInstrumentMenus) {
346 StdA4n.updateLoadInstrumentMenu(menu, loadInstrActionFactory);
347 updateLoadInstrumentMenuState(menu);
348 }
349 }
350
351 private void
352 updateLoadInstrumentMenuStates() {
353 for(JMenu menu : loadInstrumentMenus) updateLoadInstrumentMenuState(menu);
354 }
355
356 private void
357 updateLoadInstrumentMenuState(JMenu menu) {
358 Object obj = getLeadObject();
359 boolean b = obj == null || !(obj instanceof DbInstrumentInfo);
360 b = b || CC.getSamplerModel().getChannelCount() == 0;
361 menu.setEnabled(!b);
362 }
363
364 private void
365 updateAddToMidiMapMenus() {
366 for(JMenu menu : addToMidiMapMenus) updateAddToMidiMapMenu(menu);
367 }
368
369 private void
370 updateAddToMidiMapMenu(JMenu menu) {
371 menu.removeAll();
372 for(int i = 0; i < CC.getSamplerModel().getMidiInstrumentMapCount(); i++) {
373 MidiInstrumentMap m = CC.getSamplerModel().getMidiInstrumentMap(i);
374 menu.add(new JMenuItem(new AddToMidiMapAction(m)));
375 }
376
377 updateAddToMidiMapMenuState(menu);
378 }
379
380 private void
381 updateAddToMidiMapMenuStates() {
382 for(JMenu menu : addToMidiMapMenus) updateAddToMidiMapMenuState(menu);
383 }
384
385 private void
386 updateAddToMidiMapMenuState(JMenu menu) {
387 Object obj = getLeadObject();
388 boolean b = obj == null || !(obj instanceof DbInstrumentInfo);
389 b = b || CC.getSamplerModel().getMidiInstrumentMapCount() == 0;
390 menu.setEnabled(!b);
391 }
392
393 private void
394 updateAddToOrchestraMenus() {
395 for(JMenu menu : addToOrchestraMenus) updateAddToOrchestraMenu(menu);
396 }
397
398 private void
399 updateAddToOrchestraMenu(JMenu menu) {
400 menu.removeAll();
401 for(int i = 0; i < CC.getOrchestras().getOrchestraCount(); i++) {
402 OrchestraModel m = CC.getOrchestras().getOrchestra(i);
403 Action a = new AddToOrchestraAction(m);
404 menu.add(new JMenuItem(a));
405 }
406
407 updateAddToOrchestraMenuState(menu);
408 }
409
410 private void
411 updateAddToOrchestraMenuStates() {
412 for(JMenu menu : addToOrchestraMenus) updateAddToOrchestraMenuState(menu);
413 }
414
415 private void
416 updateAddToOrchestraMenuState(JMenu menu) {
417 Object obj = getLeadObject();
418 boolean b = obj == null || !(obj instanceof DbInstrumentInfo);
419 b = b || CC.getOrchestras().getOrchestraCount() == 0;
420 menu.setEnabled(!b);
421 }
422
423 private boolean
424 showYesNoDialog(String s) {
425 Window w = JuifeUtils.getWindow(this);
426 if(w instanceof Dialog) return HF.showYesNoDialog((Dialog)w, s);
427 if(w instanceof Frame) return HF.showYesNoDialog((Frame)w, s);
428 return HF.showYesNoDialog((Frame)null, s);
429 }
430
431 private class ReloadAction extends AbstractAction implements TreeSelectionListener {
432 ReloadAction() {
433 super(i18n.getMenuLabel("instrumentsdb.actions.reload"));
434
435 String s = i18n.getMenuLabel("instrumentsdb.actions.reload.tt");
436 putValue(SHORT_DESCRIPTION, s);
437 setEnabled(false);
438 }
439
440 @Override
441 public void
442 actionPerformed(ActionEvent e) {
443 DbDirectoryTreeNode n = instrumentsDbTree.getSelectedDirectoryNode();
444 if(n == null) return;
445 final String path = n.getInfo().getDirectoryPath();
446 instrumentsDbTree.refreshDirectoryContent(path);
447 CC.scheduleInTaskQueue(new Runnable() {
448 public void
449 run() { instrumentsDbTree.setSelectedDirectory(path); }
450 });
451 }
452
453 @Override
454 public void
455 valueChanged(TreeSelectionEvent e) {
456 DbDirectoryTreeNode n = instrumentsDbTree.getSelectedDirectoryNode();
457 setEnabled(n != null);
458 }
459 }
460
461 class CreateDirectoryAction extends AbstractAction {
462 private String directoryName = null;
463
464 CreateDirectoryAction() {
465 super(i18n.getMenuLabel("instrumentsdb.actions.createFolder"));
466
467 String s = i18n.getMenuLabel("instrumentsdb.actions.createFolder.tt");
468 putValue(SHORT_DESCRIPTION, s);
469 }
470
471 @Override
472 public void
473 actionPerformed(ActionEvent e) {
474 setDirectoryName(getUniqueDirectoryName());
475
476 String path = instrumentsDbTree.getSelectedDirectoryPath();
477 if(path.length() > 1) path += "/";
478 path += toEscapedFileName(getDirectoryName());
479
480 final InstrumentsDb.CreateDirectory t =
481 new InstrumentsDb.CreateDirectory(path);
482
483 setCreatedDirectoryName(directoryName);
484
485 t.addTaskListener(new TaskListener() {
486 public void
487 taskPerformed(TaskEvent e) {
488 if(t.doneWithErrors()) {
489 setCreatedDirectoryName(null);
490 return;
491 }
492 }
493 });
494 CC.getTaskQueue().add(t);
495 }
496
497 /**
498 * Gets the name of the directory to be created.
499 * @return The name of the directory to be created.
500 */
501 public String
502 getDirectoryName() { return directoryName; }
503
504 /**
505 * Sets the name of the directory to be created.
506 * @param name The name of the directory to be created.
507 */
508 public void
509 setDirectoryName(String name) { directoryName = name; }
510 }
511
512 class DeleteAction extends AbstractAction {
513 DeleteAction() {
514 super(i18n.getMenuLabel("instrumentsdb.actions.delete"));
515
516 String s;
517 s = i18n.getMenuLabel("instrumentsdb.actions.delete.tt");
518 putValue(SHORT_DESCRIPTION, s);
519 setEnabled(false);
520 }
521
522 @Override
523 public void
524 actionPerformed(ActionEvent e) {
525 final DbDirectoryInfo[] dirs = getSelectedDirectories();
526
527 if(dirs.length > 0) {
528 String s = i18n.getMessage("JSInstrumentsDbTable.confirmDeletion");
529 if(!showYesNoDialog(s)) return;
530
531 final Task t = new InstrumentsDb.RemoveDirectories(dirs);
532 t.addTaskListener(new TaskListener() {
533 public void
534 taskPerformed(TaskEvent e) {
535 if(instrumentsDbTree.getSelectionCount() == 0) {
536 // update search results
537 // TODO: lazily implemented
538 deleteDirectories(dirs);
539 }
540 }
541 });
542 CC.getTaskQueue().add(t);
543
544
545 }
546
547 final DbInstrumentInfo[] instrs = getSelectedInstruments();
548 if(instrs.length > 0) {
549 final Task t = new InstrumentsDb.RemoveInstruments(instrs);
550 t.addTaskListener(new TaskListener() {
551 public void
552 taskPerformed(TaskEvent e) {
553 if(instrumentsDbTree.getSelectionCount() == 0) {
554 // update search results
555 // TODO: lazily implemented
556 deleteInstruments(instrs);
557 }
558 }
559 });
560 CC.getTaskQueue().add(t);
561 }
562 }
563
564 /** Deletes the specified directories from the model */
565 private void
566 deleteDirectories(DbDirectoryInfo[] dirs) {
567 for(DbDirectoryInfo info : dirs) {
568 String path = info.getDirectoryPath();
569 getParentDirectoryNode().removeDirectoryByPathName(path);
570 getModel().fireTableDataChanged();
571 }
572 }
573
574 /** Deletes the specified instruments from the model */
575 private void
576 deleteInstruments(DbInstrumentInfo[] instrs) {
577 for(DbInstrumentInfo info : instrs) {
578 String path = info.getInstrumentPath();
579 getParentDirectoryNode().removeInstrumentByPathName(path);
580 getModel().fireTableDataChanged();
581 }
582 }
583 }
584
585 class AddInstrumentsFromFileAction extends AbstractAction {
586 AddInstrumentsFromFileAction() {
587 super(i18n.getMenuLabel("instrumentsdb.actions.addInstruments.fromFile"));
588
589 String s = "instrumentsdb.actions.addInstruments.fromFile.tt";
590 putValue(SHORT_DESCRIPTION, i18n.getMenuLabel(s));
591 }
592
593 @Override
594 public void
595 actionPerformed(ActionEvent e) {
596 String s;
597 DbDirectoryTreeNode node = getParentDirectoryNode();
598 if(node == null || node.getInfo() == null) s = null;
599 else s = node.getInfo().getDirectoryPath();
600
601 JSAddDbInstrumentsFromFileDlg dlg;
602 Icon ico = instrumentsDbTree.getView().getOpenIcon();
603 Window w = JuifeUtils.getWindow(JSInstrumentsDbTable.this);
604 if(w instanceof Dialog) {
605 dlg = new JSAddDbInstrumentsFromFileDlg((Dialog)w, s, ico);
606 } else if(w instanceof Frame) {
607 dlg = new JSAddDbInstrumentsFromFileDlg((Frame)w, s, ico);
608 } else {
609 dlg = new JSAddDbInstrumentsFromFileDlg((Frame)null, s, ico);
610 }
611
612 dlg.setVisible(true);
613 if(w != null) w.toFront();
614 }
615 }
616
617 class AddInstrumentsFromDirAction extends AbstractAction {
618 AddInstrumentsFromDirAction() {
619 super(i18n.getMenuLabel("instrumentsdb.actions.addInstruments.fromDir"));
620
621 String s = "instrumentsdb.actions.addInstruments.fromDir.tt";
622 putValue(SHORT_DESCRIPTION, i18n.getMenuLabel(s));
623 }
624
625 @Override
626 public void
627 actionPerformed(ActionEvent e) {
628 String s;
629 DbDirectoryTreeNode node = getParentDirectoryNode();
630 if(node == null || node.getInfo() == null) s = null;
631 else s = node.getInfo().getDirectoryPath();
632
633 JSAddDbInstrumentsFromDirDlg dlg;
634 Icon ico = instrumentsDbTree.getView().getOpenIcon();
635 Window w = JuifeUtils.getWindow(JSInstrumentsDbTable.this);
636 if(w instanceof Dialog) {
637 dlg = new JSAddDbInstrumentsFromDirDlg((Dialog)w, s, ico);
638 } else if(w instanceof Frame) {
639 dlg = new JSAddDbInstrumentsFromDirDlg((Frame)w, s, ico);
640 } else {
641 dlg = new JSAddDbInstrumentsFromDirDlg((Frame)null, s, ico);
642 }
643
644 dlg.setVisible(true);
645 if(w != null) w.toFront();
646 }
647 }
648
649 class LoadInstrumentAction extends StdA4n.LoadInstrumentAction {
650 LoadInstrumentAction(SamplerChannelModel model, boolean onPanel) {
651 super(model, onPanel);
652 }
653
654 @Override
655 public void
656 actionPerformed(ActionEvent e) {
657 Object obj = getLeadObject();
658 if(obj == null || !(obj instanceof DbInstrumentInfo)) return;
659 DbInstrumentInfo info = (DbInstrumentInfo)obj;
660 int idx = info.getInstrumentIndex();
661 channelModel.setBackendEngineType(info.getFormatFamily()); // TODO: fix this
662 channelModel.loadBackendInstrument(info.getFilePath(), idx);
663 }
664 }
665
666 private LoadInstrumentActionFactory loadInstrActionFactory = new LoadInstrumentActionFactory();
667
668 class LoadInstrumentActionFactory implements StdA4n.LoadInstrumentActionFactory {
669 public StdA4n.LoadInstrumentAction
670 createLoadInstrumentAction(SamplerChannelModel model, boolean onPanel) {
671 return new LoadInstrumentAction(model, onPanel);
672 }
673 }
674
675 class AddToMidiMapAction extends AbstractAction {
676 private final MidiInstrumentMap midiMap;
677
678 AddToMidiMapAction(MidiInstrumentMap map) {
679 super(map.getName());
680 midiMap = map;
681 }
682
683 @Override
684 public void
685 actionPerformed(ActionEvent e) {
686 DbInstrumentInfo[] instruments = getSelectedInstruments();
687 int l = instruments.length;
688 if(l == 0) return;
689
690 if(l > 4) {
691 String s = "JSInstrumentsDbTable.confirmAddToMidiMap";
692 s = i18n.getMessage(s, l, midiMap.getName());
693 if(!HF.showYesNoDialog(JSInstrumentsDbTable.this, s)) return;
694 }
695
696 JSAddMidiInstrumentDlg dlg;
697 Window w = JuifeUtils.getWindow(JSInstrumentsDbTable.this);
698
699 boolean b = instruments.length > 1;
700 boolean apply2all = false;
701 float volume = 1.0f;
702 MidiInstrumentInfo.LoadMode loadMode = MidiInstrumentInfo.LoadMode.DEFAULT;
703 final LinkedList<MidiInstrumentInfo> instrs = new LinkedList<MidiInstrumentInfo>();
704
705 for(DbInstrumentInfo i : instruments) {
706 if(!apply2all) {
707 if(w instanceof Dialog) {
708 dlg = new JSAddMidiInstrumentDlg((Dialog)w, midiMap, i, b);
709 } else if(w instanceof Frame) {
710 dlg = new JSAddMidiInstrumentDlg((Frame)w, midiMap, i, b);
711 } else {
712 dlg = new JSAddMidiInstrumentDlg((Frame)null, midiMap, i, b);
713 }
714
715 dlg.setVisible(true);
716 if(dlg.isApplyToAllSelected()) {
717 if(dlg.isCancelled()) break;
718
719 apply2all = true;
720 volume = dlg.getVolume();
721 loadMode = dlg.getLoadMode();
722 }
723 } else {
724 final MidiInstrumentInfo instrInfo = new MidiInstrumentInfo();
725 instrInfo.setName(i.getName());
726 instrInfo.setFilePath(i.getFilePath());
727 instrInfo.setInstrumentIndex(i.getInstrumentIndex());
728 instrInfo.setEngine(i.getEngine());
729 instrInfo.setVolume(volume);
730 instrInfo.setLoadMode(loadMode);
731
732 instrs.add(instrInfo);
733 }
734 }
735
736 if(instrs.isEmpty()) return;
737
738 addToMap(instrs);
739 }
740
741 private void
742 addToMap(final LinkedList<MidiInstrumentInfo> instrs) {
743 CC.scheduleInTaskQueue(new Runnable() {
744 public void
745 run() { addToMap0(instrs); }
746 });
747 }
748
749 private void
750 addToMap0(final LinkedList<MidiInstrumentInfo> instrs) {
751 if(instrs.isEmpty()) return;
752
753 MidiInstrumentEntry e = midiMap.getAvailableEntry();
754 if(e == null) {
755 CC.getLogger().info("No available MIDI entry");
756 return;
757 }
758
759 int id = midiMap.getMapId();
760 int b = e.getMidiBank();
761 int p = e.getMidiProgram();
762 final Midi.MapInstrument t = new Midi.MapInstrument(id, b, p, instrs.pop());
763
764 t.addTaskListener(new TaskListener() {
765 public void
766 taskPerformed(TaskEvent e) {
767 CC.scheduleTask(new Midi.UpdateInstruments(midiMap.getMapId()));
768 addToMap(instrs);
769 }
770 });
771
772 CC.getTaskQueue().add(t);
773 }
774 }
775
776 class AddToOrchestraAction extends AbstractAction {
777 private final OrchestraModel orchestraModel;
778
779 AddToOrchestraAction(OrchestraModel model) {
780 super(model.getName());
781 orchestraModel = model;
782 }
783
784 @Override
785 public void
786 actionPerformed(ActionEvent e) {
787 DbInstrumentInfo[] instruments = getSelectedInstruments();
788 int l = instruments.length;
789 if(l == 0) return;
790
791 if(l > 1) {
792 String s = "JSInstrumentsDbTable.confirmAddToOrchestra";
793 s = i18n.getMessage(s, l, orchestraModel.getName());
794 if(!HF.showYesNoDialog(JSInstrumentsDbTable.this, s)) return;
795 }
796
797 for(DbInstrumentInfo i : instruments) {
798 OrchestraInstrument instr = new OrchestraInstrument();
799 instr.setFilePath(i.getFilePath());
800 instr.setInstrumentIndex(i.getInstrumentIndex());
801 instr.setName(i.getName());
802 instr.setDescription(i.getDescription());
803 instr.setEngine(i.getFormatFamily()); // TODO: this should be fixed
804 orchestraModel.addInstrument(instr);
805 }
806 }
807 }
808
809 class PropertiesAction extends AbstractAction {
810 PropertiesAction() {
811 super(i18n.getMenuLabel("instrumentsdb.actions.properties"));
812
813 String s;
814 s = i18n.getMenuLabel("instrumentsdb.actions.properties.tt");
815 putValue(SHORT_DESCRIPTION, s);
816 setEnabled(false);
817 }
818
819 @Override
820 public void
821 actionPerformed(ActionEvent e) {
822 Object obj = getLeadObject();
823 if(obj == null) {
824 DbDirectoryTreeNode node = getParentDirectoryNode();
825 if(node == null || node.getInfo() == null) return;
826 showDirectoryProperties(node.getInfo());
827 return;
828 }
829
830 if(obj instanceof DbDirectoryInfo) {
831 showDirectoryProperties((DbDirectoryInfo)obj);
832 } else if(obj instanceof DbInstrumentInfo) {
833 showInstrumentProperties((DbInstrumentInfo)obj);
834 }
835 }
836
837 private void
838 showInstrumentProperties(DbInstrumentInfo instr) {
839 JPanel p = new JSDbInstrumentPropsPane(instr);
840 String s = i18n.getLabel("JSInstrumentsDbTable.instrProps");
841 showDialog(s, p);
842 }
843
844 private void
845 showDirectoryProperties(DbDirectoryInfo dir) {
846 JPanel p = new JSDbDirectoryPropsPane(dir);
847 String s = i18n.getLabel("JSInstrumentsDbTable.dirProps");
848 showDialog(s, p);
849 }
850
851 private void
852 showDialog(String title, JPanel mainPane) {
853 InformationDialog dlg;
854 Window w = JuifeUtils.getWindow(JSInstrumentsDbTable.this);
855 if(w instanceof Dialog) {
856 dlg = new InformationDialog((Dialog)w, title, mainPane);
857 } else if(w instanceof Frame) {
858 dlg = new InformationDialog((Frame)w, title, mainPane);
859 } else {
860 dlg = new InformationDialog((Frame)null, title, mainPane);
861 }
862
863 dlg.setMinimumSize(dlg.getPreferredSize());
864 dlg.setVisible(true);
865 }
866 }
867
868 class RenameAction extends AbstractAction {
869 private String directoryPath = null;
870
871 RenameAction() {
872 super(i18n.getMenuLabel("instrumentsdb.edit.rename"));
873
874 String s = i18n.getMenuLabel("instrumentsdb.edit.rename.tt");
875 putValue(SHORT_DESCRIPTION, s);
876 setEnabled(false);
877 }
878
879 @Override
880 public void
881 actionPerformed(ActionEvent e) {
882 int i = getSelectionModel().getLeadSelectionIndex();
883 if(i == -1) return;
884 editCellAt(i, 0);
885 }
886 }
887
888 class ChangeDescriptionAction extends AbstractAction {
889 private String directoryPath = null;
890
891 ChangeDescriptionAction() {
892 super(i18n.getMenuLabel("instrumentsdb.edit.description"));
893
894 String s = i18n.getMenuLabel("instrumentsdb.edit.description.tt");
895 putValue(SHORT_DESCRIPTION, s);
896 setEnabled(false);
897 }
898
899 @Override
900 public void
901 actionPerformed(ActionEvent e) {
902 Object obj = getLeadObject();
903 if(obj == null) return;
904
905 if(obj instanceof DbDirectoryInfo) {
906 DbDirectoryInfo info = (DbDirectoryInfo)obj;
907 String s = editDescription(info.getDescription());
908 if(s == null) return;
909 String path = info.getDirectoryPath();
910 Task t = new InstrumentsDb.SetDirectoryDescription(path, s);
911 CC.getTaskQueue().add(t);
912 } else if(obj instanceof DbInstrumentInfo) {
913 DbInstrumentInfo info = (DbInstrumentInfo)obj;
914 String s = editDescription(info.getDescription());
915 if(s == null) return;
916 String path = info.getInstrumentPath();
917 Task t = new InstrumentsDb.SetInstrumentDescription(path, s);
918 CC.getTaskQueue().add(t);
919 }
920 }
921
922 private String
923 editDescription(String s) {
924 JSDbDescriptionDlg dlg;
925 Window w = JuifeUtils.getWindow(JSInstrumentsDbTable.this);
926 if(w instanceof Dialog) {
927 dlg = new JSDbDescriptionDlg((Dialog)w);
928 } else if(w instanceof Frame) {
929 dlg = new JSDbDescriptionDlg((Frame)w);
930 } else {
931 dlg = new JSDbDescriptionDlg((Frame)null);
932 }
933
934 dlg.setDescription(s);
935 dlg.setVisible(true);
936 if(dlg.isCancelled()) return null;
937 return dlg.getDescription();
938 }
939 }
940
941 class CutAction extends AbstractAction {
942 CutAction() {
943 super(i18n.getMenuLabel("instrumentsdb.edit.cut"));
944
945 String s = i18n.getMenuLabel("instrumentsdb.edit.cut.tt");
946 putValue(SHORT_DESCRIPTION, s);
947 setEnabled(false);
948 }
949
950 @Override
951 public void
952 actionPerformed(ActionEvent e) {
953 getDbClipboard().setDirectories(getSelectedDirectories());
954 getDbClipboard().setInstruments(getSelectedInstruments());
955 getDbClipboard().setOperation(DbClipboard.Operation.CUT);
956 }
957 }
958
959 class CopyAction extends AbstractAction {
960 CopyAction() {
961 super(i18n.getMenuLabel("instrumentsdb.edit.copy"));
962
963 String s = i18n.getMenuLabel("instrumentsdb.edit.copy.tt");
964 putValue(SHORT_DESCRIPTION, s);
965 setEnabled(false);
966 }
967
968 @Override
969 public void
970 actionPerformed(ActionEvent e) {
971 getDbClipboard().setDirectories(getSelectedDirectories());
972 getDbClipboard().setInstruments(getSelectedInstruments());
973 getDbClipboard().setOperation(DbClipboard.Operation.COPY);
974 }
975 }
976
977 class PasteAction extends AbstractAction implements TreeSelectionListener, ChangeListener {
978 PasteAction() {
979 super(i18n.getMenuLabel("instrumentsdb.edit.paste"));
980
981 String s = i18n.getMenuLabel("instrumentsdb.edit.paste.tt");
982 putValue(SHORT_DESCRIPTION, s);
983 setEnabled(false);
984 getDbClipboard().addChangeListener(this);
985 }
986
987 @Override
988 public void
989 actionPerformed(ActionEvent e) {
990 DbDirectoryInfo[] dirs = getDbClipboard().getDirectories();
991 DbInstrumentInfo[] instrs = getDbClipboard().getInstruments();
992 String dest = instrumentsDbTree.getSelectedDirectoryPath();
993
994 Task t;
995 if(getDbClipboard().getOperation() == DbClipboard.Operation.CUT) {
996 t = new InstrumentsDb.Move(dirs, instrs, dest);
997 getDbClipboard().setDirectories(new DbDirectoryInfo[0]);
998 getDbClipboard().setInstruments(new DbInstrumentInfo[0]);
999 } else if(getDbClipboard().getOperation() == DbClipboard.Operation.COPY) {
1000 t = new InstrumentsDb.Copy(dirs, instrs, dest);
1001 } else {
1002 return;
1003 }
1004
1005 CC.getTaskQueue().add(t);
1006 }
1007
1008 @Override
1009 public void
1010 valueChanged(TreeSelectionEvent e) { updateState(); }
1011
1012 @Override
1013 public void
1014 stateChanged(ChangeEvent e) { updateState(); }
1015
1016 private void
1017 updateState() {
1018 DbDirectoryTreeNode n = instrumentsDbTree.getSelectedDirectoryNode();
1019 if(n == null) {
1020 setEnabled(false);
1021 return;
1022 }
1023
1024 int dirs = getDbClipboard().getDirectories().length;
1025 setEnabled(dirs > 0 || getDbClipboard().getInstruments().length > 0);
1026 }
1027 }
1028
1029 class InstrumentsDbCellRenderer extends JLabel implements TableCellRenderer {
1030
1031 InstrumentsDbCellRenderer() {
1032 setOpaque(true);
1033 setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3));
1034 }
1035
1036 @Override
1037 public Component
1038 getTableCellRendererComponent (
1039 JTable table,
1040 Object value,
1041 boolean isSelected,
1042 boolean hasFocus,
1043 int row,
1044 int column
1045 ) {
1046 if(column == 0 && value != null) {
1047 String s;
1048 if(value instanceof DbDirectoryInfo) {
1049 setIcon(getView().getFolderIcon());
1050 s = ((DbDirectoryInfo)value).getDescription();
1051 setToolTipText(s.length() == 0 ? null : s);
1052 } else if(value instanceof String) {
1053 setIcon(getView().getFolderIcon());
1054 setToolTipText(null);
1055 } else if(value instanceof DbInstrumentInfo) {
1056 DbInstrumentInfo info = (DbInstrumentInfo)value;
1057 if("GIG".equals(info.getFormatFamily())) { // TODO: fix it!
1058 setIcon(getView().getGigInstrumentIcon());
1059 } else {
1060 setIcon(getView().getInstrumentIcon());
1061 }
1062
1063 s = info.getDescription();
1064 setToolTipText(s.length() == 0 ? null : s);
1065 } else {
1066 setIcon(null);
1067 setToolTipText(null);
1068 }
1069 } else {
1070 setIcon(null);
1071 setToolTipText(null);
1072 }
1073
1074 if(value != null) setText(value.toString());
1075 else setText("");
1076
1077 if (isSelected) {
1078 setBackground(table.getSelectionBackground());
1079 setForeground(table.getSelectionForeground());
1080 } else {
1081 setBackground(table.getBackground());
1082 setForeground(table.getForeground());
1083 }
1084
1085 ColumnType ct =
1086 ((InstrumentsDbTableModel)table.getModel()).getColumnType(column);
1087
1088 if(ct == ColumnType.IS_DRUM || ct == ColumnType.FORMAT_FAMILY) {
1089 setHorizontalAlignment(CENTER);
1090 } else if ( ct == ColumnType.SIZE ||
1091 ct == ColumnType.INSTRUMENT_NR ||
1092 ct == ColumnType.FORMAT_VERSION
1093 ) {
1094 setHorizontalAlignment(RIGHT);
1095 } else {
1096 setHorizontalAlignment(LEFT);
1097 }
1098
1099 return this;
1100 }
1101 }
1102
1103 private final EventHandler eventHandler = new EventHandler();
1104
1105 private EventHandler
1106 getHandler() { return eventHandler; }
1107
1108 private class EventHandler implements ListSelectionListener, TreeSelectionListener,
1109 SamplerChannelListListener, ListListener<OrchestraModel> {
1110
1111 @Override
1112 public void
1113 valueChanged(ListSelectionEvent e) {
1114 boolean b = !getSelectionModel().isSelectionEmpty();
1115 deleteAction.setEnabled(b);
1116 propertiesAction.setEnabled(b || instrumentsDbTree.getSelectionCount() > 0);
1117 renameAction.setEnabled(b);
1118 changeDescriptionAction.setEnabled(b);
1119 cutAction.setEnabled(b);
1120 copyAction.setEnabled(b);
1121 updateLoadInstrumentMenuStates();
1122 updateAddToMidiMapMenuStates();
1123 updateAddToOrchestraMenuStates();
1124 }
1125
1126 @Override
1127 public void
1128 valueChanged(TreeSelectionEvent e) {
1129 DbDirectoryTreeNode n = instrumentsDbTree.getSelectedDirectoryNode();
1130 setParentDirectoryNode(n);
1131 reloadAction.setEnabled(n != null);
1132 createDirectoryAction.setEnabled(n != null);
1133 propertiesAction.setEnabled(n != null || getLeadObject() != null);
1134 }
1135
1136 @Override
1137 public void
1138 channelAdded(SamplerChannelListEvent e) {
1139 if(CC.getSamplerModel().getChannelListIsAdjusting()) return;
1140 updateLoadInstrumentMenus();
1141 }
1142
1143 @Override
1144 public void
1145 channelRemoved(SamplerChannelListEvent e) {
1146 updateLoadInstrumentMenus();
1147 }
1148
1149 @Override
1150 public void
1151 entryAdded(ListEvent<OrchestraModel> e) { updateAddToOrchestraMenus(); }
1152
1153 @Override
1154 public void
1155 entryRemoved(ListEvent<OrchestraModel> e) { updateAddToOrchestraMenus(); }
1156 }
1157
1158 class ContextMenu extends MouseAdapter {
1159 private final JPopupMenu instrumentMenu = new JPopupMenu();
1160 private final JPopupMenu directoryMenu = new JPopupMenu();
1161 private final JPopupMenu menu = new JPopupMenu();
1162
1163 private JMenu loadInstrumentMenu;
1164 private JMenu addToMidiMapMenu;
1165 private JMenu addToOrchestraMenu;
1166
1167 class MenuItem extends JMenuItem {
1168 MenuItem(Action a) { super(a); }
1169
1170 public Icon
1171 getIcon() { return null; }
1172 }
1173
1174 ContextMenu() {
1175 JMenuItem mi = new JMenuItem(pasteAction);
1176 mi.setIcon(null);
1177 menu.add(mi);
1178
1179 menu.addSeparator();
1180
1181 mi = new MenuItem(createDirectoryAction);
1182 mi.setIcon(null);
1183 menu.add(mi);
1184
1185 String s = i18n.getMenuLabel("instrumentsdb.actions.addInstruments");
1186 JMenu addInstrumentsMenu = new JMenu(s);
1187 menu.add(addInstrumentsMenu);
1188
1189 mi = new JMenuItem(addInstrumentsFromFileAction);
1190 mi.setIcon(null);
1191 addInstrumentsMenu.add(mi);
1192
1193 mi = new JMenuItem(addInstrumentsFromDirAction);
1194 mi.setIcon(null);
1195 addInstrumentsMenu.add(mi);
1196
1197 menu.addSeparator();
1198
1199 mi = new MenuItem(reloadAction);
1200 mi.setIcon(null);
1201 menu.add(mi);
1202
1203 menu.addSeparator();
1204
1205 mi = new JMenuItem(propertiesAction);
1206 mi.setIcon(null);
1207 menu.add(mi);
1208
1209 // Instrument's context menu
1210 mi = new JMenuItem(cutAction);
1211 mi.setIcon(null);
1212 instrumentMenu.add(mi);
1213
1214 mi = new JMenuItem(copyAction);
1215 mi.setIcon(null);
1216 instrumentMenu.add(mi);
1217
1218 instrumentMenu.addSeparator();
1219
1220 mi = new JMenuItem(deleteAction);
1221 mi.setIcon(null);
1222 instrumentMenu.add(mi);
1223
1224 mi = new JMenuItem(renameAction);
1225 mi.setIcon(null);
1226 instrumentMenu.add(mi);
1227
1228 mi = new JMenuItem(changeDescriptionAction);
1229 mi.setIcon(null);
1230 instrumentMenu.add(mi);
1231
1232 instrumentMenu.addSeparator();
1233
1234 s = i18n.getMenuLabel("instrumentsdb.actions.loadInstrument");
1235 loadInstrumentMenu = CC.getViewConfig().createMultiColumnMenu(s);
1236 instrumentMenu.add(loadInstrumentMenu);
1237 registerLoadInstrumentMenus(loadInstrumentMenu);
1238
1239 s = i18n.getMenuLabel("instrumentsdb.actions.addToMidiMap");
1240 addToMidiMapMenu = CC.getViewConfig().createMultiColumnMenu(s);
1241 instrumentMenu.add(addToMidiMapMenu);
1242 registerAddToMidiMapMenu(addToMidiMapMenu);
1243
1244 s = i18n.getMenuLabel("instrumentsdb.actions.addToOrchestra");
1245 addToOrchestraMenu = CC.getViewConfig().createMultiColumnMenu(s);
1246 instrumentMenu.add(addToOrchestraMenu);
1247 registerAddToOrchestraMenu(addToOrchestraMenu);
1248
1249 instrumentMenu.addSeparator();
1250
1251 mi = new JMenuItem(propertiesAction);
1252 mi.setIcon(null);
1253 instrumentMenu.add(mi);
1254
1255 // Directory's context menu
1256 mi = new JMenuItem(cutAction);
1257 mi.setIcon(null);
1258 directoryMenu.add(mi);
1259
1260 mi = new JMenuItem(copyAction);
1261 mi.setIcon(null);
1262 directoryMenu.add(mi);
1263
1264 directoryMenu.addSeparator();
1265
1266 mi = new JMenuItem(deleteAction);
1267 mi.setIcon(null);
1268 directoryMenu.add(mi);
1269
1270 mi = new JMenuItem(renameAction);
1271 mi.setIcon(null);
1272 directoryMenu.add(mi);
1273
1274 mi = new JMenuItem(changeDescriptionAction);
1275 mi.setIcon(null);
1276 directoryMenu.add(mi);
1277
1278 directoryMenu.addSeparator();
1279
1280 mi = new JMenuItem(propertiesAction);
1281 mi.setIcon(null);
1282 directoryMenu.add(mi);
1283 }
1284
1285 @Override
1286 public void
1287 mousePressed(MouseEvent e) {
1288 if(e.isPopupTrigger()) show(e);
1289 }
1290
1291 @Override
1292 public void
1293 mouseReleased(MouseEvent e) {
1294 if(e.isPopupTrigger()) show(e);
1295 }
1296
1297 void
1298 show(MouseEvent e) {
1299 Object obj = getLeadObject();
1300 if(obj == null) {
1301 menu.show(e.getComponent(), e.getX(), e.getY());
1302 return;
1303 }
1304
1305 if(obj instanceof DbInstrumentInfo) {
1306 instrumentMenu.show(e.getComponent(), e.getX(), e.getY());
1307 return;
1308 }
1309
1310 if(obj instanceof DbDirectoryInfo) {
1311 directoryMenu.show(e.getComponent(), e.getX(), e.getY());
1312 return;
1313 }
1314 }
1315 }
1316 }

  ViewVC Help
Powered by ViewVC