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

Annotation of /jsampler/trunk/src/org/jsampler/view/InstrumentsDbTreeModel.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1347 - (hide annotations) (download)
Thu Sep 13 22:20:38 2007 UTC (16 years, 7 months ago) by iliev
File size: 18020 byte(s)
* added support for escape sequences to the instruments database

1 iliev 1204 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4     * Copyright (C) 2005-2007 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;
24    
25     import java.awt.event.ActionEvent;
26     import java.awt.event.ActionListener;
27    
28     import java.util.Vector;
29    
30     import javax.swing.SwingUtilities;
31    
32     import javax.swing.event.TreeModelEvent;
33     import javax.swing.event.TreeModelListener;
34    
35     import javax.swing.tree.TreeModel;
36     import javax.swing.tree.TreePath;
37    
38     import net.sf.juife.event.TaskEvent;
39     import net.sf.juife.event.TaskListener;
40    
41     import org.jsampler.CC;
42    
43     import org.jsampler.task.InstrumentsDb;
44    
45     import org.linuxsampler.lscp.DbDirectoryInfo;
46     import org.linuxsampler.lscp.DbInstrumentInfo;
47    
48     import org.linuxsampler.lscp.event.InstrumentsDbEvent;
49     import org.linuxsampler.lscp.event.InstrumentsDbListener;
50    
51 iliev 1347 import static org.linuxsampler.lscp.Parser.*;
52    
53    
54 iliev 1204 /**
55     *
56     * @author Grigor Iliev
57     */
58     public class InstrumentsDbTreeModel implements TreeModel {
59     private DbDirectoryTreeNode root = null;
60     private Vector<TreeModelListener> listeners = new Vector<TreeModelListener>();
61    
62     /**
63     * Creates a new instance of <code>InstrumentsDbTreeModel</code>.
64     */
65     public
66     InstrumentsDbTreeModel() { this(null); }
67    
68     /**
69     * Creates a new instance of <code>InstrumentsDbTreeModel</code>.
70     * @param l A listener that will be notified when the root
71     * directory content is loaded.
72     */
73     public
74     InstrumentsDbTreeModel(final ActionListener l) {
75     final InstrumentsDb.GetDrectory gdi = new InstrumentsDb.GetDrectory("/");
76     final InstrumentsDb.GetDrectories gd = new InstrumentsDb.GetDrectories("/");
77     final InstrumentsDb.GetInstruments gi = new InstrumentsDb.GetInstruments("/");
78    
79     gdi.addTaskListener(new TaskListener() {
80     public void
81     taskPerformed(TaskEvent e) {
82     if(gdi.doneWithErrors()) return;
83     root = new DbDirectoryTreeNode(gdi.getResult());
84     fireNodeStructureChanged(root);
85    
86     // TODO: This shouldn't be done in the event-dispatcing thread
87     CC.getClient().addInstrumentsDbListener(getHandler());
88     ///////
89     CC.getTaskQueue().add(gd);
90     CC.getTaskQueue().add(gi);
91     }
92     });
93    
94     gd.addTaskListener(new TaskListener() {
95     public void
96     taskPerformed(TaskEvent e) {
97     root.setConnected(true);
98     if(gd.doneWithErrors()) return;
99     updateDirectoryContent(root, gd.getResult());
100    
101     for(int i = 0; i < root.getChildCount(); i++) {
102     DbDirectoryTreeNode node = root.getChildAt(i);
103     node.setConnected(true);
104 iliev 1347 updateDirectoryContent(node, "/" + toEscapedFileName(node));
105 iliev 1204 }
106    
107     if(l != null) l.actionPerformed(null);
108     }
109     });
110    
111     gi.addTaskListener(new TaskListener() {
112     public void
113     taskPerformed(TaskEvent e) {
114     if(gi.doneWithErrors()) return;
115     updateDirectoryContent(root, gi.getResult());
116     }
117     });
118    
119     CC.getTaskQueue().add(gdi);
120     }
121    
122     public void
123     treeWillExpand(TreePath path) {
124     DbDirectoryTreeNode node = (DbDirectoryTreeNode)path.getLastPathComponent();
125    
126     if(!node.isConnected()) {
127     node.setConnected(true);
128     updateDirectoryContent(node, node.getInfo().getDirectoryPath());
129     }
130    
131     for(int i = 0; i < node.getChildCount(); i++) {
132     DbDirectoryTreeNode child = node.getChildAt(i);
133     if(child.isConnected()) continue;
134     child.setConnected(true);
135     String pathName = getPathName(path.getPath());
136     if(pathName.length() > 1) pathName += "/";
137 iliev 1347 updateDirectoryContent(child, pathName + toEscapedFileName(child));
138 iliev 1204 }
139     }
140    
141     // Tree model methods
142     public void
143     addTreeModelListener(TreeModelListener l) {
144     listeners.add(l);
145     }
146    
147     public void
148     removeTreeModelListener(TreeModelListener l) {
149     listeners.remove(l);
150     }
151    
152     public Object
153     getChild(Object parent, int index) {
154     return ((DbDirectoryTreeNode)parent).getChildAt(index);
155     }
156    
157     public int
158     getChildCount(Object parent) {
159     return ((DbDirectoryTreeNode)parent).getChildCount();
160     }
161    
162     public Object
163     getRoot() { return root; }
164    
165     public int
166     getIndexOfChild(Object parent, Object child) {
167     if(parent == null || child == null) return -1;
168     return ((DbDirectoryTreeNode)parent).getIndex((DbDirectoryTreeNode)child);
169     }
170    
171     public boolean
172     isLeaf(Object node) { return ((DbDirectoryTreeNode)node).isLeaf(); }
173    
174     public void
175     valueForPathChanged(TreePath path, Object newValue) {
176    
177     }
178     ///////
179    
180     /**
181     * Schedules an update of the directory content for the specified directory node.
182     */
183     private void
184     updateDirectoryContent(final DbDirectoryTreeNode dirNode, String dirPath) {
185     updateDirectoryContent(dirNode, dirPath, null);
186     }
187    
188     /**
189     * Schedules an update of the directory content for the specified directory node.
190     * @param l A listener that will be notified when the subdirectory list is updated.
191     */
192     private void
193     updateDirectoryContent (
194     final DbDirectoryTreeNode dirNode, String dirPath, final ActionListener l
195     ) {
196     final InstrumentsDb.GetDrectories gd = new InstrumentsDb.GetDrectories(dirPath);
197    
198     gd.addTaskListener(new TaskListener() {
199     public void
200     taskPerformed(TaskEvent e) {
201     if(gd.doneWithErrors()) {
202     if(l != null) l.actionPerformed(null);
203     return;
204     }
205     updateDirectoryContent(dirNode, gd.getResult());
206     if(l != null) l.actionPerformed(null);
207     }
208     });
209     CC.scheduleTask(gd);
210    
211     final InstrumentsDb.GetInstruments gi = new InstrumentsDb.GetInstruments(dirPath);
212    
213     gi.addTaskListener(new TaskListener() {
214     public void
215     taskPerformed(TaskEvent e) {
216     if(gi.doneWithErrors()) return;
217     updateDirectoryContent(dirNode, gi.getResult());
218     }
219     });
220     CC.scheduleTask(gi);
221     }
222    
223     private void
224     updateDirectoryContent(DbDirectoryTreeNode parent, DbDirectoryInfo[] children) {
225     boolean found = false;
226     Vector<DbDirectoryTreeNode> removedNodes = new Vector<DbDirectoryTreeNode>();
227     for(int i = 0; i < parent.getChildCount(); i++) {
228     for(int j = 0; j < children.length; j++) {
229     if(children[j] == null) continue;
230     if(children[j].getName().equals(parent.getChildAt(i).toString())) {
231     children[j] = null;
232     found = true;
233     break;
234     }
235     }
236     if(!found) removedNodes.add(parent.getChildAt(i));
237     found = false;
238     }
239    
240     for(DbDirectoryTreeNode node : removedNodes) {
241     int i = parent.getIndex(node);
242     parent.removeDirectory(i);
243     fireNodeRemoved(parent, node, i);
244     }
245    
246     for(DbDirectoryInfo info : children) {
247     if(info == null) continue;
248     DbDirectoryTreeNode node = new DbDirectoryTreeNode(info);
249     parent.addDirectory(node);
250     fireNodeInserted(node, parent.getIndex(node));
251     if(parent.getParent() == null) {
252     node.setConnected(true);
253     updateDirectoryContent(node, info.getDirectoryPath());
254     } else if(parent.isConnected()) {
255     updateDirectoryContent(node, info.getDirectoryPath());
256     }
257     }
258     }
259    
260     private void
261     updateDirectoryContent(DbDirectoryTreeNode parent, DbInstrumentInfo[] children) {
262     boolean found = false;
263     Vector<DbInstrumentInfo> removedNodes = new Vector<DbInstrumentInfo>();
264     for(int i = 0; i < parent.getInstrumentCount(); i++) {
265     String name = parent.getInstrumentAt(i).getName();
266    
267     for(int j = 0; j < children.length; j++) {
268     if(children[j] == null) continue;
269     if(children[j].getName().equals(name)) {
270     children[j] = null;
271     found = true;
272     break;
273     }
274     }
275     if(!found) removedNodes.add(parent.getInstrumentAt(i));
276     found = false;
277     }
278    
279     for(DbInstrumentInfo info : removedNodes) {
280     int i = parent.getInstrumentIndex(info);
281     parent.removeInstrument(i);
282     }
283    
284     for(DbInstrumentInfo info : children) {
285     if(info == null) continue;
286     parent.addInstrument(info);
287     }
288     }
289    
290     /**
291     * Schedules a task for refreshing the directory content of the specified directory.
292     * Note that the specified directory is expected to be connected.
293     * @param dir The absolute path name of the directory to refresh.
294     */
295     public void
296     refreshDirectoryContent(String dir) {
297     final DbDirectoryTreeNode node = getNodeByPath(dir);
298     if(node == null) return;
299    
300     node.removeAllDirectories();
301     fireNodeStructureChanged(node);
302     node.removeAllInstruments();
303    
304     final InstrumentsDb.GetDrectories gd = new InstrumentsDb.GetDrectories(dir);
305    
306     gd.addTaskListener(new TaskListener() {
307     public void
308     taskPerformed(TaskEvent e) {
309     if(gd.doneWithErrors()) return;
310    
311     for(DbDirectoryInfo info : gd.getResult()) {
312     DbDirectoryTreeNode n = new DbDirectoryTreeNode(info);
313     node.addDirectory(n);
314     fireNodeInserted(n, node.getIndex(n));
315     n.setConnected(true);
316     updateDirectoryContent(n, n.getInfo().getDirectoryPath());
317     }
318     }
319     });
320     CC.scheduleTask(gd);
321    
322     final InstrumentsDb.GetInstruments gi = new InstrumentsDb.GetInstruments(dir);
323    
324     gi.addTaskListener(new TaskListener() {
325     public void
326     taskPerformed(TaskEvent e) {
327     if(gi.doneWithErrors()) return;
328    
329     for(DbInstrumentInfo info : gi.getResult()) {
330     node.addInstrument(info);
331     }
332     }
333     });
334     CC.scheduleTask(gi);
335     }
336    
337     protected Object[]
338     getPathToRoot(DbDirectoryTreeNode node) {
339     Vector v = new Vector();
340    
341     while(node != null) {
342     v.insertElementAt(node, 0);
343     if(node == getRoot()) break;
344     node = node.getParent();
345     }
346    
347     return v.toArray(new Object[v.size()]);
348     }
349    
350     protected String
351     getPathName(Object[] objs) {
352     if(objs.length == 1) return "/";
353    
354     StringBuffer sb = new StringBuffer();
355     for(int i = 1; i < objs.length; i++) {
356 iliev 1347 sb.append('/').append(toEscapedFileName(objs[i]));
357 iliev 1204 }
358    
359     return sb.toString();
360     }
361    
362     private void
363     fireNodeInserted(DbDirectoryTreeNode node, int index) {
364     Object[] path = getPathToRoot(node.getParent());
365     int[] idxs = { index };
366     Object[] objs = { node };
367     TreeModelEvent e = new TreeModelEvent(this, path, idxs, objs);
368     for(TreeModelListener l : listeners) {
369     l.treeNodesInserted(e);
370     }
371     }
372    
373     private void
374     fireNodeChanged(DbDirectoryTreeNode node, int index) {
375     Object[] path = getPathToRoot(node.getParent());
376     int[] idxs = { index };
377     Object[] objs = { node };
378     TreeModelEvent e = new TreeModelEvent(this, path, idxs, objs);
379     for(TreeModelListener l : listeners) {
380     l.treeNodesChanged(e);
381     }
382     }
383    
384     private void
385     fireNodeRemoved(DbDirectoryTreeNode parent, DbDirectoryTreeNode node, int index) {
386     Object[] path = getPathToRoot(parent);
387     int[] idxs = { index };
388     Object[] objs = { node };
389     TreeModelEvent e = new TreeModelEvent(this, path, idxs, objs);
390     for(int i = listeners.size() - 1; i >=0; i--) {
391     listeners.get(i).treeNodesRemoved(e);
392     }
393     }
394    
395     private void
396     fireNodeStructureChanged(DbDirectoryTreeNode node) {
397     Object[] path = getPathToRoot(node);
398     Object[] objs = { node };
399     TreeModelEvent e = new TreeModelEvent(this, path);
400     for(TreeModelListener l : listeners) {
401     l.treeStructureChanged(e);
402     }
403     }
404    
405     public DbDirectoryTreeNode
406     getNodeByPath(String path) {
407 iliev 1347 String[] dirs = getDirectoryList(path);
408 iliev 1204 if(dirs == null) return null;
409     if(dirs.length == 1) return root;
410    
411     DbDirectoryTreeNode node = root;
412     boolean found = false;
413     for(int i = 1; i < dirs.length; i++) {
414     for(int k = 0; k < node.getChildCount(); k++) {
415 iliev 1347 String s = toNonEscapedFileName(dirs[i]);
416     if(s.equals(node.getChildAt(k).toString())) {
417 iliev 1204 node = node.getChildAt(k);
418     found = true;
419     break;
420     }
421     }
422    
423     if(!found) return null;
424     found = false;
425     }
426    
427     return node;
428     }
429    
430     public String
431     getPathByNode(DbDirectoryTreeNode node) {
432     if(node == null) return null;
433     return getPathName(getPathToRoot(node));
434     }
435    
436     /**
437     * @param l A listener which will be notified when the operation is completed.
438     */
439     public void
440     loadPath(String path, final ActionListener l) {
441     // TODO: This method is lazily implemented. Should be optimized.
442 iliev 1347 final String[] dirs = getDirectoryList(path);
443 iliev 1204 if(dirs == null) {
444     l.actionPerformed(null);
445     return;
446     }
447    
448     final ActionListener listener = new ActionListener() {
449     public void
450     actionPerformed(ActionEvent e) {
451     String s = "";
452     DbDirectoryTreeNode node = null;
453     for(int i = 0; i < dirs.length; i++) {
454     if(i > 1) s += "/" + dirs[i];
455     else s += dirs[i];
456     node = getNodeByPath(s);
457     if(node == null) {
458     if(l != null) l.actionPerformed(null);
459     return;
460     }
461    
462     if(!node.isConnected()) {
463     node.setConnected(true);
464     updateDirectoryContent(node, s, this);
465     return;
466     }
467     }
468    
469     if(l != null) l.actionPerformed(null);
470     }
471     };
472    
473     listener.actionPerformed(null);
474     }
475    
476     private final EventHandler eventHandler = new EventHandler();
477    
478     private EventHandler
479     getHandler() { return eventHandler; }
480    
481     private class EventHandler implements InstrumentsDbListener {
482     /**
483     * Invoked when the number of instrument
484     * directories in a specific directory has changed.
485     */
486     public void
487     directoryCountChanged(final InstrumentsDbEvent e) {
488     SwingUtilities.invokeLater(new Runnable() {
489     public void
490     run() {
491     DbDirectoryTreeNode node = getNodeByPath(e.getPathName());
492     if(node == null) {
493     return;
494     }
495     if(!node.isConnected()) {
496     return;
497     }
498    
499     updateDirectoryContent(node, e.getPathName());
500     }
501     });
502     }
503    
504     /**
505     * Invoked when the settings of an instrument directory are changed.
506     */
507     public void
508     directoryInfoChanged(final InstrumentsDbEvent e) {
509     SwingUtilities.invokeLater(new Runnable() {
510     public void
511     run() { updateDirectoryInfo(e); }
512     });
513     }
514    
515     private void
516     updateDirectoryInfo(InstrumentsDbEvent e) {
517     final DbDirectoryTreeNode node = getNodeByPath(e.getPathName());
518     if(node == null) return;
519    
520     final InstrumentsDb.GetDrectory t =
521     new InstrumentsDb.GetDrectory(e.getPathName());
522    
523     t.addTaskListener(new TaskListener() {
524     public void
525     taskPerformed(TaskEvent e) {
526     if(t.doneWithErrors()) return;
527     if(node.getParent() != null) {
528     node.getParent().updateDirectory(t.getResult());
529     fireNodeChanged(node, node.getParent().getIndex(node));
530     }
531     }
532     });
533    
534     CC.getTaskQueue().add(t);
535     }
536    
537     /**
538     * Invoked when an instrument directory is renamed.
539     */
540     public void
541     directoryNameChanged(final InstrumentsDbEvent e) {
542     SwingUtilities.invokeLater(new Runnable() {
543     public void
544     run() { directoryRenamed(e); }
545     });
546     }
547    
548     private void
549     directoryRenamed(InstrumentsDbEvent e) {
550     DbDirectoryTreeNode node = getNodeByPath(e.getPathName());
551     if(node == null) {
552     // If the directory is renamed by this frontend the
553     // directory should already be with the new name
554     String s = getParentDirectory(e.getPathName());
555 iliev 1347 if(s.length() == 1) s += toEscapedFileName(e.getNewName());
556     else s += "/" + toEscapedFileName(e.getNewName());
557 iliev 1204 node = getNodeByPath(s);
558     }
559     if(node == null || node.getParent() == null) {
560     CC.getLogger().warning("Invalid path: " + e.getPathName());
561     return;
562     }
563    
564     node.getInfo().setName(e.getNewName());
565     DbDirectoryTreeNode parent = node.getParent();
566    
567     int i = parent.getIndex(node);
568     parent.removeDirectory(i);
569     fireNodeRemoved(parent, node, i);
570    
571     parent.addDirectory(node);
572     fireNodeInserted(node, parent.getIndex(node));
573     }
574    
575     /**
576     * Invoked when the number of instruments
577     * in a specific directory has changed.
578     */
579     public void
580     instrumentCountChanged(final InstrumentsDbEvent e) {
581     SwingUtilities.invokeLater(new Runnable() {
582     public void
583     run() {
584     DbDirectoryTreeNode node = getNodeByPath(e.getPathName());
585     if(node == null) {
586     return;
587     }
588     if(!node.isConnected()) {
589     return;
590     }
591    
592     updateDirectoryContent(node, e.getPathName());
593     }
594     });
595     }
596    
597     /**
598     * Invoked when the settings of an instrument are changed.
599     */
600     public void
601     instrumentInfoChanged(final InstrumentsDbEvent e) {
602     SwingUtilities.invokeLater(new Runnable() {
603     public void
604     run() { updateInstrumentInfo(e); }
605     });
606     }
607    
608     /**
609     * Invoked when an instrument is renamed.
610     */
611     public void
612     instrumentNameChanged(final InstrumentsDbEvent e) {
613     SwingUtilities.invokeLater(new Runnable() {
614     public void
615     run() { instrumentRenamed(e); }
616     });
617     }
618    
619     private void
620     updateInstrumentInfo(InstrumentsDbEvent e) {
621     String dir = getParentDirectory(e.getPathName());
622     final DbDirectoryTreeNode node = getNodeByPath(dir);
623     if(node == null) return;
624     if(!node.isConnected()) return;
625    
626     final InstrumentsDb.GetInstrument t =
627     new InstrumentsDb.GetInstrument(e.getPathName());
628    
629     t.addTaskListener(new TaskListener() {
630     public void
631     taskPerformed(TaskEvent e) {
632     if(t.doneWithErrors()) return;
633     node.updateInstrument(t.getResult());
634     }
635     });
636    
637     CC.getTaskQueue().add(t);
638     }
639    
640     private void
641     instrumentRenamed(InstrumentsDbEvent e) {
642     String dir = getParentDirectory(e.getPathName());
643     DbDirectoryTreeNode node = getNodeByPath(dir);
644     if(node == null) return;
645    
646 iliev 1347 String instr = getFileName(e.getPathName());
647     if(instr == null) return;
648 iliev 1204
649     DbInstrumentInfo info = node.getInstrument(instr);
650    
651     if(info == null) {
652     // If the instrument is renamed by this frontend the
653     // instrument should already be with the new name
654     info = node.getInstrument(e.getNewName());
655     }
656     if(info == null) {
657     CC.getLogger().warning("Invalid path: " + e.getPathName());
658     return;
659     }
660    
661     info.setName(e.getNewName());
662     node.removeInstrument(node.getInstrumentIndex(info));
663     node.addInstrument(info);
664     }
665    
666     /** Invoked when the status of particular job has changed. */
667     public void
668     jobStatusChanged(InstrumentsDbEvent e) { }
669     }
670     }

  ViewVC Help
Powered by ViewVC