JAL-4134 display tree for columns - selecting an internal node selects column in...
[jalview.git] / src / jalview / gui / TreeCanvas.java
index a1bcebd..b8bcc74 100755 (executable)
@@ -36,6 +36,7 @@ import java.awt.print.PageFormat;
 import java.awt.print.Printable;
 import java.awt.print.PrinterException;
 import java.awt.print.PrinterJob;
+import java.util.BitSet;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
@@ -51,6 +52,8 @@ import jalview.analysis.Conservation;
 import jalview.analysis.TreeModel;
 import jalview.api.AlignViewportI;
 import jalview.datamodel.BinaryNode;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -806,12 +809,15 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     else
     {
       Vector<BinaryNode> leaves = tree.findLeaves(highlightNode);
-
+      if (tp.getColumnWise()) {
+        markColumnsFor(getAssociatedPanels(), leaves, Color.red);
+      } else {
       for (int i = 0; i < leaves.size(); i++)
       {
         SequenceI seq = (SequenceI) leaves.elementAt(i).element();
         treeSelectionChanged(seq);
       }
+      }
       av.sendSelection();
     }
 
@@ -981,69 +987,109 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
       setColor(groups.get(i), col.brighter());
 
       Vector<BinaryNode> l = tree.findLeaves(groups.get(i));
+      if (!tp.getColumnWise()) {
+        createSeqGroupFor(aps, l, col);
+      } else {
+        markColumnsFor(aps,l,col);
+      }
+    }
 
-      Vector<SequenceI> sequences = new Vector<>();
-
-      for (int j = 0; j < l.size(); j++)
+    // notify the panel(s) to redo any group specific stuff
+    // also updates structure views if necessary
+    for (int a = 0; a < aps.length; a++)
+    {
+      aps[a].updateAnnotation();
+      final AlignViewportI codingComplement = aps[a].av
+              .getCodingComplement();
+      if (codingComplement != null)
       {
-        SequenceI s1 = (SequenceI) l.elementAt(j).element();
+        ((AlignViewport) codingComplement).getAlignPanel()
+                .updateAnnotation();
+      }
+    }
+  }
 
-        if (!sequences.contains(s1))
-        {
-          sequences.addElement(s1);
+  private void markColumnsFor(AlignmentPanel[] aps, Vector<BinaryNode> l,
+          Color col)
+  {
+    SequenceI rseq = tp.assocAnnotation.sequenceRef;
+    for (BinaryNode bn:l)
+    {
+      int colm=-1;
+      try {
+        colm = Integer.parseInt(bn.getName().substring(bn.getName().indexOf("c")+1));
+      } catch (Exception e)
+      {
+        continue;
+      }
+      ColumnSelection cs = av.getColumnSelection();
+      HiddenColumns hc = av.getAlignment().getHiddenColumns();
+      {
+        int offp = (rseq!=null) ? rseq.findIndex(rseq.getStart()-1+colm) : colm;
+        
+        if (!av.hasHiddenColumns() || hc.isVisible(offp))
+        { 
+          if (cs.contains(offp))
+          {
+            cs.removeElement(offp);
+          } else {
+            cs.addElement(offp);
+          }
         }
       }
+    } 
+  }
 
-      ColourSchemeI cs = null;
-      SequenceGroup _sg = new SequenceGroup(sequences, null, cs, true, true,
-              false, 0, av.getAlignment().getWidth() - 1);
+  public void createSeqGroupFor(AlignmentPanel[] aps, Vector<BinaryNode> l,
+          Color col)
+  {
 
-      _sg.setName("JTreeGroup:" + _sg.hashCode());
-      _sg.setIdColour(col);
+    Vector<SequenceI> sequences = new Vector<>();
 
-      for (int a = 0; a < aps.length; a++)
-      {
-        SequenceGroup sg = new SequenceGroup(_sg);
-        AlignViewport viewport = aps[a].av;
-
-        // Propagate group colours in each view
-        if (viewport.getGlobalColourScheme() != null)
-        {
-          cs = viewport.getGlobalColourScheme().getInstance(viewport, sg);
-          sg.setColourScheme(cs);
-          sg.getGroupColourScheme().setThreshold(
-                  viewport.getResidueShading().getThreshold(),
-                  viewport.isIgnoreGapsConsensus());
+    for (int j = 0; j < l.size(); j++)
+    {
+      SequenceI s1 = (SequenceI) l.elementAt(j).element();
 
-          if (viewport.getResidueShading().conservationApplied())
-          {
-            Conservation c = new Conservation("Group",
-                    sg.getSequences(null), sg.getStartRes(),
-                    sg.getEndRes());
-            c.calculate();
-            c.verdict(false, viewport.getConsPercGaps());
-            sg.cs.setConservation(c);
-          }
-        }
-        // indicate that associated structure views will need an update
-        viewport.setUpdateStructures(true);
-        // propagate structure view update and sequence group to complement view
-        viewport.addSequenceGroup(sg);
+      if (!sequences.contains(s1))
+      {
+        sequences.addElement(s1);
       }
     }
 
-    // notify the panel(s) to redo any group specific stuff
-    // also updates structure views if necessary
+    ColourSchemeI cs = null;
+    SequenceGroup _sg = new SequenceGroup(sequences, null, cs, true, true,
+            false, 0, av.getAlignment().getWidth() - 1);
+
+    _sg.setName("JTreeGroup:" + _sg.hashCode());
+    _sg.setIdColour(col);
+
     for (int a = 0; a < aps.length; a++)
     {
-      aps[a].updateAnnotation();
-      final AlignViewportI codingComplement = aps[a].av
-              .getCodingComplement();
-      if (codingComplement != null)
+      SequenceGroup sg = new SequenceGroup(_sg);
+      AlignViewport viewport = aps[a].av;
+
+      // Propagate group colours in each view
+      if (viewport.getGlobalColourScheme() != null)
       {
-        ((AlignViewport) codingComplement).getAlignPanel()
-                .updateAnnotation();
+        cs = viewport.getGlobalColourScheme().getInstance(viewport, sg);
+        sg.setColourScheme(cs);
+        sg.getGroupColourScheme().setThreshold(
+                viewport.getResidueShading().getThreshold(),
+                viewport.isIgnoreGapsConsensus());
+
+        if (viewport.getResidueShading().conservationApplied())
+        {
+          Conservation c = new Conservation("Group", sg.getSequences(null),
+                  sg.getStartRes(), sg.getEndRes());
+          c.calculate();
+          c.verdict(false, viewport.getConsPercGaps());
+          sg.cs.setConservation(c);
+        }
       }
+      // indicate that associated structure views will need an update
+      viewport.setUpdateStructures(true);
+      // propagate structure view update and sequence group to complement view
+      viewport.addSequenceGroup(sg);
     }
   }