From: kjvdheide Date: Mon, 18 Dec 2017 15:37:19 +0000 (+0000) Subject: Merge branch 'kjvdh/features/PhylogenyViewer' into X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=fffa60416174fe7a29bca9ea4c8b53d45a6e905c;p=jalview.git Merge branch 'kjvdh/features/PhylogenyViewer' into kjvdh/features/PhylogenyViewerInterfaces Conflicts: src/jalview/ext/archaeopteryx/AptxFrame.java src/jalview/ext/archaeopteryx/AptxInit.java src/jalview/ext/archaeopteryx/AptxTreePanel.java src/jalview/ext/archaeopteryx/JalviewBinding.java src/jalview/ext/archaeopteryx/LoadedTreeSequenceAssociation.java src/jalview/ext/archaeopteryx/Tree.java src/jalview/ext/archaeopteryx/TreeNode.java src/jalview/ext/treeviewer/ExternalTreeParserI.java src/jalview/ext/treeviewer/ExternalTreeViewerFrameI.java --- fffa60416174fe7a29bca9ea4c8b53d45a6e905c diff --cc src/jalview/ext/archaeopteryx/AptxFrame.java index c517ed3,0000000..9a47836 mode 100644,000000..100644 --- a/src/jalview/ext/archaeopteryx/AptxFrame.java +++ b/src/jalview/ext/archaeopteryx/AptxFrame.java @@@ -1,404 -1,0 +1,395 @@@ +package jalview.ext.archaeopteryx; + +import jalview.bin.Cache; +import jalview.ext.treeviewer.ExternalTreeControlsI; +import jalview.ext.treeviewer.ExternalTreeFrame; +import jalview.ext.treeviewer.ExternalTreeI; +import jalview.ext.treeviewer.ExternalTreePanel; +import jalview.gui.Desktop; +import jalview.gui.EPSOptions; +import jalview.io.JalviewFileChooser; +import jalview.io.JalviewFileView; +import jalview.util.ImageMaker; +import jalview.util.MessageManager; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Font; +import java.awt.Image; +import java.awt.MenuComponent; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.FileOutputStream; + +import javax.accessibility.AccessibleContext; +import javax.swing.JLayeredPane; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JRootPane; +import javax.swing.JSeparator; +import javax.swing.event.InternalFrameListener; + +import org.forester.archaeopteryx.Archaeopteryx; +import org.forester.archaeopteryx.Configuration; +import org.forester.archaeopteryx.MainFrame; +import org.forester.phylogeny.Phylogeny; +import org.jibble.epsgraphics.EpsGraphics2D; + +public class AptxFrame implements ExternalTreeFrame +{ + private final MainFrame aptxFrame; + + private ExternalTreePanel aptxPanel; + + private ExternalTreeControlsI aptxControls; + + + public AptxFrame(Phylogeny tree, Configuration aptxConfig, + String treeTitle) + { + this(Archaeopteryx.createApplication(tree, + aptxConfig, + treeTitle)); + + } + + + public AptxFrame(MainFrame aptx) + { + + aptxFrame = aptx; + aptxPanel = new AptxTreePanel( + aptxFrame.getMainPanel().getCurrentTreePanel()); + aptxControls = new AptxControlPanel( + aptxFrame.getMainPanel().getControlPanel()); + adaptAptxGui(aptxFrame); + + } + + /** + * Hides certain redundant Archaeopteryx GUI elements such as the menu items + * for reading in trees and adds extra items related to Jalview such as the + * tree sorting menu item. + * + * + * @param aptxFrame + */ + protected void adaptAptxGui(MainFrame aptxFrame) + { + JMenuBar frameBar = aptxFrame.getJMenuBar(); + boolean epsAdded = false; + for (int i = 0; i < frameBar.getMenuCount();i++) { + JMenu menu = frameBar.getMenu(i); + int menuCount = menu.getMenuComponentCount(); + + if (menu.getText().contains("File")) + { + // hide all "Read from ..." and "New" menu items and any Separators that + // come directly after them + Component previousComp = null; + for (int x = 0; x < menuCount; x++) + { + Component menuItem = menu.getMenuComponent(x); + if (previousComp instanceof JMenuItem) + { + JMenuItem previousMenuItem = (JMenuItem) previousComp; + if (previousMenuItem.getText().startsWith("Read") + || previousMenuItem.getText() + .startsWith("New") + || previousMenuItem.getText() + .startsWith("Close Tab")) + { + previousComp.setVisible(false); + + if (menuItem instanceof JSeparator) + { + menuItem.setVisible(false); + } + + } + + if ((!epsAdded) && previousMenuItem.getText() + .startsWith("Export to")) + { + JMenuItem exportEps = new JMenuItem("Export to EPS file..."); + menu.add(exportEps, x); + exportEps.addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + epsTree_actionPerformed(e); + + } + + }); + epsAdded = true; + + } + } + previousComp = menuItem; + } + } + else if (menu.getText().contains("Inference")) + { + menu.setVisible(false); + } + else if (menu.getText().contains("View")) + { + menu.addSeparator(); + JMenuItem sortByTree = new JMenuItem("Sort alignment by tree"); + JMenuItem refreshJalview = new JMenuItem( + "Filter alignment to show only currently visible sequences"); + + refreshJalview.setFont(menu.getFont()); + + menu.add(sortByTree); + menu.add(refreshJalview); + + sortByTree.setFont(menu.getFont()); - refreshJalview.addActionListener(new ActionListener() - { - - @Override - public void actionPerformed(ActionEvent e) - { - // TODO Auto-generated method stub - - } - - }); ++ refreshJalview ++ .addActionListener(AptxInit.getAllAptxFrames().get(this)); + + + } + + } + // aptxFrame.validate(); + } + + public void epsTree_actionPerformed(ActionEvent e) + { + boolean accurateText = true; + + String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING", + "Prompt each time"); + + // If we need to prompt, and if the GUI is visible then + // Prompt for EPS rendering style + if (renderStyle.equalsIgnoreCase("Prompt each time") + && !(System.getProperty("java.awt.headless") != null && System + .getProperty("java.awt.headless").equals("true"))) + { + EPSOptions eps = new EPSOptions(); + renderStyle = eps.getValue(); + + if (renderStyle == null || eps.cancelled) + { + return; + } + + } + + if (renderStyle.equalsIgnoreCase("text")) + { + accurateText = false; + } + + int width = getTreePanel().getWidth(); + int height = getTreePanel().getHeight(); + + try + { + JalviewFileChooser chooser = new JalviewFileChooser( + ImageMaker.EPS_EXTENSION, ImageMaker.EPS_EXTENSION); + chooser.setFileView(new JalviewFileView()); + chooser.setDialogTitle( + MessageManager.getString("label.create_eps_from_tree")); + chooser.setToolTipText(MessageManager.getString("action.save")); + + int value = chooser.showSaveDialog(aptxFrame); + + if (value != JalviewFileChooser.APPROVE_OPTION) + { + return; + } + + Cache.setProperty("LAST_DIRECTORY", + chooser.getSelectedFile().getParent()); + + FileOutputStream out = new FileOutputStream( + chooser.getSelectedFile()); + EpsGraphics2D pg = new EpsGraphics2D("Tree", out, 0, 0, width, + height); + + pg.setAccurateTextMode(accurateText); + + getTreePanel().paintToFile(pg, width, height); + + pg.flush(); + pg.close(); + } catch (Exception ex) + { + ex.printStackTrace(); + } + } + @Override + public ExternalTreePanel getTreePanel() + { + return aptxPanel; + } + + @Override + public ExternalTreeI getTree() + { + return aptxPanel.getTree(); + } + + @Override + public void checkMultipleTrees() + { + aptxFrame.activateSaveAllIfNeeded(); + + } + + @Override + public int getNumberOfTrees() + { + return aptxFrame.getMainPanel().getTabbedPane().getTabCount(); + } + + @Override + public ExternalTreeControlsI getTreeControls() + { + return aptxControls; + } + + @Override + public AccessibleContext getAccessibleContext() + { + return aptxFrame.getAccessibleContext(); + } + + @Override + public JRootPane getRootPane() + { + return aptxFrame.getRootPane(); + } + + @Override + public void setContentPane(Container contentPane) + { + aptxFrame.setContentPane(contentPane); + + } + + @Override + public Container getContentPane() + { + return aptxFrame.getContentPane(); + } + + @Override + public void setLayeredPane(JLayeredPane layeredPane) + { + aptxFrame.setLayeredPane(layeredPane); + + } + + @Override + public JLayeredPane getLayeredPane() + { + return aptxFrame.getLayeredPane(); + } + + @Override + public void setGlassPane(Component glassPane) + { + aptxFrame.setGlassPane(glassPane); + + } + + @Override + public Component getGlassPane() + { + return aptxFrame.getGlassPane(); + } + + @Override + public boolean imageUpdate(Image img, int infoflags, int x, int y, + int width, int height) + { + return aptxFrame.imageUpdate(img, infoflags, x, y, width, height); + } + + @Override + public Font getFont() + { + return aptxFrame.getFont(); + } + + @Override + public void remove(MenuComponent comp) + { + aptxFrame.remove(comp); + + } + + @Deprecated + @Override + public boolean postEvent(Event evt) + { + return aptxFrame.postEvent(evt); + } + + @Override + public void addFrameListener(InternalFrameListener listener) + { + aptxFrame.addInternalFrameListener(listener); + + } + + @Override + public void removeFrameListener(InternalFrameListener listener) + { + aptxFrame.removeInternalFrameListener(listener); + + } + + @Override + public InternalFrameListener[] getFrameListeners() + { + return aptxFrame.getInternalFrameListeners(); + + } + + @Override + public void repaint() + { + aptxFrame.repaint(); + + } + + @Override + public void setMinimumSize(Dimension dimension) + { + aptxFrame.setMinimumSize(dimension); + + } + + @Override + public boolean isShowing() + { + return aptxFrame.isShowing(); + } + + @Override + public Container getTopLevelAncestor() + { + return aptxFrame.getTopLevelAncestor(); + } + + @Override + public void addFrameToJalview(String title, boolean makeVisible, + int width, int height, boolean resizable, boolean ignoreMinSize) + { + Desktop.addInternalFrame(aptxFrame, title, makeVisible, width, height, + resizable, ignoreMinSize); + + } + +} diff --cc src/jalview/ext/archaeopteryx/AptxTreePanel.java index f811c3b,0000000..5693b0f mode 100644,000000..100644 --- a/src/jalview/ext/archaeopteryx/AptxTreePanel.java +++ b/src/jalview/ext/archaeopteryx/AptxTreePanel.java @@@ -1,182 -1,0 +1,195 @@@ +package jalview.ext.archaeopteryx; + +import jalview.ext.treeviewer.ExternalTreeI; +import jalview.ext.treeviewer.ExternalTreeNodeI; +import jalview.ext.treeviewer.ExternalTreePanel; +import jalview.gui.PaintRefresher; + +import java.awt.Event; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.MenuComponent; ++import java.awt.Rectangle; +import java.awt.event.MouseListener; +import java.io.File; +import java.util.Set; + +import javax.accessibility.AccessibleContext; + +public class AptxTreePanel implements ExternalTreePanel +{ + private final org.forester.archaeopteryx.TreePanel treeView; + + private final ExternalTreeI tree; + + private String sequenceSetId; + + protected AptxTreePanel( + org.forester.archaeopteryx.TreePanel aptxTreePanel) + { + treeView = aptxTreePanel; + tree = new Tree(treeView.getPhylogeny()); + } + + protected AptxTreePanel( + org.forester.archaeopteryx.TreePanel aptxTreePanel, + ExternalTreeI aptxTree) + { + treeView = aptxTreePanel; + tree = aptxTree; + + } + + @Override + public void setTreeFile(File file) + { + treeView.setTreeFile(file); + } + + @Override + public ExternalTreeI getTree() + { + return tree; + } + + @Override + public File getTreeFile() + { + return treeView.getTreeFile(); + } + + @Override + public ExternalTreeNodeI findNode(int x, int y) + { + return TreeNode.getUniqueWrapper(treeView.findNode(x, y)); + } + + @Override + public void setMatchingNodes(Set hashSet) + { + treeView.setFoundNodes0(hashSet); + + } + + @Override + public Set getMatchingNodes() + { + return treeView.getFoundNodes0(); + } + + @Override + public AccessibleContext getAccessibleContext() + { + return treeView.getAccessibleContext(); + } + + @Override + public Font getFont() + { + return treeView.getFont(); + } + + @Override + public void remove(MenuComponent comp) + { + treeView.remove(comp); + + } + + @Deprecated + @Override + public boolean postEvent(Event evt) + { + return treeView.postEvent(evt); + } + + @Override + public void addMouseListener(MouseListener listener) + { + treeView.addMouseListener(listener); + } + + @Override + public void removeMouseListener(MouseListener listener) + { + treeView.removeMouseListener(listener); + + } + + @Override + public MouseListener[] getMouseListeners() + { + return treeView.getMouseListeners(); + } + + @Override + public void repaint() + { + treeView.repaint(); + + } + + @Override + public void registerWithPaintRefresher(String sequenceSetIdentifier) + { + sequenceSetId = sequenceSetIdentifier; + PaintRefresher.Register(treeView, sequenceSetIdentifier); + + } + + @Override + public void notifyPaintRefresher(String sequenceSetIdentifier, + boolean alignmentChanged, boolean validateSequences) + { + PaintRefresher.Refresh(treeView, sequenceSetIdentifier, + alignmentChanged, validateSequences); + + } + + @Override + public void notifyPaintRefresher(boolean alignmentChanged, + boolean validateSequences) + { + if (sequenceSetId != null) + { + PaintRefresher.Refresh(treeView, sequenceSetId, alignmentChanged, + validateSequences); + } + else + { + // throw some kind of exception + } + + } + + @Override + public int getWidth() + { + return treeView.getWidth(); + } + + @Override + public int getHeight() + { + return treeView.getHeight(); + } + + @Override + public void paintToFile(Graphics2D pg, int width, int height) + { + treeView.paintFile(pg, false, width, height, 0, 0); + + } ++ ++ @Override ++ public boolean showingSubTree() ++ { ++ return treeView.isCurrentTreeIsSubtree(); ++ } ++ ++ @Override ++ public Rectangle getVisibleArea() ++ { ++ return treeView.getVisibleRect(); ++ } +} diff --cc src/jalview/ext/archaeopteryx/JalviewBinding.java index 810a711,0593217..772a7d8 --- a/src/jalview/ext/archaeopteryx/JalviewBinding.java +++ b/src/jalview/ext/archaeopteryx/JalviewBinding.java @@@ -9,11 -9,7 +9,12 @@@ import jalview.datamodel.ColumnSelectio import jalview.datamodel.HiddenColumns; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.ext.treeviewer.ExternalTreeFrame; +import jalview.ext.treeviewer.ExternalTreeI; +import jalview.ext.treeviewer.ExternalTreeNodeI; +import jalview.ext.treeviewer.ExternalTreePanel; import jalview.ext.treeviewer.ExternalTreeViewerBindingI; ++import jalview.ext.treeviewer.LoadedTreeSequenceAssociation; import jalview.gui.AlignViewport; import jalview.gui.AlignmentPanel; import jalview.gui.Desktop; @@@ -169,7 -178,50 +171,52 @@@ public final class JalviewBindin @Override public void actionPerformed(ActionEvent e) { - // aptxFrame.actionPerformed(e); + // reset hidden sequences first + parentAvport.showAllHiddenSeqs(); + - if (treeView.isCurrentTreeIsSubtree()) ++ if (treeView.showingSubTree()) + { + LoadedTreeSequenceAssociation bindAptxNodes = new LoadedTreeSequenceAssociation( + parentAvport.getAlignment().getSequencesArray(), - treeView.getPhylogeny()); ++ treeView.getTree()); + bindAptxNodes.associateLeavesToSequences(); + sequencesBoundToNodes = bindAptxNodes.getAlignmentWithNodes(); + nodesBoundToSequences = bindAptxNodes.getNodesWithAlignment(); + AptxInit.bindNodesToJalviewSequences(aptxFrame, parentAvport, + sequencesBoundToNodes, nodesBoundToSequences); + + + for (SequenceI seq : parentAvport.getAlignment().getSequencesArray()) + { + if (!sequencesBoundToNodes.containsKey(seq)) + { + parentAvport.hideSequence(new SequenceI[] { seq }); + } + } + } + + else + { + - Rectangle visibleView = treeView.getVisibleRect(); ++ Rectangle visibleView = treeView.getVisibleArea(); + - for (PhylogenyNode node : PhylogenyMethods.getAllDescendants(treeView.getPhylogeny().getRoot())) { ++ for (ExternalTreeNodeI node : treeView.getTree().getRoot() ++ .getAllDescendants()) ++ { + if (!(node.getXcoord() > visibleView.getMinX() + && node.getXcoord() < visibleView.getMaxX() + && node.getYcoord() > visibleView.getMinY() + && node.getYcoord() < visibleView.getMaxY())) + { + parentAvport + .hideSequence(new SequenceI[] + { nodesBoundToSequences.get(node) }); + } + } + + } + + } diff --cc src/jalview/ext/treeviewer/ExternalTreePanel.java index 5197b1c,0000000..85ad800 mode 100644,000000..100644 --- a/src/jalview/ext/treeviewer/ExternalTreePanel.java +++ b/src/jalview/ext/treeviewer/ExternalTreePanel.java @@@ -1,49 -1,0 +1,54 @@@ +package jalview.ext.treeviewer; + +import java.awt.Graphics2D; +import java.awt.MenuContainer; ++import java.awt.Rectangle; +import java.awt.event.MouseListener; +import java.io.File; +import java.util.Set; + +import javax.accessibility.Accessible; + +public interface ExternalTreePanel extends Accessible, MenuContainer +{ + + + public abstract void setTreeFile(File file); + + public abstract File getTreeFile(); + + public abstract ExternalTreeI getTree(); + + public abstract ExternalTreeNodeI findNode(int x, int y); + + public abstract void setMatchingNodes(Set matchingNodes); + + public abstract Set getMatchingNodes(); + + public void addMouseListener(MouseListener listener); + + public void removeMouseListener(MouseListener listener); + + public MouseListener[] getMouseListeners(); + + public void repaint(); + + public void registerWithPaintRefresher(String sequenceSetIdentifier); + + public void notifyPaintRefresher(boolean alignmentChanged, + boolean validateSequences); + + public void notifyPaintRefresher(String newSeqSetIdentifier, + boolean alignmentChanged, boolean validateSequences); + + public int getWidth(); + + public int getHeight(); + + public abstract void paintToFile(Graphics2D pg, int width, int height); + ++ public boolean showingSubTree(); ++ ++ public abstract Rectangle getVisibleArea(); ++ +}