17298ba37e40509216c15237ee61fe2e7df5b69f
[jalview.git] / src / jalview / gui / AnnotationRowFilter.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import jalview.datamodel.AlignmentAnnotation;
24 import jalview.datamodel.GraphLine;
25 import jalview.datamodel.SequenceGroup;
26 import jalview.schemes.AnnotationColourGradient;
27 import jalview.util.MessageManager;
28
29 import java.awt.event.ActionEvent;
30 import java.awt.event.MouseAdapter;
31 import java.awt.event.MouseEvent;
32 import java.util.Vector;
33
34 import javax.swing.JButton;
35 import javax.swing.JCheckBox;
36 import javax.swing.JComboBox;
37 import javax.swing.JInternalFrame;
38 import javax.swing.JPanel;
39 import javax.swing.JSlider;
40 import javax.swing.JTextField;
41 import javax.swing.event.ChangeEvent;
42 import javax.swing.event.ChangeListener;
43
44 @SuppressWarnings("serial")
45 public abstract class AnnotationRowFilter extends JPanel
46 {
47   protected AlignViewport av;
48
49   protected AlignmentPanel ap;
50
51   protected int[] annmap;
52
53   protected boolean enableSeqAss = false;
54
55   private jalview.datamodel.AlignmentAnnotation currentAnnotation;
56
57   protected boolean adjusting = false;
58
59   protected JCheckBox currentColours = new JCheckBox();
60
61   protected JPanel minColour = new JPanel();
62
63   protected JPanel maxColour = new JPanel();
64
65   protected JCheckBox seqAssociated = new JCheckBox();
66
67   protected JCheckBox thresholdIsMin = new JCheckBox();
68
69   protected JSlider slider = new JSlider();
70
71   protected JTextField thresholdValue = new JTextField(20);
72
73   protected JInternalFrame frame;
74
75   protected JButton ok = new JButton();
76
77   protected JButton cancel = new JButton();
78
79   /**
80    * enabled if the user is dragging the slider - try to keep updates to a
81    * minimun
82    */
83   protected boolean sliderDragging = false;
84
85   protected void addSliderChangeListener()
86   {
87
88     slider.addChangeListener(new ChangeListener()
89     {
90       @Override
91       public void stateChanged(ChangeEvent evt)
92       {
93         if (!adjusting)
94         {
95           thresholdValue.setText((slider.getValue() / 1000f) + "");
96           valueChanged(!sliderDragging);
97         }
98       }
99     });
100   }
101
102   protected void addSliderMouseListeners()
103   {
104
105     slider.addMouseListener(new MouseAdapter()
106     {
107       @Override
108       public void mousePressed(MouseEvent e)
109       {
110         sliderDragging = true;
111         super.mousePressed(e);
112       }
113
114       @Override
115       public void mouseDragged(MouseEvent e)
116       {
117         sliderDragging = true;
118         super.mouseDragged(e);
119       }
120
121       @Override
122       public void mouseReleased(MouseEvent evt)
123       {
124         if (sliderDragging)
125         {
126           sliderDragging = false;
127           valueChanged(true);
128         }
129         ap.paintAlignment(true);
130       }
131     });
132   }
133
134   public AnnotationRowFilter(AlignViewport av, final AlignmentPanel ap)
135   {
136     this.av = av;
137     this.ap = ap;
138   }
139
140   public AnnotationRowFilter()
141   {
142
143   }
144
145   public Vector<String> getAnnotationItems(boolean isSeqAssociated)
146   {
147     Vector<String> list = new Vector<String>();
148     int index = 1;
149     int[] anmap = new int[av.getAlignment().getAlignmentAnnotation().length];
150     for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
151     {
152       if (av.getAlignment().getAlignmentAnnotation()[i].sequenceRef == null)
153       {
154         if (isSeqAssociated)
155         {
156           continue;
157         }
158       }
159       else
160       {
161         enableSeqAss = true;
162       }
163       String label = av.getAlignment().getAlignmentAnnotation()[i].label;
164       if (!list.contains(label))
165       {
166         anmap[list.size()] = i;
167         list.add(label);
168
169       }
170       else
171       {
172         if (!isSeqAssociated)
173         {
174           anmap[list.size()] = i;
175           list.add(label + "_" + (index++));
176         }
177       }
178     }
179     this.annmap = new int[list.size()];
180     System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length);
181     return list;
182   }
183
184   protected int getSelectedThresholdItem(int indexValue)
185   {
186     int selectedThresholdItem = -1;
187     if (indexValue == 1)
188     {
189       selectedThresholdItem = AnnotationColourGradient.ABOVE_THRESHOLD;
190     }
191     else if (indexValue == 2)
192     {
193       selectedThresholdItem = AnnotationColourGradient.BELOW_THRESHOLD;
194     }
195     return selectedThresholdItem;
196   }
197
198   public void modelChanged()
199   {
200     seqAssociated.setEnabled(enableSeqAss);
201   }
202
203   public void ok_actionPerformed(ActionEvent e)
204   {
205     try
206     {
207       frame.setClosed(true);
208     } catch (Exception ex)
209     {
210     }
211   }
212
213   public void cancel_actionPerformed(ActionEvent e)
214   {
215     reset();
216     ap.paintAlignment(true);
217     try
218     {
219       frame.setClosed(true);
220     } catch (Exception ex)
221     {
222     }
223   }
224
225   public void thresholdCheck_actionPerformed(ActionEvent e)
226   {
227     updateView();
228   }
229
230   public void annotations_actionPerformed(ActionEvent e)
231   {
232     updateView();
233   }
234
235   public void threshold_actionPerformed(ActionEvent e)
236   {
237     updateView();
238   }
239
240   public void thresholdValue_actionPerformed(ActionEvent e)
241   {
242     try
243     {
244       float f = Float.parseFloat(thresholdValue.getText());
245       slider.setValue((int) (f * 1000));
246       updateView();
247     } catch (NumberFormatException ex)
248     {
249     }
250   }
251
252   public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
253   {
254     updateView();
255   }
256
257   protected void populateThresholdComboBox(JComboBox<String> threshold)
258   {
259     threshold.addItem(MessageManager
260             .getString("label.threshold_feature_no_thereshold"));
261     threshold.addItem(MessageManager
262             .getString("label.threshold_feature_above_thereshold"));
263     threshold.addItem(MessageManager
264             .getString("label.threshold_feature_below_thereshold"));
265   }
266
267   protected void seqAssociated_actionPerformed(ActionEvent arg0,
268           JComboBox<String> annotations, JCheckBox seqAssociated)
269   {
270     adjusting = true;
271     String cursel = (String) annotations.getSelectedItem();
272     boolean isvalid = false, isseqs = seqAssociated.isSelected();
273     annotations.removeAllItems();
274     for (String anitem : getAnnotationItems(seqAssociated.isSelected()))
275     {
276       if (anitem.equals(cursel) || (isseqs && cursel.startsWith(anitem)))
277       {
278         isvalid = true;
279         cursel = anitem;
280       }
281       annotations.addItem(anitem);
282     }
283     adjusting = false;
284     if (isvalid)
285     {
286       annotations.setSelectedItem(cursel);
287     }
288     else
289     {
290       if (annotations.getItemCount() > 0)
291       {
292         annotations.setSelectedIndex(0);
293       }
294     }
295   }
296
297   protected void propagateSeqAssociatedThreshold(boolean allAnnotation,
298           AlignmentAnnotation annotation)
299   {
300     if (annotation.sequenceRef == null || annotation.threshold == null)
301     {
302       return;
303     }
304
305     float thr = annotation.threshold.value;
306     for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
307     {
308       AlignmentAnnotation aa = av.getAlignment().getAlignmentAnnotation()[i];
309       if (aa.label.equals(annotation.label)
310               && (annotation.getCalcId() == null ? aa.getCalcId() == null
311                       : annotation.getCalcId().equals(aa.getCalcId())))
312       {
313         if (aa.threshold == null)
314         {
315           aa.threshold = new GraphLine(annotation.threshold);
316         }
317         else
318         {
319           aa.threshold.value = thr;
320         }
321       }
322     }
323   }
324
325   protected boolean colorAlignmContaining(
326           AlignmentAnnotation currentAnnotation, int selectedThresholdItem)
327   {
328
329     AnnotationColourGradient acg = null;
330     if (currentColours.isSelected())
331     {
332       acg = new AnnotationColourGradient(currentAnnotation,
333               av.getGlobalColourScheme(), selectedThresholdItem);
334     }
335     else
336     {
337       acg = new AnnotationColourGradient(currentAnnotation,
338               minColour.getBackground(), maxColour.getBackground(),
339               selectedThresholdItem);
340     }
341     acg.setSeqAssociated(seqAssociated.isSelected());
342
343     if (currentAnnotation.graphMin == 0f
344             && currentAnnotation.graphMax == 0f)
345     {
346       acg.setPredefinedColours(true);
347     }
348
349     acg.thresholdIsMinMax = thresholdIsMin.isSelected();
350
351     av.setGlobalColourScheme(acg);
352
353     if (av.getAlignment().getGroups() != null)
354     {
355
356       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
357       {
358         if (sg.cs == null)
359         {
360           continue;
361         }
362
363         if (currentColours.isSelected())
364         {
365           sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs,
366                   selectedThresholdItem);
367           ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
368                   .isSelected());
369
370         }
371         else
372         {
373           sg.cs = new AnnotationColourGradient(currentAnnotation,
374                   minColour.getBackground(), maxColour.getBackground(),
375                   selectedThresholdItem);
376           ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
377                   .isSelected());
378         }
379
380       }
381     }
382     return false;
383   }
384
385   public jalview.datamodel.AlignmentAnnotation getCurrentAnnotation()
386   {
387     return currentAnnotation;
388   }
389
390   public void setCurrentAnnotation(
391           jalview.datamodel.AlignmentAnnotation currentAnnotation)
392   {
393     this.currentAnnotation = currentAnnotation;
394   }
395
396   public abstract void valueChanged(boolean updateAllAnnotation);
397
398   public abstract void updateView();
399
400   public abstract void reset();
401 }