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