/[svn]/jsampler/trunk/src/org/jsampler/CC.java
ViewVC logotype

Annotation of /jsampler/trunk/src/org/jsampler/CC.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1767 - (hide annotations) (download)
Mon Sep 8 00:19:27 2008 UTC (15 years, 7 months ago) by iliev
File size: 40337 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 787 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4 iliev 1767 * Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5 iliev 787 *
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;
24    
25     import java.awt.event.ActionEvent;
26     import java.awt.event.ActionListener;
27    
28 iliev 911 import java.io.ByteArrayOutputStream;
29 iliev 1143 import java.io.File;
30     import java.io.FileInputStream;
31 iliev 787 import java.io.FileOutputStream;
32 iliev 1143 import java.io.InputStream;
33 iliev 787
34 iliev 911 import java.util.Vector;
35    
36 iliev 787 import java.util.logging.Handler;
37     import java.util.logging.Level;
38     import java.util.logging.Logger;
39     import java.util.logging.SimpleFormatter;
40     import java.util.logging.StreamHandler;
41    
42     import javax.swing.Timer;
43    
44 iliev 1688 import javax.swing.event.ChangeEvent;
45     import javax.swing.event.ChangeListener;
46    
47 iliev 911 import net.sf.juife.Task;
48     import net.sf.juife.TaskQueue;
49    
50     import net.sf.juife.event.TaskEvent;
51     import net.sf.juife.event.TaskListener;
52     import net.sf.juife.event.TaskQueueEvent;
53     import net.sf.juife.event.TaskQueueListener;
54    
55 iliev 1143 import org.jsampler.event.ListEvent;
56     import org.jsampler.event.ListListener;
57 iliev 911 import org.jsampler.event.OrchestraEvent;
58     import org.jsampler.event.OrchestraListener;
59    
60 iliev 787 import org.jsampler.task.*;
61    
62     import org.jsampler.view.JSMainFrame;
63     import org.jsampler.view.JSProgress;
64 iliev 1285 import org.jsampler.view.JSViewConfig;
65 iliev 1204 import org.jsampler.view.InstrumentsDbTreeModel;
66 iliev 787
67 iliev 1143 import org.linuxsampler.lscp.AudioOutputChannel;
68     import org.linuxsampler.lscp.AudioOutputDevice;
69 iliev 787 import org.linuxsampler.lscp.Client;
70 iliev 1143 import org.linuxsampler.lscp.FxSend;
71     import org.linuxsampler.lscp.MidiInputDevice;
72     import org.linuxsampler.lscp.MidiPort;
73     import org.linuxsampler.lscp.Parameter;
74     import org.linuxsampler.lscp.SamplerChannel;
75    
76 iliev 787 import org.linuxsampler.lscp.event.*;
77    
78 iliev 911 import org.w3c.dom.Document;
79     import org.w3c.dom.Node;
80 iliev 787
81 iliev 1143 import static org.jsampler.JSI18n.i18n;
82 iliev 787
83 iliev 1143
84 iliev 787 /**
85 iliev 911 * This class serves as a 'Control Center' of the application.
86     * It also provides some fundamental routines and access to most used objects.
87 iliev 787 * @author Grigor Iliev
88     */
89     public class CC {
90     private static Handler handler;
91 iliev 911 private static FileOutputStream fos;
92 iliev 787
93 iliev 1285 private static JSViewConfig viewConfig = null;
94 iliev 787 private static JSMainFrame mainFrame = null;
95     private static JSProgress progress = null;
96    
97     private final static Client lsClient = new Client();
98    
99 iliev 1143 private static String jSamplerHome = null;
100    
101 iliev 787 private final static TaskQueue taskQueue = new TaskQueue();
102 iliev 911 private final static Timer timer = new Timer(2000, null);
103 iliev 787
104 iliev 1143 /** Forbits the instantiation of this class. */
105     private
106     CC() { }
107 iliev 787
108 iliev 911 /**
109     * Returns the logger to be used for logging events.
110     * @return The logger to be used for logging events.
111     */
112 iliev 787 public static Logger
113     getLogger() {
114     return Logger.getLogger (
115     "org.jsampler",
116     "org.jsampler.langprops.LogsBundle"
117     );
118     }
119    
120 iliev 911 /**
121     * Returns the task queue to be used for scheduling tasks
122     * for execution out of the event-dispatching thread.
123     * @return The task queue to be used for scheduling tasks
124     * for execution out of the event-dispatching thread.
125     */
126 iliev 787 public static TaskQueue
127     getTaskQueue() { return taskQueue; }
128    
129 iliev 911 /**
130 iliev 1204 * Adds the specified task to the task queue. All task in the
131     * queue equal to the specified task are removed from the queue.
132     */
133     public static void
134     scheduleTask(Task t) {
135     while(getTaskQueue().removeTask(t)) { }
136    
137     getTaskQueue().add(t);
138     }
139    
140     /**
141 iliev 1734 * Adds the specified task to the task queue only if the last
142     * task in the is not equal to <code>t</code>.
143     */
144     public static void
145     addTask(Task t) {
146     Task[] tasks = getTaskQueue().getPendingTasks();
147     if(tasks.length > 0 && tasks[tasks.length - 1].equals(t)) return;
148     getTaskQueue().add(t);
149     }
150    
151     /**
152 iliev 1285 * Gets the configuration of the current view.
153     */
154     public static JSViewConfig
155     getViewConfig() { return viewConfig; }
156    
157 iliev 1767 public static JSPrefs
158 iliev 1688 preferences() { return getViewConfig().preferences(); }
159    
160 iliev 1285 /**
161     * Sets the configuration of the current view.
162     */
163     public static void
164     setViewConfig(JSViewConfig viewConfig) { CC.viewConfig = viewConfig; }
165    
166     /**
167 iliev 911 * Returns the main window of this application.
168     * @return The main window of this application.
169     */
170 iliev 787 public static JSMainFrame
171     getMainFrame() { return mainFrame; }
172    
173 iliev 911 /**
174     * Sets the main window of this application.
175     * @param mainFrame The main window of this application.
176     */
177 iliev 787 public static void
178     setMainFrame(JSMainFrame mainFrame) { CC.mainFrame = mainFrame; }
179    
180 iliev 911 /**
181     * Gets the progress indicator of this application.
182     * @return The progress indicator of this application.
183     */
184 iliev 787 public static JSProgress
185     getProgressIndicator() { return progress; }
186    
187 iliev 911 /**
188     * Sets the progress indicator to be used by this application.
189     * @param progress The progress indicator to be used by this application.
190     */
191 iliev 787 public static void
192     setProgressIndicator(JSProgress progress) { CC.progress = progress; }
193    
194 iliev 911 /**
195 iliev 1143 * Gets the absolute path to the JSampler's home location.
196     * @return The absolute path to the JSampler's home location
197     * or <code>null</code> if the JSampler's home location is not specified yet.
198     */
199     public static String
200     getJSamplerHome() { return jSamplerHome; }
201    
202     /**
203     * Sets the location of the JSampler's home.
204     * @param path The new absolute path to the JSampler's home location.
205     */
206     public static void
207     setJSamplerHome(String path) {
208     jSamplerHome = path;
209     Prefs.setJSamplerHome(jSamplerHome);
210     }
211    
212     /**
213 iliev 911 * This method does the initial preparation of the application.
214     */
215 iliev 787 protected static void
216     initJSampler() {
217     fos = null;
218 iliev 1143 setJSamplerHome(Prefs.getJSamplerHome());
219     String s = getJSamplerHome();
220     try {
221     if(s != null) {
222     s += File.separator + "jsampler.log";
223     File f = new File(s);
224     if(f.isFile()) HF.createBackup("jsampler.log", "jsampler.log.0");
225     fos = new FileOutputStream(s);
226     }
227     } catch(Exception x) { x.printStackTrace(); }
228 iliev 787
229     if(fos == null) handler = new StreamHandler(System.out, new SimpleFormatter());
230     else handler = new StreamHandler(fos, new SimpleFormatter());
231    
232     handler.setLevel(Level.FINE);
233     getLogger().addHandler(handler);
234     getLogger().setLevel(Level.FINE);
235 iliev 1204 Logger.getLogger("org.linuxsampler.lscp").setLevel(Level.FINE);
236 iliev 787 Logger.getLogger("org.linuxsampler.lscp").addHandler(handler);
237    
238     // Flushing logs on every second
239     new java.util.Timer().schedule(new java.util.TimerTask() {
240     public void
241     run() { if(handler != null) handler.flush(); }
242     }, 1000, 1000);
243    
244 iliev 1767 getLogger().fine("CC.jsStarted");
245 iliev 787
246     HF.setUIDefaultFont(Prefs.getInterfaceFont());
247    
248     timer.setRepeats(false);
249    
250     timer.addActionListener(new ActionListener() {
251     public void
252     actionPerformed(ActionEvent e) { CC.getProgressIndicator().start(); }
253     });
254    
255 iliev 911 taskQueue.addTaskQueueListener(getHandler());
256 iliev 787
257     taskQueue.start();
258    
259 iliev 1143 getClient().removeChannelCountListener(getHandler());
260 iliev 911 getClient().addChannelCountListener(getHandler());
261 iliev 1143
262     getClient().removeChannelInfoListener(getHandler());
263 iliev 911 getClient().addChannelInfoListener(getHandler());
264 iliev 1143
265     getClient().removeFxSendCountListener(getHandler());
266     getClient().addFxSendCountListener(getHandler());
267    
268     getClient().removeFxSendInfoListener(getHandler());
269     getClient().addFxSendInfoListener(getHandler());
270    
271     getClient().removeStreamCountListener(getHandler());
272 iliev 911 getClient().addStreamCountListener(getHandler());
273 iliev 1143
274     getClient().removeVoiceCountListener(getHandler());
275 iliev 911 getClient().addVoiceCountListener(getHandler());
276 iliev 1143
277 iliev 1545 getClient().removeTotalStreamCountListener(getHandler());
278     getClient().addTotalStreamCountListener(getHandler());
279    
280 iliev 1143 getClient().removeTotalVoiceCountListener(getHandler());
281 iliev 911 getClient().addTotalVoiceCountListener(getHandler());
282    
283 iliev 1143 getClient().removeAudioDeviceCountListener(audioDeviceCountListener);
284     getClient().addAudioDeviceCountListener(audioDeviceCountListener);
285 iliev 911
286 iliev 1143 getClient().removeAudioDeviceInfoListener(audioDeviceInfoListener);
287     getClient().addAudioDeviceInfoListener(audioDeviceInfoListener);
288    
289     getClient().removeMidiDeviceCountListener(midiDeviceCountListener);
290     getClient().addMidiDeviceCountListener(midiDeviceCountListener);
291    
292     getClient().removeMidiDeviceInfoListener(midiDeviceInfoListener);
293     getClient().addMidiDeviceInfoListener(midiDeviceInfoListener);
294    
295     getClient().removeMidiInstrumentMapCountListener(midiInstrMapCountListener);
296     getClient().addMidiInstrumentMapCountListener(midiInstrMapCountListener);
297    
298     getClient().removeMidiInstrumentMapInfoListener(midiInstrMapInfoListener);
299     getClient().addMidiInstrumentMapInfoListener(midiInstrMapInfoListener);
300    
301     getClient().removeMidiInstrumentCountListener(getHandler());
302     getClient().addMidiInstrumentCountListener(getHandler());
303    
304     getClient().removeMidiInstrumentInfoListener(getHandler());
305     getClient().addMidiInstrumentInfoListener(getHandler());
306    
307     getClient().removeGlobalInfoListener(getHandler());
308     getClient().addGlobalInfoListener(getHandler());
309     }
310    
311     /**
312     * Checks whether the JSampler home directory is specified and exist.
313     * If the JSampler home directory is not specifed, or is specified
314     * but doesn't exist, a procedure of specifying a JSampler home
315     * directory is initiated.
316     * @see org.jsampler.view.JSMainFrame#installJSamplerHome
317     */
318     public static void
319     checkJSamplerHome() {
320     if(getJSamplerHome() != null) {
321     File f = new File(getJSamplerHome());
322 iliev 1285 if(f.exists() && f.isDirectory()) {
323     return;
324     }
325 iliev 911 }
326 iliev 1143
327 iliev 1767 getMainFrame().installJSamplerHome();
328 iliev 787 }
329    
330 iliev 1143 /**
331     * Changes the JSampler's home directory and moves all files from
332     * the old JSampler's home directory to the new one. If all files are
333     * moved succesfully, the old directory is deleted.
334     * @param path The location of the new JSampler's home directory. If
335     * the last directory in the path doesn't exist, it is created.
336     */
337     public static void
338     changeJSamplerHome(String path) {
339     File fNew = new File(path);
340 iliev 1285 if(fNew.exists() && fNew.isFile()) {
341 iliev 1143 HF.showErrorMessage(i18n.getError("CC.JSamplerHomeIsNotDir!"));
342     return;
343     }
344    
345 iliev 1285 if(!fNew.exists()) {
346 iliev 1143 if(!fNew.mkdir()) {
347     String s = fNew.getAbsolutePath();
348     HF.showErrorMessage(i18n.getError("CC.mkdirFailed", s));
349     return;
350     }
351     }
352    
353 iliev 1285 if(getJSamplerHome() == null || path.equals(getJSamplerHome())) {
354 iliev 1143 setJSamplerHome(fNew.getAbsolutePath());
355     return;
356     }
357    
358     File fOld = new File(getJSamplerHome());
359 iliev 1285 if(!fOld.exists() || !fOld.isDirectory()) {
360 iliev 1143 setJSamplerHome(fNew.getAbsolutePath());
361     return;
362     }
363    
364     File[] files = fOld.listFiles();
365     boolean b = true;
366     if(files != null) {
367     String s = fNew.getAbsolutePath() + File.separator;
368     for(File f : files) if(!f.renameTo(new File(s + f.getName()))) b = false;
369     }
370    
371     if(b) fOld.delete();
372     setJSamplerHome(fNew.getAbsolutePath());
373     }
374    
375 iliev 911 private final static OrchestraListModel orchestras = new DefaultOrchestraListModel();
376    
377     /**
378     * Returns a list containing all available orchestras.
379     * @return A list containing all available orchestras.
380     */
381     public static OrchestraListModel
382     getOrchestras() { return orchestras; }
383    
384 iliev 1688 private final static ServerList servers = new ServerList();
385    
386     /** Returns the server list. */
387     public static ServerList
388     getServerList() { return servers; }
389    
390     private static ServerListListener serverListListener = new ServerListListener();
391    
392     private static class ServerListListener implements ChangeListener {
393     public void
394     stateChanged(ChangeEvent e) {
395     saveServerList();
396     }
397     }
398    
399     private static final Vector<ChangeListener> idtmListeners = new Vector<ChangeListener>();
400 iliev 1204 private static InstrumentsDbTreeModel instrumentsDbTreeModel = null;
401 iliev 1688
402 iliev 1143 /**
403 iliev 1204 * Gets the tree model of the instruments database.
404     * If the currently used view doesn't have instruments
405     * database support the tree model is initialized on first use.
406     * @return The tree model of the instruments database or
407     * <code>null</code> if the backend doesn't have instruments database support.
408 iliev 1327 * @see org.jsampler.view.JSViewConfig#getInstrumentsDbSupport
409 iliev 1204 */
410     public static InstrumentsDbTreeModel
411     getInstrumentsDbTreeModel() {
412 iliev 1767 if(getSamplerModel().getServerInfo() == null) return null;
413     if(!getSamplerModel().getServerInfo().hasInstrumentsDbSupport()) return null;
414 iliev 1204
415     if(instrumentsDbTreeModel == null) {
416     instrumentsDbTreeModel = new InstrumentsDbTreeModel();
417 iliev 1688 for(ChangeListener l : idtmListeners) l.stateChanged(null);
418 iliev 1204 }
419    
420     return instrumentsDbTreeModel;
421     }
422    
423 iliev 1688 public static void
424     addInstrumentsDbChangeListener(ChangeListener l) {
425     idtmListeners.add(l);
426     }
427    
428     public static void
429     removeInstrumentsDbChangeListener(ChangeListener l) {
430     idtmListeners.remove(l);
431     }
432    
433 iliev 1729 private static final LostFilesModel lostFilesModel = new LostFilesModel();
434    
435     public static LostFilesModel
436     getLostFilesModel() { return lostFilesModel; }
437    
438 iliev 1204 /**
439 iliev 1143 * Loads the orchestras described in <code>&lt;jsampler_home&gt;/orchestras.xml</code>.
440     * If file with name <code>orchestras.xml.bkp</code> exist in the JSampler's home
441     * directory, this means that the last save has failed. In that case a recovery file
442     * <code>orchestras.xml.rec</code> is created and a recovery procedure
443     * will be initiated.
444     */
445     public static void
446     loadOrchestras() {
447     if(getJSamplerHome() == null) return;
448    
449     try {
450     String s = getJSamplerHome();
451    
452     File f = new File(s + File.separator + "orchestras.xml.bkp");
453     if(f.isFile()) HF.createBackup("orchestras.xml.bkp", "orchestras.xml.rec");
454    
455     FileInputStream fis;
456     fis = new FileInputStream(s + File.separator + "orchestras.xml");
457    
458     loadOrchestras(fis);
459     fis.close();
460     } catch(Exception x) {
461     getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
462     }
463 iliev 1688
464     getOrchestras().addOrchestraListListener(getHandler());
465 iliev 1143 }
466    
467    
468 iliev 911 private static void
469 iliev 1143 loadOrchestras(InputStream in) {
470     Document doc = DOMUtils.readObject(in);
471    
472     try { getOrchestras().readObject(doc.getDocumentElement()); }
473     catch(Exception x) {
474     HF.showErrorMessage(x, "Loading orchestras: ");
475     return;
476     }
477    
478     for(int i = 0; i < getOrchestras().getOrchestraCount(); i++) {
479     getOrchestras().getOrchestra(i).addOrchestraListener(getHandler());
480     }
481     }
482    
483     private static void
484 iliev 911 saveOrchestras() {
485 iliev 1143 try {
486     String s = getJSamplerHome();
487     if(s == null) return;
488    
489     HF.createBackup("orchestras.xml", "orchestras.xml.bkp");
490    
491     FileOutputStream fos;
492     fos = new FileOutputStream(s + File.separator + "orchestras.xml", false);
493    
494     Document doc = DOMUtils.createEmptyDocument();
495 iliev 911
496 iliev 1143 Node node = doc.createElement("temp");
497     doc.appendChild(node);
498    
499     getOrchestras().writeObject(doc, doc.getDocumentElement());
500    
501     doc.replaceChild(node.getFirstChild(), node);
502 iliev 911
503 iliev 1143 DOMUtils.writeObject(doc, fos);
504    
505     fos.close();
506    
507     HF.deleteFile("orchestras.xml.bkp");
508     } catch(Exception x) {
509     HF.showErrorMessage(x, "Saving orchestras: ");
510     return;
511     }
512 iliev 911 }
513    
514     /**
515 iliev 1688 * Loads the servers' info described in <code>&lt;jsampler_home&gt;/servers.xml</code>.
516     * If file with name <code>servers.xml.bkp</code> exist in the JSampler's home
517     * directory, this means that the last save has failed. In that case a recovery file
518     * <code>servers.xml.rec</code> is created and a recovery procedure
519     * will be initiated.
520     */
521     public static void
522     loadServerList() {
523     if(getJSamplerHome() == null) return;
524    
525     try {
526     String s = getJSamplerHome();
527    
528     File f = new File(s + File.separator + "servers.xml.bkp");
529     if(f.isFile()) HF.createBackup("servers.xml.bkp", "servers.xml.rec");
530    
531     FileInputStream fis;
532     fis = new FileInputStream(s + File.separator + "servers.xml");
533    
534     loadServerList(fis);
535     fis.close();
536     } catch(Exception x) {
537     getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
538     }
539    
540     getServerList().addChangeListener(serverListListener);
541    
542     /* We should have at least one server to connect. */
543     if(getServerList().getServerCount() == 0) {
544     Server server = new Server();
545     server.setName("127.0.0.1:8888");
546     server.setAddress("127.0.0.1");
547     server.setPort(8888);
548     getServerList().addServer(server);
549     }
550     }
551    
552    
553     private static void
554     loadServerList(InputStream in) {
555     Document doc = DOMUtils.readObject(in);
556    
557     try { getServerList().readObject(doc.getDocumentElement()); }
558     catch(Exception x) {
559     HF.showErrorMessage(x, "Loading server list: ");
560     return;
561     }
562     }
563    
564     private static void
565     saveServerList() {
566     try {
567     String s = getJSamplerHome();
568     if(s == null) return;
569    
570     HF.createBackup("servers.xml", "servers.xml.bkp");
571    
572     FileOutputStream fos;
573     fos = new FileOutputStream(s + File.separator + "servers.xml", false);
574    
575     Document doc = DOMUtils.createEmptyDocument();
576    
577     Node node = doc.createElement("temp");
578     doc.appendChild(node);
579    
580     getServerList().writeObject(doc, doc.getDocumentElement());
581    
582     doc.replaceChild(node.getFirstChild(), node);
583    
584     DOMUtils.writeObject(doc, fos);
585    
586     fos.close();
587    
588     HF.deleteFile("servers.xml.bkp");
589     } catch(Exception x) {
590     HF.showErrorMessage(x, "Saving server list: ");
591     return;
592     }
593     }
594    
595     /**
596 iliev 911 * The exit point of the application which ensures clean exit with default exit status 0.
597     * @see #cleanExit(int i)
598     */
599 iliev 787 public static void
600     cleanExit() { cleanExit(0); }
601    
602 iliev 911 /**
603     * The exit point of the application which ensures clean exit.
604     * @param i The exit status.
605     */
606 iliev 787 public static void
607     cleanExit(int i) {
608 iliev 1767 getLogger().fine("CC.jsEnded");
609 iliev 787 System.exit(i);
610     }
611    
612 iliev 911 /**
613     * Gets the <code>Client</code> object that is used to communicate with the backend.
614     * @return The <code>Client</code> object that is used to communicate with the backend.
615     */
616 iliev 787 public static Client
617     getClient() { return lsClient; }
618    
619 iliev 911 private static final Vector<ActionListener> listeners = new Vector<ActionListener>();
620 iliev 787
621 iliev 911 /**
622     * Registers the specified listener to be notified when reconnecting to LinuxSampler.
623     * @param l The <code>ActionListener</code> to register.
624     */
625     public static void
626     addReconnectListener(ActionListener l) { listeners.add(l); }
627    
628     /**
629     * Removes the specified listener.
630     * @param l The <code>ActionListener</code> to remove.
631     */
632     public static void
633     removeReconnectListener(ActionListener l) { listeners.remove(l); }
634    
635     private static void
636     fireReconnectEvent() {
637     ActionEvent e = new ActionEvent(CC.class, ActionEvent.ACTION_PERFORMED, null);
638     for(ActionListener l : listeners) l.actionPerformed(e);
639     }
640    
641 iliev 787 private static final SamplerModel samplerModel = new DefaultSamplerModel();
642    
643     /**
644     * Gets the sampler model.
645     * @return The sampler model.
646     */
647     public static SamplerModel
648     getSamplerModel() { return samplerModel; }
649    
650 iliev 911 /**
651 iliev 1688 * Connects to LinuxSampler.
652     */
653     public static void
654     connect() { initSamplerModel(); }
655    
656     /**
657 iliev 911 * Reconnects to LinuxSampler.
658     */
659 iliev 787 public static void
660 iliev 1688 reconnect() { initSamplerModel(getCurrentServer()); }
661    
662     private static Server currentServer = null;
663    
664     /**
665     * Gets the server, to which the frontend is going to connect
666     * or is already connected.
667     */
668     public static Server
669     getCurrentServer() { return currentServer; }
670    
671     /**
672     * Sets the current server.
673     */
674     public static void
675     setCurrentServer(Server server) { currentServer = server; }
676    
677     /**
678 iliev 1767 * Sets the LSCP client's read timeout.
679     * @param timeout The new timeout value (in seconds).
680     */
681     public static void
682     setClientReadTimeout(int timeout) {
683     getTaskQueue().add(new Global.SetClientReadTimeout(timeout));
684     }
685    
686     /**
687 iliev 1688 * This method updates the information about the backend state.
688     */
689     private static void
690     initSamplerModel() {
691     Server srv = getMainFrame().getServer();
692     if(srv == null) return;
693     initSamplerModel(srv);
694 iliev 911 }
695    
696     /**
697     * This method updates the information about the backend state.
698     */
699 iliev 1688 private static void
700     initSamplerModel(Server srv) {
701     setCurrentServer(srv);
702     final SetServerAddress ssa = new SetServerAddress(srv.getAddress(), srv.getPort());
703    
704 iliev 787 final DefaultSamplerModel model = (DefaultSamplerModel)getSamplerModel();
705    
706 iliev 1204 final Global.GetServerInfo gsi = new Global.GetServerInfo();
707 iliev 787 gsi.addTaskListener(new TaskListener() {
708     public void
709     taskPerformed(TaskEvent e) {
710 iliev 1204 if(gsi.doneWithErrors()) return;
711    
712     model.setServerInfo(gsi.getResult());
713    
714 iliev 1285 if(CC.getViewConfig().getInstrumentsDbSupport()) {
715 iliev 1204 getInstrumentsDbTreeModel();
716     }
717 iliev 787 }
718     });
719    
720 iliev 1143 final Audio.GetDrivers gaod = new Audio.GetDrivers();
721 iliev 787 gaod.addTaskListener(new TaskListener() {
722     public void
723     taskPerformed(TaskEvent e) {
724     if(!gaod.doneWithErrors())
725     model.setAudioOutputDrivers(gaod.getResult());
726     }
727     });
728    
729     final GetEngines ge = new GetEngines();
730     ge.addTaskListener(new TaskListener() {
731     public void
732     taskPerformed(TaskEvent e) {
733     if(!ge.doneWithErrors()) model.setEngines(ge.getResult());
734     }
735     });
736    
737 iliev 1143 final Midi.GetDrivers gmid = new Midi.GetDrivers();
738 iliev 787 gmid.addTaskListener(new TaskListener() {
739     public void
740     taskPerformed(TaskEvent e) {
741     if(!gmid.doneWithErrors())
742     model.setMidiInputDrivers(gmid.getResult());
743     }
744     });
745    
746 iliev 1143 final Global.GetVolume gv = new Global.GetVolume();
747     gv.addTaskListener(new TaskListener() {
748     public void
749     taskPerformed(TaskEvent e) {
750     if(!gv.doneWithErrors())
751     model.setVolume(gv.getResult());
752     }
753     });
754    
755     final Midi.GetInstrumentMaps mgim = new Midi.GetInstrumentMaps();
756     mgim.addTaskListener(new TaskListener() {
757     public void
758     taskPerformed(TaskEvent e) {
759     if(mgim.doneWithErrors()) return;
760     model.removeAllMidiInstrumentMaps();
761    
762     for(MidiInstrumentMap map : mgim.getResult()) {
763     model.addMidiInstrumentMap(map);
764     }
765     }
766     });
767    
768     final UpdateChannels uc = new UpdateChannels();
769     uc.addTaskListener(new TaskListener() {
770     public void
771     taskPerformed(TaskEvent e) {
772 iliev 1204 for(SamplerChannelModel c : model.getChannels()) {
773 iliev 1143 if(c.getChannelInfo().getEngine() == null) continue;
774    
775     Channel.GetFxSends gfs = new Channel.GetFxSends();
776     gfs.setChannel(c.getChannelId());
777     gfs.addTaskListener(new GetFxSendsListener());
778     getTaskQueue().add(gfs);
779     }
780 iliev 1567
781     // TODO: This should be done after the fx sends are set
782     //CC.getSamplerModel().setModified(false);
783 iliev 1143 }
784     });
785    
786    
787 iliev 787 final Connect cnt = new Connect();
788     cnt.addTaskListener(new TaskListener() {
789     public void
790     taskPerformed(TaskEvent e) {
791 iliev 1688 if(cnt.doneWithErrors()) {
792     setCurrentServer(null);
793     retryToConnect();
794     return;
795     }
796 iliev 787
797     getTaskQueue().add(gsi);
798     getTaskQueue().add(gaod);
799     getTaskQueue().add(gmid);
800     getTaskQueue().add(ge);
801 iliev 1143 getTaskQueue().add(gv);
802     getTaskQueue().add(mgim);
803     getTaskQueue().add(new Midi.UpdateDevices());
804     getTaskQueue().add(new Audio.UpdateDevices());
805 iliev 1734 addTask(uc);
806 iliev 787 }
807     });
808 iliev 1688
809     ssa.addTaskListener(new TaskListener() {
810     public void
811     taskPerformed(TaskEvent e) {
812 iliev 1767 int t = preferences().getIntProperty(JSPrefs.SOCKET_READ_TIMEOUT);
813     CC.setClientReadTimeout(t * 1000);
814 iliev 1688 CC.getTaskQueue().add(cnt);
815     }
816     });
817    
818     getSamplerModel().reset();
819     if(instrumentsDbTreeModel != null) {
820     instrumentsDbTreeModel.reset();
821     instrumentsDbTreeModel = null;
822     }
823    
824     getTaskQueue().removePendingTasks();
825     getTaskQueue().add(ssa);
826    
827     fireReconnectEvent();
828 iliev 787 }
829    
830 iliev 1688 private static void
831     retryToConnect() {
832     javax.swing.SwingUtilities.invokeLater(new Runnable() {
833     public void
834     run() { changeBackend(); }
835     });
836     }
837    
838     public static void
839     changeBackend() {
840     Server s = getMainFrame().getServer(true);
841     if(s != null) initSamplerModel(s);
842     }
843    
844 iliev 1143 private static class GetFxSendsListener implements TaskListener {
845     public void
846     taskPerformed(TaskEvent e) {
847     Channel.GetFxSends gfs = (Channel.GetFxSends)e.getSource();
848     if(gfs.doneWithErrors()) return;
849 iliev 1204 SamplerChannelModel m = getSamplerModel().getChannelById(gfs.getChannel());
850 iliev 1143 m.removeAllFxSends();
851    
852     for(FxSend fxs : gfs.getResult()) m.addFxSend(fxs);
853     }
854     }
855    
856     public static String
857     exportInstrMapsToLscpScript() {
858     StringBuffer sb = new StringBuffer("# Exported by: ");
859     sb.append("JSampler - a java front-end for LinuxSampler\r\n# Version: ");
860     sb.append(JSampler.VERSION).append("\r\n");
861     sb.append("# Date: ").append(new java.util.Date().toString()).append("\r\n\r\n");
862    
863     Client lscpClient = new Client(true);
864     ByteArrayOutputStream out = new ByteArrayOutputStream();
865     lscpClient.setPrintOnlyModeOutputStream(out);
866    
867     exportInstrMapsToLscpScript(lscpClient);
868     sb.append(out.toString());
869     out.reset();
870    
871     return sb.toString();
872     }
873    
874     private static void
875     exportInstrMapsToLscpScript(Client lscpClient) {
876     try {
877     lscpClient.removeAllMidiInstrumentMaps();
878 iliev 1767 MidiInstrumentMap[] maps = getSamplerModel().getMidiInstrumentMaps();
879 iliev 1143 for(int i = 0; i < maps.length; i++) {
880     lscpClient.addMidiInstrumentMap(maps[i].getName());
881     exportInstrumentsToLscpScript(i, maps[i], lscpClient);
882     }
883     } catch(Exception e) {
884 iliev 1767 getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
885 iliev 1143 HF.showErrorMessage(e);
886     }
887     }
888    
889     private static void
890     exportInstrumentsToLscpScript(int mapId, MidiInstrumentMap map, Client lscpClient)
891     throws Exception {
892    
893 iliev 1767 boolean b = preferences().getBoolProperty(JSPrefs.LOAD_MIDI_INSTRUMENTS_IN_BACKGROUND);
894    
895 iliev 1143 for(MidiInstrument i : map.getAllMidiInstruments()) {
896 iliev 1767 lscpClient.mapMidiInstrument(mapId, i.getInfo().getEntry(), i.getInfo(), b);
897 iliev 1143 }
898     }
899    
900     public static String
901     exportSessionToLscpScript() {
902 iliev 1767 getSamplerModel().setModified(false);
903 iliev 1567
904 iliev 1143 StringBuffer sb = new StringBuffer("# Exported by: ");
905     sb.append("JSampler - a java front-end for LinuxSampler\r\n# Version: ");
906     sb.append(JSampler.VERSION).append("\r\n");
907     sb.append("# Date: ").append(new java.util.Date().toString()).append("\r\n\r\n");
908    
909     Client lscpClient = new Client(true);
910     ByteArrayOutputStream out = new ByteArrayOutputStream();
911     lscpClient.setPrintOnlyModeOutputStream(out);
912    
913     try {
914     lscpClient.resetSampler();
915     sb.append(out.toString());
916     out.reset();
917     sb.append("\r\n");
918 iliev 1767 lscpClient.setVolume(getSamplerModel().getVolume());
919 iliev 1143 sb.append(out.toString());
920     out.reset();
921     sb.append("\r\n");
922 iliev 1767 } catch(Exception e) { getLogger().log(Level.FINE, HF.getErrorMessage(e), e); }
923 iliev 1143
924 iliev 1204 MidiDeviceModel[] mDevs = getSamplerModel().getMidiDevices();
925 iliev 1143 for(int i = 0; i < mDevs.length; i++) {
926     exportMidiDeviceToLscpScript(mDevs[i].getDeviceInfo(), i, lscpClient);
927     sb.append(out.toString());
928     out.reset();
929     sb.append("\r\n");
930     }
931    
932 iliev 1204 AudioDeviceModel[] aDevs = getSamplerModel().getAudioDevices();
933 iliev 1143 for(int i = 0; i < aDevs.length; i++) {
934     exportAudioDeviceToLscpScript(aDevs[i].getDeviceInfo(), i, lscpClient);
935     sb.append(out.toString());
936     out.reset();
937     sb.append("\r\n");
938     }
939    
940 iliev 1767 boolean b = preferences().getBoolProperty(JSPrefs.EXPORT_MIDI_MAPS_TO_SESSION_SCRIPT);
941     if(b) {
942     exportInstrMapsToLscpScript(lscpClient);
943     sb.append(out.toString());
944     out.reset();
945     sb.append("\r\n");
946     }
947 iliev 1708
948 iliev 1204 SamplerChannelModel[] channels = getSamplerModel().getChannels();
949 iliev 1143
950     for(int i = 0; i < channels.length; i++) {
951 iliev 1467 SamplerChannelModel scm = channels[i];
952 iliev 1143 exportChannelToLscpScript(scm.getChannelInfo(), i, lscpClient);
953     sb.append(out.toString());
954     out.reset();
955    
956     sb.append("\r\n");
957    
958     exportFxSendsToLscpScript(scm, i, lscpClient);
959     sb.append(out.toString());
960     out.reset();
961    
962     sb.append("\r\n");
963     }
964    
965 iliev 1767 //sb.append(getViewConfig().exportSessionViewConfig());
966    
967 iliev 1143 return sb.toString();
968     }
969    
970     private static void
971     exportMidiDeviceToLscpScript(MidiInputDevice mid, int devId, Client lscpCLient) {
972     try {
973     String s = mid.getDriverName();
974     lscpCLient.createMidiInputDevice(s, mid.getAdditionalParameters());
975    
976     MidiPort[] mPorts = mid.getMidiPorts();
977     int l = mPorts.length;
978     if(l != 1) lscpCLient.setMidiInputPortCount(devId, l);
979    
980     for(int i = 0; i < l; i++) {
981     Parameter[] prms = mPorts[i].getAllParameters();
982     for(Parameter p : prms) {
983     if(!p.isFixed() && p.getStringValue().length() > 0)
984     lscpCLient.setMidiInputPortParameter(devId, i, p);
985     }
986     }
987     } catch(Exception e) {
988 iliev 1767 getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
989 iliev 1143 }
990     }
991    
992     private static void
993     exportAudioDeviceToLscpScript(AudioOutputDevice aod, int devId, Client lscpCLient) {
994     try {
995     String s = aod.getDriverName();
996     lscpCLient.createAudioOutputDevice(s, aod.getAllParameters());
997    
998     AudioOutputChannel[] chns = aod.getAudioChannels();
999    
1000     for(int i = 0; i < chns.length; i++) {
1001     Parameter[] prms = chns[i].getAllParameters();
1002     for(Parameter p : prms) {
1003     if(p.isFixed() || p.getStringValue().length() == 0);
1004     else lscpCLient.setAudioOutputChannelParameter(devId, i, p);
1005     }
1006     }
1007     } catch(Exception e) {
1008 iliev 1767 getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
1009 iliev 1143 }
1010     }
1011    
1012     private static void
1013     exportChannelToLscpScript(SamplerChannel chn, int chnId, Client lscpCLient) {
1014     try {
1015     lscpCLient.addSamplerChannel();
1016    
1017 iliev 1767 SamplerModel sm = getSamplerModel();
1018 iliev 1467 int id = chn.getMidiInputDevice();
1019     if(id != -1) {
1020     for(int i = 0; i < sm.getMidiDeviceCount(); i++) {
1021     if(sm.getMidiDevice(i).getDeviceId() == id) {
1022     lscpCLient.setChannelMidiInputDevice(chnId, i);
1023     break;
1024     }
1025     }
1026 iliev 1540 lscpCLient.setChannelMidiInputPort(chnId, chn.getMidiInputPort());
1027     lscpCLient.setChannelMidiInputChannel(chnId, chn.getMidiInputChannel());
1028 iliev 1467 }
1029 iliev 1143
1030 iliev 1670 if(chn.getEngine() != null) {
1031     lscpCLient.loadSamplerEngine(chn.getEngine().getName(), chnId);
1032     lscpCLient.setChannelVolume(chnId, chn.getVolume());
1033 iliev 1708 int mapId = chn.getMidiInstrumentMapId();
1034     lscpCLient.setChannelMidiInstrumentMap(chnId, mapId);
1035 iliev 1670 }
1036    
1037 iliev 1467 id = chn.getAudioOutputDevice();
1038     if(id != -1) {
1039     for(int i = 0; i < sm.getAudioDeviceCount(); i++) {
1040     if(sm.getAudioDevice(i).getDeviceId() == id) {
1041     lscpCLient.setChannelAudioOutputDevice(chnId, i);
1042     break;
1043     }
1044     }
1045    
1046 iliev 1143 Integer[] routing = chn.getAudioOutputRouting();
1047    
1048     for(int j = 0; j < routing.length; j++) {
1049     int k = routing[j];
1050     if(k == j) continue;
1051    
1052     lscpCLient.setChannelAudioOutputChannel(chnId, j, k);
1053     }
1054     }
1055    
1056     String s = chn.getInstrumentFile();
1057 iliev 1467 int i = chn.getInstrumentIndex();
1058 iliev 1143 if(s != null) lscpCLient.loadInstrument(s, i, chnId, true);
1059    
1060     if(chn.isMuted()) lscpCLient.setChannelMute(chnId, true);
1061     if(chn.isSoloChannel()) lscpCLient.setChannelSolo(chnId, true);
1062     } catch(Exception e) {
1063 iliev 1767 getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
1064 iliev 1143 }
1065     }
1066    
1067     private static void
1068     exportFxSendsToLscpScript(SamplerChannelModel scm, int chnId, Client lscpClient) {
1069     try {
1070     FxSend[] fxSends = scm.getFxSends();
1071    
1072     for(int i = 0; i < fxSends.length; i++) {
1073     FxSend f = fxSends[i];
1074     lscpClient.createFxSend(chnId, f.getMidiController(), f.getName());
1075    
1076     Integer[] r = f.getAudioOutputRouting();
1077     for(int j = 0; j < r.length; j++) {
1078     lscpClient.setFxSendAudioOutputChannel(chnId, i, j, r[j]);
1079     }
1080     }
1081     } catch(Exception e) {
1082 iliev 1767 getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
1083 iliev 1143 }
1084     }
1085    
1086 iliev 1688 public static void
1087     scheduleInTaskQueue(final Runnable r) {
1088     Task dummy = new Global.DummyTask();
1089     dummy.addTaskListener(new TaskListener() {
1090     public void
1091     taskPerformed(TaskEvent e) {
1092     javax.swing.SwingUtilities.invokeLater(r);
1093     }
1094     });
1095    
1096 iliev 1767 getTaskQueue().add(dummy);
1097 iliev 1688 }
1098 iliev 1143
1099 iliev 1688 public static boolean
1100     verifyConnection() {
1101     if(getCurrentServer() == null) {
1102     HF.showErrorMessage(i18n.getError("CC.notConnected"));
1103     return false;
1104     }
1105    
1106     return true;
1107     }
1108    
1109    
1110 iliev 911 private final static EventHandler eventHandler = new EventHandler();
1111    
1112     private static EventHandler
1113     getHandler() { return eventHandler; }
1114    
1115 iliev 787 private static class EventHandler implements ChannelCountListener, ChannelInfoListener,
1116 iliev 1143 FxSendCountListener, FxSendInfoListener, StreamCountListener, VoiceCountListener,
1117 iliev 1545 TotalStreamCountListener, TotalVoiceCountListener, TaskQueueListener,
1118     OrchestraListener, ListListener<OrchestraModel>, MidiInstrumentCountListener,
1119 iliev 1143 MidiInstrumentInfoListener, GlobalInfoListener {
1120 iliev 787
1121     /** Invoked when the number of channels has changed. */
1122     public void
1123     channelCountChanged( ChannelCountEvent e) {
1124 iliev 1734 addTask(new UpdateChannels());
1125 iliev 787 }
1126    
1127     /** Invoked when changes to the sampler channel has occured. */
1128     public void
1129     channelInfoChanged(ChannelInfoEvent e) {
1130     /*
1131     * Because of the rapid notification flow when instrument is loaded
1132     * we need to do some optimization to decrease the traffic.
1133     */
1134     boolean b = true;
1135     Task[] tS = getTaskQueue().getPendingTasks();
1136    
1137     for(int i = tS.length - 1; i >= 0; i--) {
1138     Task t = tS[i];
1139    
1140 iliev 1143 if(t instanceof Channel.UpdateInfo) {
1141     Channel.UpdateInfo cui = (Channel.UpdateInfo)t;
1142     if(cui.getChannelId() == e.getSamplerChannel()) return;
1143 iliev 787 } else {
1144     b = false;
1145     break;
1146     }
1147     }
1148    
1149     if(b) {
1150     Task t = getTaskQueue().getRunningTask();
1151 iliev 1143 if(t instanceof Channel.UpdateInfo) {
1152     Channel.UpdateInfo cui = (Channel.UpdateInfo)t;
1153     if(cui.getChannelId() == e.getSamplerChannel()) return;
1154 iliev 787 }
1155     }
1156    
1157    
1158 iliev 1143 getTaskQueue().add(new Channel.UpdateInfo(e.getSamplerChannel()));
1159 iliev 787 }
1160    
1161     /**
1162 iliev 1143 * Invoked when the number of effect sends
1163     * on a particular sampler channel has changed.
1164     */
1165     public void
1166     fxSendCountChanged(FxSendCountEvent e) {
1167     getTaskQueue().add(new Channel.UpdateFxSends(e.getChannel()));
1168     }
1169    
1170     /**
1171     * Invoked when the settings of an effect sends are changed.
1172     */
1173     public void
1174     fxSendInfoChanged(FxSendInfoEvent e) {
1175     Task t = new Channel.UpdateFxSendInfo(e.getChannel(), e.getFxSend());
1176     getTaskQueue().add(t);
1177     }
1178    
1179     /**
1180 iliev 787 * Invoked when the number of active disk
1181     * streams in a specific sampler channel has changed.
1182     */
1183     public void
1184     streamCountChanged(StreamCountEvent e) {
1185     SamplerChannelModel scm =
1186 iliev 1204 getSamplerModel().getChannelById(e.getSamplerChannel());
1187 iliev 787
1188     if(scm == null) {
1189     CC.getLogger().log (
1190     Level.WARNING,
1191     "CC.unknownChannel!",
1192     e.getSamplerChannel()
1193     );
1194    
1195     return;
1196     }
1197    
1198     scm.setStreamCount(e.getStreamCount());
1199     }
1200    
1201     /**
1202     * Invoked when the number of active voices
1203     * in a specific sampler channel has changed.
1204     */
1205     public void
1206     voiceCountChanged(VoiceCountEvent e) {
1207     SamplerChannelModel scm =
1208 iliev 1204 getSamplerModel().getChannelById(e.getSamplerChannel());
1209 iliev 787
1210     if(scm == null) {
1211     CC.getLogger().log (
1212     Level.WARNING,
1213     "CC.unknownChannel!",
1214     e.getSamplerChannel()
1215     );
1216    
1217     return;
1218     }
1219    
1220     scm.setVoiceCount(e.getVoiceCount());
1221     }
1222    
1223 iliev 1545 /** Invoked when the total number of active streams has changed. */
1224     public void
1225     totalStreamCountChanged(TotalStreamCountEvent e) {
1226     getSamplerModel().updateActiveStreamsInfo(e.getTotalStreamCount());
1227     }
1228    
1229 iliev 787 /** Invoked when the total number of active voices has changed. */
1230     public void
1231     totalVoiceCountChanged(TotalVoiceCountEvent e) {
1232     getTaskQueue().add(new UpdateTotalVoiceCount());
1233     }
1234 iliev 911
1235 iliev 1143 /** Invoked when the number of MIDI instruments in a MIDI instrument map is changed. */
1236     public void
1237     instrumentCountChanged(MidiInstrumentCountEvent e) {
1238 iliev 1719 scheduleTask(new Midi.UpdateInstruments(e.getMapId()));
1239 iliev 1143 }
1240    
1241     /** Invoked when a MIDI instrument in a MIDI instrument map is changed. */
1242     public void
1243     instrumentInfoChanged(MidiInstrumentInfoEvent e) {
1244     Task t = new Midi.UpdateInstrumentInfo (
1245     e.getMapId(), e.getMidiBank(), e.getMidiProgram()
1246     );
1247     getTaskQueue().add(t);
1248    
1249     }
1250    
1251     /** Invoked when the global volume of the sampler is changed. */
1252     public void
1253     volumeChanged(GlobalInfoEvent e) {
1254     getSamplerModel().setVolume(e.getVolume());
1255     }
1256    
1257 iliev 911 /**
1258     * Invoked to indicate that the state of a task queue is changed.
1259     * This method is invoked only from the event-dispatching thread.
1260     */
1261     public void
1262     stateChanged(TaskQueueEvent e) {
1263     switch(e.getEventID()) {
1264     case TASK_FETCHED:
1265     getProgressIndicator().setString (
1266     ((Task)e.getSource()).getDescription()
1267     );
1268     break;
1269     case TASK_DONE:
1270     EnhancedTask t = (EnhancedTask)e.getSource();
1271 iliev 1204 if(t.doneWithErrors() && !t.isStopped()) {
1272 iliev 1285 showError(t);
1273 iliev 1204 }
1274 iliev 911 break;
1275     case NOT_IDLE:
1276     timer.start();
1277     break;
1278     case IDLE:
1279     timer.stop();
1280     getProgressIndicator().stop();
1281     break;
1282     }
1283     }
1284    
1285 iliev 1285 private void
1286     showError(final Task t) {
1287     javax.swing.SwingUtilities.invokeLater(new Runnable() {
1288     public void
1289     run() {
1290     if(t.getErrorDetails() == null) {
1291     HF.showErrorMessage(t.getErrorMessage());
1292     } else {
1293     getMainFrame().showDetailedErrorMessage (
1294     getMainFrame(),
1295     t.getErrorMessage(),
1296     t.getErrorDetails()
1297     );
1298     }
1299     }
1300     });
1301     }
1302    
1303 iliev 911 /** Invoked when the name of orchestra is changed. */
1304     public void
1305     nameChanged(OrchestraEvent e) { saveOrchestras(); }
1306    
1307     /** Invoked when the description of orchestra is changed. */
1308     public void
1309     descriptionChanged(OrchestraEvent e) { saveOrchestras(); }
1310    
1311     /** Invoked when an instrument is added to the orchestra. */
1312     public void
1313     instrumentAdded(OrchestraEvent e) { saveOrchestras(); }
1314    
1315     /** Invoked when an instrument is removed from the orchestra. */
1316     public void
1317     instrumentRemoved(OrchestraEvent e) { saveOrchestras(); }
1318    
1319     /** Invoked when the settings of an instrument are changed. */
1320     public void
1321     instrumentChanged(OrchestraEvent e) { saveOrchestras(); }
1322    
1323     /** Invoked when an orchestra is added to the orchestra list. */
1324     public void
1325 iliev 1143 entryAdded(ListEvent<OrchestraModel> e) {
1326     e.getEntry().addOrchestraListener(getHandler());
1327 iliev 911 saveOrchestras();
1328     }
1329    
1330     /** Invoked when an orchestra is removed from the orchestra list. */
1331     public void
1332 iliev 1143 entryRemoved(ListEvent<OrchestraModel> e) {
1333     e.getEntry().removeOrchestraListener(getHandler());
1334 iliev 911 saveOrchestras();
1335     }
1336 iliev 787 }
1337 iliev 1143
1338     private static final AudioDeviceCountListener audioDeviceCountListener =
1339     new AudioDeviceCountListener();
1340    
1341     private static class AudioDeviceCountListener implements ItemCountListener {
1342     /** Invoked when the number of audio output devices has changed. */
1343     public void
1344     itemCountChanged(ItemCountEvent e) {
1345     getTaskQueue().add(new Audio.UpdateDevices());
1346     }
1347     }
1348    
1349     private static final AudioDeviceInfoListener audioDeviceInfoListener =
1350     new AudioDeviceInfoListener();
1351    
1352     private static class AudioDeviceInfoListener implements ItemInfoListener {
1353     /** Invoked when the audio output device's settings are changed. */
1354     public void
1355     itemInfoChanged(ItemInfoEvent e) {
1356     getTaskQueue().add(new Audio.UpdateDeviceInfo(e.getItemID()));
1357     }
1358     }
1359    
1360     private static final MidiDeviceCountListener midiDeviceCountListener =
1361     new MidiDeviceCountListener();
1362    
1363     private static class MidiDeviceCountListener implements ItemCountListener {
1364     /** Invoked when the number of MIDI input devices has changed. */
1365     public void
1366     itemCountChanged(ItemCountEvent e) {
1367     getTaskQueue().add(new Midi.UpdateDevices());
1368     }
1369     }
1370    
1371     private static final MidiDeviceInfoListener midiDeviceInfoListener =
1372     new MidiDeviceInfoListener();
1373    
1374     private static class MidiDeviceInfoListener implements ItemInfoListener {
1375     /** Invoked when the MIDI input device's settings are changed. */
1376     public void
1377     itemInfoChanged(ItemInfoEvent e) {
1378     getTaskQueue().add(new Midi.UpdateDeviceInfo(e.getItemID()));
1379     }
1380     }
1381    
1382     private static final MidiInstrMapCountListener midiInstrMapCountListener =
1383     new MidiInstrMapCountListener();
1384    
1385     private static class MidiInstrMapCountListener implements ItemCountListener {
1386     /** Invoked when the number of MIDI instrument maps is changed. */
1387     public void
1388     itemCountChanged(ItemCountEvent e) {
1389     getTaskQueue().add(new Midi.UpdateInstrumentMaps());
1390     }
1391     }
1392    
1393     private static final MidiInstrMapInfoListener midiInstrMapInfoListener =
1394     new MidiInstrMapInfoListener();
1395    
1396     private static class MidiInstrMapInfoListener implements ItemInfoListener {
1397     /** Invoked when the MIDI instrument map's settings are changed. */
1398     public void
1399     itemInfoChanged(ItemInfoEvent e) {
1400     getTaskQueue().add(new Midi.UpdateInstrumentMapInfo(e.getItemID()));
1401     }
1402     }
1403 iliev 787 }

  ViewVC Help
Powered by ViewVC