e0a143ce1b41484ce0977ee50a820fb40ad3615b
[jalview.git] / src / jalview / ext / archaeopteryx / JalviewAptxBinding.java
1 package jalview.ext.archaeopteryx;
2
3 import jalview.datamodel.ColumnSelection;
4 import jalview.datamodel.HiddenColumns;
5 import jalview.datamodel.SequenceGroup;
6 import jalview.datamodel.SequenceI;
7 import jalview.gui.PaintRefresher;
8 import jalview.structure.SelectionSource;
9 import jalview.structure.StructureSelectionManager;
10 import jalview.viewmodel.AlignmentViewport;
11
12 import java.awt.event.ActionEvent;
13 import java.awt.event.InputEvent;
14 import java.awt.event.MouseEvent;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Map;
18
19 import org.forester.archaeopteryx.MainFrame;
20 import org.forester.phylogeny.PhylogenyMethods;
21 import org.forester.phylogeny.PhylogenyNode;
22
23 /**
24  * Class for binding the Archaeopteryx tree viewer to the Jalview alignment that
25  * it originates from, meaning that selecting sequences in the tree viewer also
26  * selects them in the alignment view and vice versa.
27  * 
28  * @author kjvanderheide
29  *
30  */
31 public final class JalviewAptxBinding implements JalviewTreeViewerBindingI
32 {
33   private org.forester.archaeopteryx.TreePanel treeView;
34
35   private AlignmentViewport parentAvport;
36
37   private final StructureSelectionManager ssm;
38
39   private Map<SequenceI, PhylogenyNode> sequencesBoundToNodes;
40
41   private Map<PhylogenyNode, SequenceI> nodesBoundToSequences;
42
43   /**
44    * 
45    * @param archaeopteryx
46    * 
47    * @param jalviewAlignmentViewport
48    *          alignment viewport from which the tree was calculated.
49    * 
50    * @param alignMappedToNodes
51    *          map with sequences used to calculate the tree and matching tree
52    *          nodes as key, value pair respectively.
53    * 
54    * @param nodesMappedToAlign
55    *          map with tree nodes and matching sequences used to calculate the
56    *          tree as key, value pair respectively.
57    */
58   public JalviewAptxBinding(final MainFrame archaeopteryx,
59           final AlignmentViewport jalviewAlignmentViewport,
60           final Map<SequenceI, PhylogenyNode> alignMappedToNodes,
61           final Map<PhylogenyNode, SequenceI> nodesMappedToAlign)
62   {
63     // deal with/prohibit null values here as that will cause problems
64     parentAvport = jalviewAlignmentViewport;
65     sequencesBoundToNodes = alignMappedToNodes;
66     nodesBoundToSequences = nodesMappedToAlign;
67     treeView = archaeopteryx.getMainPanel().getCurrentTreePanel();
68     ssm = parentAvport.getStructureSelectionManager();
69     ssm.addSelectionListener(this);
70     treeView.addMouseListener(this);
71     PaintRefresher.Register(treeView, parentAvport.getSequenceSetId());
72
73   }
74
75   @Override
76   public void actionPerformed(ActionEvent e)
77   {
78   }
79
80   @Override
81   public void mouseClicked(MouseEvent e)
82   {
83   }
84
85   @Override
86   public void mousePressed(final MouseEvent e)
87   {
88     showNodeSelectionOnAlign(e);
89   }
90
91   @Override
92   public void mouseReleased(MouseEvent e)
93   {
94   }
95
96   @Override
97   public void mouseEntered(MouseEvent e)
98   {
99   }
100
101   @Override
102   public void mouseExited(MouseEvent e)
103   {
104   }
105
106
107   @Override
108   public void selection(final SequenceGroup seqsel,
109           final ColumnSelection colsel, final HiddenColumns hidden,
110           final SelectionSource source)
111   {
112     if (source == parentAvport) // check if source is alignment from where the
113     // tree originates
114     {
115       treeView.setFoundNodes0(
116               new HashSet<Long>(seqsel.getSequences().size()));
117
118       for (SequenceI selectedSequence : seqsel.getSequences())
119       {
120         PhylogenyNode matchingNode = sequencesBoundToNodes.get(selectedSequence);
121         if (matchingNode != null)
122         {
123           treeView.getFoundNodes0().add(matchingNode.getId());
124         }
125
126       }
127       PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
128
129     }
130
131
132   }
133
134   /**
135    * If a node is selected in the tree panel this method highlights the
136    * corresponding sequence in the Jalview alignment view. If an internal node
137    * is selected all child sequences get highlighted as well.
138    */
139   @Override
140   public void showNodeSelectionOnAlign(final MouseEvent e)
141   {
142     final PhylogenyNode node = treeView.findNode(e.getX(), e.getY());
143     if (node != null)
144     {
145       if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) // clear previous
146       // selection if shift
147       // IS NOT pressed
148       {
149         parentAvport.setSelectionGroup(null);
150       }
151
152       if (node.isInternal())
153       {
154         showMatchingChildSequences(node);
155
156       }
157       else
158       {
159         showMatchingSequence(node);
160
161       }
162
163     }
164   }
165
166
167
168
169   public void showMatchingSequence(final PhylogenyNode nodeToMatch)
170   {
171     SequenceI matchingSequence = nodesBoundToSequences.get(nodeToMatch);
172     if (matchingSequence != null)
173     {
174       treeSelectionChanged(matchingSequence);
175       parentAvport.sendSelection();
176       PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
177     }
178   }
179
180   public void showMatchingChildSequences(final PhylogenyNode parentNode)
181   {
182     final List<PhylogenyNode> childNodes = PhylogenyMethods
183             .getAllDescendants(parentNode);
184
185     for (PhylogenyNode childNode : childNodes)
186     {
187       SequenceI matchingSequence = nodesBoundToSequences.get(childNode);
188       if (matchingSequence != null)
189       {
190         treeSelectionChanged(matchingSequence);
191       }
192     }
193
194     parentAvport.sendSelection();
195     PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
196   }
197
198   /**
199    * Refactored from TreeCanvas.
200    * 
201    * @param sequence
202    *          of the node selected in the tree viewer.
203    */
204   public void treeSelectionChanged(final SequenceI sequence)
205   {
206     SequenceGroup selected = parentAvport.getSelectionGroup();
207
208     if (selected == null)
209     {
210       selected = new SequenceGroup();
211       parentAvport.setSelectionGroup(selected);
212     }
213
214     selected.setEndRes(parentAvport.getAlignment().getWidth() - 1);
215     selected.addOrRemove(sequence, true);
216
217   }
218
219   public AlignmentViewport getParentAvport()
220   {
221     return parentAvport;
222   }
223
224   public void setParentAvport(final AlignmentViewport parentAvport)
225   {
226     this.parentAvport = parentAvport;
227   }
228
229 }
230
231
232