/******************************************************************************* * Copyright (c) 2007, 2008 Gregory Jordan * * This file is part of PhyloWidget. * * PhyloWidget is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 2 of the License, or (at your option) any later * version. * * PhyloWidget is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * PhyloWidget. If not, see <http://www.gnu.org/licenses/>. */ package org.phylowidget; import java.util.ArrayList; import java.util.List; import org.andrewberman.ui.unsorted.SearchIndex; import org.jgrapht.graph.DefaultWeightedEdge; import org.jgrapht.traverse.DepthFirstIterator; import org.phylowidget.tree.CachedRootedTree; import org.phylowidget.tree.PhyloNode; import org.phylowidget.ui.NodeUncollapser; public class PhyloTree extends CachedRootedTree<PhyloNode, DefaultWeightedEdge> { private static final long serialVersionUID = 1L; private SearchIndex<PhyloNode> index = new SearchIndex<PhyloNode>(); public PhyloTree() { super(DefaultWeightedEdge.class); if (PWPlatform.getInstance().getThisAppContext() != null) setEnforceUniqueLabels(PWPlatform.getInstance().getThisAppContext().config().enforceUniqueLabels); } @Override public void uncollapseNode(PhyloNode v) { v.clearAnnotation("collapse"); // Set all subtree nodes to current position. List<PhyloNode> nodes = getAllNodes(v); for (PhyloNode n : nodes) { n.setLayoutX(v.getLayoutX()); n.setLayoutY(v.getLayoutY()); n.setX(v.getX()); n.setY(v.getY()); n.fforward(); } modPlus(); } private static String baseURL; public void setBaseURL(String baseURL) { this.baseURL = baseURL; } @Override public String getAnnotation(PhyloNode vertex,String key) { if (vertex == null) return null; return vertex.getAnnotation(key); // return super.getAnnotation(vertex); } public void clearAnnotation(PhyloNode vertex, String key) { if (vertex == null) return; vertex.clearAnnotation(key); } public String getBaseURL() { if (baseURL == null) return ""; return this.baseURL; } @Override public void collapseNode(PhyloNode v) { v.setAnnotation("collapse", "yes"); new NodeUncollapser(PWPlatform.getInstance().getThisAppContext().getPW(),v); modPlus(); } @Override public boolean isCollapsed(PhyloNode v) { String annot = v.getAnnotation("collapse"); if (annot != null) { if (PhyloNode.parseTruth(annot)) return true; } return false; } public PhyloNode hoveredNode; public void setHoveredNode(PhyloNode n) { hoveredNode = n; } public PhyloNode createVertex() { return new PhyloNode(); } public void flipChildren(PhyloNode parent) { super.flipChildren(parent); } public PhyloNode getHoveredNode() { return hoveredNode; } int modCount = 0; @Override public int getModCount() { return modCount; } public void reverseSubtree(PhyloNode vertex) { super.reverseSubtree(vertex); } @Override public void setLabel(Object vertex, String label) { index.remove((PhyloNode) vertex); super.setLabel(vertex, label); index.add((PhyloNode) vertex); } void removeFound() { ArrayList nodes = new ArrayList(); getAll(getRoot(), null, nodes); for (int i = 0; i < nodes.size(); i++) { PhyloNode n = (PhyloNode) nodes.get(i); n.found = false; } } public void markNodesAsFound(List<PhyloNode> matches) { removeFound(); for (PhyloNode n : matches) { PhyloNode cur = n; while (cur != null) { cur.found = true; cur = (PhyloNode) getParentOf(cur); } } } public void searchAndMarkFound(String s) { List<PhyloNode> matches = search(s); markNodesAsFound(matches); } public List<PhyloNode> search(String s) { String[] searches = s.split(";"); ArrayList<PhyloNode> matches = new ArrayList<PhyloNode>(); for (String s2 : searches) { matches.addAll(index.search(s2)); } return matches; } public PhyloNode getVertexForAnnotation(String key, String searchValue) { DepthFirstIterator<PhyloNode,DefaultWeightedEdge> it = new DepthFirstIterator<PhyloNode,DefaultWeightedEdge>(this, getRoot()); while (it.hasNext()) { PhyloNode vertex = it.next(); String value = vertex.getAnnotation(key); if (value != null) { if (value.equalsIgnoreCase(searchValue)) { return vertex; } } } return null; } @Override public boolean removeVertex(PhyloNode o) { boolean b = super.removeVertex(o); if (b) index.remove((PhyloNode) o); return b; } @Override public boolean addVertex(PhyloNode o) { boolean b = super.addVertex(o); if (b) index.add((PhyloNode) o); return b; } @Override public void modPlus() { super.modPlus(); modCount++; if (modCount > 1000) modCount = 0; } // class NewickUpdater implements GraphListener // { // public void edgeAdded(GraphEdgeChangeEvent e) // { // if (e.getType() == GraphEdgeChangeEvent.EDGE_ADDED) // { // updateNewick(); // } // } // // public void edgeRemoved(GraphEdgeChangeEvent e) // { // if (e.getType() == GraphEdgeChangeEvent.EDGE_REMOVED) // { // updateNewick(); // } // } // // public void vertexAdded(GraphVertexChangeEvent e) // { // if (e.getType() == GraphVertexChangeEvent.VERTEX_ADDED) // { // updateNewick(); // } // } // // public void vertexRemoved(GraphVertexChangeEvent e) // { // if (e.getType() == GraphVertexChangeEvent.VERTEX_REMOVED) // { // // index.remove((PhyloNode) e.getVertex()); // updateNewick(); // } // } // } // public static void main(String... args) // { // SimpleDirectedGraph<String, String> g = new SimpleDirectedGraph<String, String>( // String.class); // g.addVertex("Hello"); // g.addVertex("World!"); // g.addEdge("World!", "Hello"); // // SimpleDirectedGraph<String, String> g2 = new SimpleDirectedGraph<String, String>( // String.class) // { // public boolean addVertex(String s) // { // System.out.println(s); // return super.addVertex(s); // } // }; // System.out.println(g2); // Graphs.addGraph(g2, g); // System.out.println(g2); // } }