JAL-1553 enhancement of column selection by annotation row to include the query filte...
[jalview.git] / src / jalview / gui / AnnotationColumnChooser.java
1 package jalview.gui;
2
3 import jalview.datamodel.AlignmentAnnotation;
4 import jalview.datamodel.AnnotationFilterParameter;
5 import jalview.datamodel.ColumnSelection;
6 import jalview.jbgui.FurtherActionPanel;
7 import jalview.jbgui.SearchPanel;
8 import jalview.jbgui.StructureFilterPanel;
9 import jalview.schemes.AnnotationColourGradient;
10 import jalview.util.MessageManager;
11
12 import java.awt.BorderLayout;
13 import java.awt.CardLayout;
14 import java.awt.Color;
15 import java.awt.Dimension;
16 import java.awt.event.ActionEvent;
17 import java.awt.event.ActionListener;
18 import java.awt.event.ItemEvent;
19 import java.awt.event.ItemListener;
20 import java.util.Iterator;
21
22 import javax.swing.JButton;
23 import javax.swing.JComboBox;
24 import javax.swing.JInternalFrame;
25 import javax.swing.JLabel;
26 import javax.swing.JLayeredPane;
27 import javax.swing.JPanel;
28 import javax.swing.JRadioButton;
29 import javax.swing.border.TitledBorder;
30
31 import net.miginfocom.swing.MigLayout;
32
33 @SuppressWarnings("serial")
34 public class AnnotationColumnChooser extends AnnotationRowFilter implements
35         ItemListener
36 {
37
38   private ColumnSelection oldColumnSelection;
39
40   private JComboBox<String> annotations;
41
42   JButton ok = new JButton();
43
44   JButton cancel = new JButton();
45
46   JPanel actionPanel = new JPanel();
47
48   JPanel thresholdPanel = new JPanel();
49
50   JPanel switchableViewsPanel = new JPanel(new CardLayout());
51
52   CardLayout switchableViewsLayout = (CardLayout) (switchableViewsPanel
53           .getLayout());
54
55   JPanel noGraphFilterView = new JPanel();
56
57   JPanel graphFilterView = new JPanel();
58
59   JPanel annotationComboBoxPanel = new JPanel();
60
61   StructureFilterPanel gStructureFilterPanel;
62
63   StructureFilterPanel ngStructureFilterPanel;
64
65   private StructureFilterPanel currentStructureFilterPanel;
66
67   JLabel annotationLabel = new JLabel();
68
69   BorderLayout borderLayout1 = new BorderLayout();
70
71   private JComboBox<String> threshold = new JComboBox<String>();
72
73   private SearchPanel currentSearchPanel;
74
75   private SearchPanel gSearchPanel;
76
77   private SearchPanel ngSearchPanel;
78
79   private FurtherActionPanel currentFurtherActionPanel;
80
81   private FurtherActionPanel gFurtherActionPanel;
82
83   private FurtherActionPanel ngFurtherActionPanel;
84
85   public static final int ACTION_OPTION_SELECT = 1;
86
87   public static int ACTION_OPTION_HIDE = 2;
88
89   public static String NO_GRAPH_VIEW = "0";
90
91   public static String GRAPH_VIEW = "1";
92
93   private int actionOption = ACTION_OPTION_SELECT;
94
95   public AnnotationColumnChooser(AlignViewport av, final AlignmentPanel ap)
96   {
97     super(av, ap);
98     frame = new JInternalFrame();
99     frame.setContentPane(this);
100     frame.setLayer(JLayeredPane.PALETTE_LAYER);
101     Desktop.addInternalFrame(frame,
102             MessageManager.getString("label.select_by_annotation"), 520,
103             215);
104
105     addSliderChangeListener();
106     addSliderMouseListeners();
107
108     if (av.getAlignment().getAlignmentAnnotation() == null)
109     {
110       return;
111     }
112     setOldColumnSelection(av.getColumnSelection());
113     adjusting = true;
114
115     setAnnotations(new JComboBox<String>(getAnnotationItems(false)));
116     populateThresholdComboBox(threshold);
117
118     // restore the Object state from the previous session if one exists
119     if (av.getAnnotationColumnSelectionState() != null)
120     {
121       currentSearchPanel = av.getAnnotationColumnSelectionState()
122               .getCurrentSearchPanel();
123       currentStructureFilterPanel = av.getAnnotationColumnSelectionState()
124               .getCurrentStructureFilterPanel();
125       annotations.setSelectedIndex(av.getAnnotationColumnSelectionState()
126               .getAnnotations().getSelectedIndex());
127       threshold.setSelectedIndex(av.getAnnotationColumnSelectionState()
128               .getThreshold().getSelectedIndex());
129       actionOption = av.getAnnotationColumnSelectionState()
130               .getActionOption();
131
132     }
133
134     try
135     {
136       jbInit();
137     } catch (Exception ex)
138     {
139     }
140     adjusting = false;
141
142     updateView();
143     frame.invalidate();
144     frame.pack();
145   }
146
147   public AnnotationColumnChooser()
148   {
149     try
150     {
151       jbInit();
152     } catch (Exception ex)
153     {
154       ex.printStackTrace();
155     }
156   }
157
158   private void jbInit() throws Exception
159   {
160     ok.setOpaque(false);
161     ok.setText(MessageManager.getString("action.ok"));
162     ok.addActionListener(new ActionListener()
163     {
164       @Override
165       public void actionPerformed(ActionEvent e)
166       {
167         ok_actionPerformed(e);
168       }
169     });
170     cancel.setOpaque(false);
171     cancel.setText(MessageManager.getString("action.cancel"));
172     cancel.addActionListener(new ActionListener()
173     {
174       @Override
175       public void actionPerformed(ActionEvent e)
176       {
177         cancel_actionPerformed(e);
178       }
179     });
180
181     getAnnotations().addItemListener(this);
182     getThreshold().addActionListener(new ActionListener()
183     {
184       @Override
185       public void actionPerformed(ActionEvent e)
186       {
187         threshold_actionPerformed(e);
188       }
189     });
190
191     thresholdValue.addActionListener(new ActionListener()
192     {
193       @Override
194       public void actionPerformed(ActionEvent e)
195       {
196         thresholdValue_actionPerformed(e);
197       }
198     });
199     slider.setPaintLabels(false);
200     slider.setPaintTicks(true);
201     slider.setBackground(Color.white);
202     slider.setEnabled(false);
203     slider.setOpaque(false);
204     slider.setPreferredSize(new Dimension(100, 32));
205     thresholdValue.setEnabled(false);
206     thresholdValue.setColumns(7);
207
208     annotationLabel.setBackground(Color.white);
209     annotationLabel.setFont(JvSwingUtils.getLabelFont());
210     annotationLabel.setText("Select Annotation : ");
211
212     thresholdPanel.setBorder(new TitledBorder("Threshold Filter"));
213     thresholdPanel.setBackground(Color.white);
214     thresholdPanel.setFont(JvSwingUtils.getLabelFont());
215     thresholdPanel.setLayout(new MigLayout("", "[left][right]", "[][]"));
216
217     actionPanel.setBackground(Color.white);
218     actionPanel.setFont(JvSwingUtils.getLabelFont());
219
220     this.setLayout(borderLayout1);
221     graphFilterView.setLayout(new MigLayout("", "[left][right]", "[][]"));
222     graphFilterView.setBackground(Color.white);
223
224     noGraphFilterView.setLayout(new MigLayout("", "[left][right]", "[][]"));
225     noGraphFilterView.setBackground(Color.white);
226     annotationComboBoxPanel.setBackground(Color.white);
227     annotationComboBoxPanel.setFont(JvSwingUtils.getLabelFont());
228
229     gSearchPanel = new SearchPanel(this);
230     ngSearchPanel = new SearchPanel(this);
231     gFurtherActionPanel = new FurtherActionPanel(this);
232     ngFurtherActionPanel = new FurtherActionPanel(this);
233     gStructureFilterPanel = new StructureFilterPanel(this);
234     ngStructureFilterPanel = new StructureFilterPanel(this);
235
236
237     thresholdPanel.add(getThreshold());
238     thresholdPanel.add(thresholdValue, "wrap");
239     thresholdPanel.add(slider, "grow, span, wrap");
240
241     actionPanel.add(ok);
242     actionPanel.add(cancel);
243
244     graphFilterView.add(gSearchPanel, "grow, span, wrap");
245     graphFilterView.add(gStructureFilterPanel, "grow, span, wrap");
246     graphFilterView.add(thresholdPanel, "grow, span, wrap");
247     graphFilterView.add(gFurtherActionPanel);
248
249     noGraphFilterView.add(ngSearchPanel, "grow, span, wrap");
250     noGraphFilterView.add(ngStructureFilterPanel, "grow, span, wrap");
251     noGraphFilterView.add(ngFurtherActionPanel);
252
253     annotationComboBoxPanel.add(getAnnotations());
254     switchableViewsPanel.add(noGraphFilterView,
255             AnnotationColumnChooser.NO_GRAPH_VIEW);
256     switchableViewsPanel.add(graphFilterView,
257             AnnotationColumnChooser.GRAPH_VIEW);
258
259     this.add(annotationComboBoxPanel, java.awt.BorderLayout.PAGE_START);
260     this.add(switchableViewsPanel, java.awt.BorderLayout.CENTER);
261     this.add(actionPanel, java.awt.BorderLayout.SOUTH);
262
263     selectedAnnotationChanged();
264     this.validate();
265   }
266
267   @SuppressWarnings("unchecked")
268   public void reset()
269   {
270     if (this.getOldColumnSelection() != null)
271     {
272       av.getColumnSelection().clear();
273
274       if (av.getAnnotationColumnSelectionState() != null)
275       {
276         ColumnSelection oldSelection = av
277                 .getAnnotationColumnSelectionState()
278                 .getOldColumnSelection();
279         if (oldSelection != null && oldSelection.getHiddenColumns() != null
280                 && !oldSelection.getHiddenColumns().isEmpty())
281         {
282           for (Iterator<int[]> itr = oldSelection.getHiddenColumns()
283                   .iterator(); itr.hasNext();)
284           {
285             int positions[] = itr.next();
286             av.hideColumns(positions[0], positions[1]);
287           }
288         }
289         av.setColumnSelection(oldSelection);
290       }
291       // ap.alignmentChanged();
292       ap.paintAlignment(true);
293     }
294
295   }
296
297   public void valueChanged(boolean updateAllAnnotation)
298   {
299     if (slider.isEnabled())
300     {
301       getCurrentAnnotation().threshold.value = slider.getValue() / 1000f;
302       updateView();
303       propagateSeqAssociatedThreshold(updateAllAnnotation,
304               getCurrentAnnotation());
305       ap.paintAlignment(false);
306     }
307   }
308
309   public JComboBox<String> getThreshold()
310   {
311     return threshold;
312   }
313
314   public void setThreshold(JComboBox<String> threshold)
315   {
316     this.threshold = threshold;
317   }
318
319   public JComboBox<String> getAnnotations()
320   {
321     return annotations;
322   }
323
324   public void setAnnotations(JComboBox<String> annotations)
325   {
326     this.annotations = annotations;
327   }
328
329   @Override
330   public void updateView()
331   {
332     // Check if combobox is still adjusting
333     if (adjusting)
334     {
335       return;
336     }
337
338     AnnotationFilterParameter filterParams = new AnnotationFilterParameter();
339
340     setCurrentAnnotation(av.getAlignment().getAlignmentAnnotation()[annmap[getAnnotations()
341             .getSelectedIndex()]]);
342
343     int selectedThresholdItem = getSelectedThresholdItem(getThreshold()
344             .getSelectedIndex());
345
346     slider.setEnabled(true);
347     thresholdValue.setEnabled(true);
348
349     if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD)
350     {
351       slider.setEnabled(false);
352       thresholdValue.setEnabled(false);
353       thresholdValue.setText("");
354       // build filter params
355     }
356     else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD)
357     {
358       if (getCurrentAnnotation().threshold == null)
359       {
360         getCurrentAnnotation()
361                 .setThreshold(
362                         new jalview.datamodel.GraphLine(
363                                 (getCurrentAnnotation().graphMax - getCurrentAnnotation().graphMin) / 2f,
364                                 "Threshold", Color.black));
365       }
366
367       adjusting = true;
368       float range = getCurrentAnnotation().graphMax * 1000
369               - getCurrentAnnotation().graphMin * 1000;
370
371       slider.setMinimum((int) (getCurrentAnnotation().graphMin * 1000));
372       slider.setMaximum((int) (getCurrentAnnotation().graphMax * 1000));
373       slider.setValue((int) (getCurrentAnnotation().threshold.value * 1000));
374       thresholdValue.setText(getCurrentAnnotation().threshold.value + "");
375       slider.setMajorTickSpacing((int) (range / 10f));
376       slider.setEnabled(true);
377       thresholdValue.setEnabled(true);
378       adjusting = false;
379
380       // build filter params
381       filterParams
382               .setThresholdType(AnnotationFilterParameter.ThresholdType.NO_THRESHOLD);
383       if (getCurrentAnnotation().graph != AlignmentAnnotation.NO_GRAPH)
384       {
385
386         if (selectedThresholdItem == AnnotationColourGradient.ABOVE_THRESHOLD)
387         {
388           filterParams
389                   .setThresholdType(AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD);
390         }
391         else if (selectedThresholdItem == AnnotationColourGradient.BELOW_THRESHOLD)
392         {
393           filterParams
394                   .setThresholdType(AnnotationFilterParameter.ThresholdType.BELOW_THRESHOLD);
395         }
396       }
397     }
398
399     if (currentStructureFilterPanel != null)
400     {
401       if (currentStructureFilterPanel.getAlphaHelix().isSelected())
402       {
403         filterParams.setFilterAlphaHelix(true);
404       }
405       if (currentStructureFilterPanel.getBetaStrand().isSelected())
406       {
407         filterParams.setFilterBetaSheet(true);
408       }
409       if (currentStructureFilterPanel.getTurn().isSelected())
410       {
411         filterParams.setFilterTurn(true);
412       }
413     }
414
415     if (currentSearchPanel != null)
416     {
417       if (!currentSearchPanel.getSearchString().isEmpty())
418       {
419         currentSearchPanel.getDescription().setEnabled(true);
420         currentSearchPanel.getDisplayName().setEnabled(true);
421         filterParams.setRegexString(currentSearchPanel.getSearchString());
422         if (currentSearchPanel.isDisplayNameChecked())
423         {
424           filterParams
425                   .addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DISPLAY_STRING);
426         }
427         if (currentSearchPanel.isDescriptionChecked())
428         {
429           filterParams
430                   .addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DESCRIPTION);
431         }
432       }
433       else
434       {
435         currentSearchPanel.getDescription().setEnabled(false);
436         currentSearchPanel.getDisplayName().setEnabled(false);
437       }
438     }
439
440     filterAnnotations(getCurrentAnnotation().annotations, filterParams,
441             av.getColumnSelection());
442
443     av.showAllHiddenColumns();
444     if (getActionOption() == ACTION_OPTION_HIDE)
445     {
446       av.hideSelectedColumns();
447     }
448
449     filterParams = null;
450     av.setAnnotationColumnSelectionState(this);
451     ap.paintAlignment(true);
452   }
453
454   public ColumnSelection getOldColumnSelection()
455   {
456     return oldColumnSelection;
457   }
458
459   public void setOldColumnSelection(ColumnSelection currentColumnSelection)
460   {
461     if (currentColumnSelection != null)
462     {
463       this.oldColumnSelection = new ColumnSelection(currentColumnSelection);
464     }
465   }
466
467
468   public void select_action(ActionEvent actionEvent)
469   {
470     JRadioButton radioButton = (JRadioButton) actionEvent.getSource();
471     if (radioButton.isSelected())
472     {
473       setActionOption(ACTION_OPTION_SELECT);
474       updateView();
475     }
476   }
477
478   public void hide_action(ActionEvent actionEvent)
479   {
480     JRadioButton radioButton = (JRadioButton) actionEvent.getSource();
481     if (radioButton.isSelected())
482     {
483       setActionOption(ACTION_OPTION_HIDE);
484       updateView();
485     }
486   }
487
488
489   @Override
490   public void itemStateChanged(ItemEvent e)
491   {
492     selectedAnnotationChanged();
493   }
494
495   public void selectedAnnotationChanged()
496   {
497     String currentView = AnnotationColumnChooser.NO_GRAPH_VIEW;
498     if (av.getAlignment().getAlignmentAnnotation()[annmap[getAnnotations()
499             .getSelectedIndex()]].graph != AlignmentAnnotation.NO_GRAPH)
500     {
501       currentView = AnnotationColumnChooser.GRAPH_VIEW;
502     }
503     // else{
504     // threshold.setSelectedIndex(AlignmentAnnotation.NO_GRAPH);
505     // }
506     
507     gSearchPanel.syncState();
508     gFurtherActionPanel.syncState();
509     gFurtherActionPanel.syncState();
510     gFurtherActionPanel.syncState();
511
512     ngSearchPanel.syncState();
513     ngFurtherActionPanel.syncState();
514     ngStructureFilterPanel.syncState();
515     ngFurtherActionPanel.syncState();
516
517     switchableViewsLayout.show(switchableViewsPanel, currentView);
518     updateView();
519   }
520
521   
522   public FurtherActionPanel getCurrentFutherActionPanel()
523   {
524     return currentFurtherActionPanel;
525   }
526
527   public void setCurrentFutherActionPanel(
528           FurtherActionPanel currentFutherActionPanel)
529   {
530     this.currentFurtherActionPanel = currentFutherActionPanel;
531   }
532
533   public SearchPanel getCurrentSearchPanel()
534   {
535     return currentSearchPanel;
536   }
537
538   public void setCurrentSearchPanel(SearchPanel currentSearchPanel)
539   {
540     this.currentSearchPanel = currentSearchPanel;
541   }
542
543   public int getActionOption()
544   {
545     return actionOption;
546   }
547
548   public void setActionOption(int actionOption)
549   {
550     this.actionOption = actionOption;
551   }
552
553   public StructureFilterPanel getCurrentStructureFilterPanel()
554   {
555     return currentStructureFilterPanel;
556   }
557
558   public void setCurrentStructureFilterPanel(
559           StructureFilterPanel currentStructureFilterPanel)
560   {
561     this.currentStructureFilterPanel = currentStructureFilterPanel;
562   }
563
564 }