/* * Copyright (c) Henrik Niehaus & Lazy Bones development team * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of the project (Lazy Bones) nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package lazybones.gui.recordings; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Observable; import java.util.Observer; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import lazybones.RecordingManager; import org.hampelratte.svdrp.responses.highlevel.Folder; import org.hampelratte.svdrp.responses.highlevel.Recording; import org.hampelratte.svdrp.responses.highlevel.TreeNode; import org.hampelratte.svdrp.sorting.RecordingAlphabeticalComparator; import org.hampelratte.svdrp.sorting.RecordingSortStrategy; import org.hampelratte.svdrp.util.RecordingTreeBuilder; public class RecordingTreeModel implements TreeModel, Observer { private Folder root = new Folder(""); private final List<TreeModelListener> tmls = new ArrayList<TreeModelListener>(); private final RecordingManager rm; private Comparator<Recording> sortStrategy = new RecordingAlphabeticalComparator(); private boolean sortAscending = true; private String filter = ""; public RecordingTreeModel(RecordingManager recordingManager) { this.rm = recordingManager; rm.addObserver(this); sortBy(sortStrategy, sortAscending); } public void setRecordings(Folder root) { this.root = root; sortBy(sortStrategy, sortAscending); } @Override public Object getRoot() { return root; } @Override public Object getChild(Object parent, int index) { if (parent instanceof Folder) { Folder folder = (Folder) parent; return folder.getChildren().get(index); } return null; } @Override public int getChildCount(Object parent) { if (parent instanceof Folder) { Folder folder = (Folder) parent; return folder.getChildren().size(); } else { return 0; } } @Override public boolean isLeaf(Object node) { return node instanceof Recording; } @Override public void valueForPathChanged(TreePath tp, Object newValue) { int index = getIndexOfChild(tp.getParentPath().getLastPathComponent(), newValue); TreeModelEvent tme = new TreeModelEvent(this, tp.getParentPath(), new int[] { index }, new Object[] { newValue }); for (TreeModelListener tml : tmls) { tml.treeNodesChanged(tme); } } @Override public int getIndexOfChild(Object parent, Object child) { Folder folder = (Folder) parent; for (int i = 0; i < folder.getChildren().size(); i++) { if (folder.getChildren().get(i) == child) { return i; } } return -1; } @Override public void addTreeModelListener(TreeModelListener l) { tmls.add(l); } @Override public void removeTreeModelListener(TreeModelListener l) { tmls.remove(l); } public void remove(TreePath tp) { Folder current = root; for (int i = 1; i < tp.getPathCount(); i++) { Object o = tp.getPathComponent(i); for (TreeNode node : current.getChildren()) { if (i == tp.getPathCount() - 1) { int index = current.getChildren().indexOf(o); if (index >= 0) { current.getChildren().remove(index); TreeModelEvent tme = new TreeModelEvent(this, tp.getParentPath(), new int[] { index }, new Object[] { o }); for (TreeModelListener tml : tmls) { tml.treeNodesRemoved(tme); } return; } else { System.err.println("Element wurde nicht aus dem Baum gelöscht"); } } if (node == o) { current = (Folder) node; break; } } } } @Override public void update(Observable o, Object arg) { if (arg instanceof List) { @SuppressWarnings("unchecked") List<Recording> recordings = (List<Recording>) arg; setRecordings(RecordingTreeBuilder.buildTree(recordings)); filter(filter); } } public void sortBy(Comparator<Recording> comparator, boolean ascending) { this.sortStrategy = comparator; this.sortAscending = ascending; RecordingSortStrategy rss = new RecordingSortStrategy(comparator, ascending); root = RecordingTreeBuilder.buildTree(rm.getRecordings(), rss); filter(filter); for (TreeModelListener tml : tmls) { tml.treeStructureChanged(new TreeModelEvent(this, new Object[] { root })); } } public void filter(String filter) { this.filter = filter; RecordingSortStrategy rss = new RecordingSortStrategy(this.sortStrategy, this.sortAscending); root = RecordingTreeBuilder.buildTree(rm.getRecordings(), rss); if (!filter.trim().isEmpty()) { filter(root, filter.trim()); } for (TreeModelListener tml : tmls) { tml.treeStructureChanged(new TreeModelEvent(this, new Object[] { root })); } } private void filter(Folder folder, String filter) { for (Iterator<TreeNode> iterator = folder.getChildren().iterator(); iterator.hasNext();) { TreeNode child = iterator.next(); if (child instanceof Folder) { Folder childFolder = (Folder) child; if (!child.getDisplayTitle().toLowerCase().contains(filter.toLowerCase())) { filter(childFolder, filter); if (childFolder.getChildren().isEmpty()) { iterator.remove(); } } } else { if (!child.getDisplayTitle().toLowerCase().contains(filter.toLowerCase())) { iterator.remove(); } } } } }