Merge branch 'kjvdh/features/PhylogenyViewer' into
authorkjvdheide <kjvanderheide@dundee.ac.uk>
Mon, 18 Dec 2017 15:37:19 +0000 (15:37 +0000)
committerkjvdheide <kjvanderheide@dundee.ac.uk>
Mon, 18 Dec 2017 15:46:55 +0000 (15:46 +0000)
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

1  2 
src/jalview/ext/archaeopteryx/AptxFrame.java
src/jalview/ext/archaeopteryx/AptxTreePanel.java
src/jalview/ext/archaeopteryx/JalviewBinding.java
src/jalview/ext/treeviewer/ExternalTreePanel.java

index c517ed3,0000000..9a47836
mode 100644,000000..100644
--- /dev/null
@@@ -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);
 +
 +  }
 +
 +}
index f811c3b,0000000..5693b0f
mode 100644,000000..100644
--- /dev/null
@@@ -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<Long> hashSet)
 +  {
 +    treeView.setFoundNodes0(hashSet);
 +
 +  }
 +
 +  @Override
 +  public Set<Long> 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();
++  }
 +}
@@@ -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) });
+         }
+       }
+     }
  
    }
  
index 5197b1c,0000000..85ad800
mode 100644,000000..100644
--- /dev/null
@@@ -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<Long> matchingNodes);
 +
 +  public abstract Set<Long> 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();
++
 +}