JAL-2089 patch broken merge to master for Release 2.10.0b1
[jalview.git] / src / jalview / gui / AnnotationColumnChooser.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
22 package jalview.gui;
23
24 import jalview.datamodel.AlignmentAnnotation;
25 import jalview.datamodel.ColumnSelection;
26 import jalview.schemes.AnnotationColourGradient;
27 import jalview.util.MessageManager;
28 import jalview.viewmodel.annotationfilter.AnnotationFilterParameter;
29
30 import java.awt.BorderLayout;
31 import java.awt.CardLayout;
32 import java.awt.Color;
33 import java.awt.Dimension;
34 import java.awt.event.ActionEvent;
35 import java.awt.event.ActionListener;
36 import java.awt.event.ItemEvent;
37 import java.awt.event.ItemListener;
38 import java.util.Iterator;
39
40 import javax.swing.ButtonGroup;
41 import javax.swing.JCheckBox;
42 import javax.swing.JComboBox;
43 import javax.swing.JInternalFrame;
44 import javax.swing.JLayeredPane;
45 import javax.swing.JPanel;
46 import javax.swing.JRadioButton;
47 import javax.swing.JTextField;
48 import javax.swing.border.TitledBorder;
49 import javax.swing.event.DocumentEvent;
50 import javax.swing.event.DocumentListener;
51
52 import net.miginfocom.swing.MigLayout;
53
54 @SuppressWarnings("serial")
55 public class AnnotationColumnChooser extends AnnotationRowFilter implements
56         ItemListener
57 {
58
59   private JComboBox<String> annotations;
60
61   private JPanel actionPanel = new JPanel();
62
63   private JPanel thresholdPanel = new JPanel();
64
65   private JPanel switchableViewsPanel = new JPanel(new CardLayout());
66
67   private CardLayout switchableViewsLayout = (CardLayout) (switchableViewsPanel
68           .getLayout());
69
70   private JPanel noGraphFilterView = new JPanel();
71
72   private JPanel graphFilterView = new JPanel();
73
74   private JPanel annotationComboBoxPanel = new JPanel();
75
76   private BorderLayout borderLayout1 = new BorderLayout();
77
78   private JComboBox<String> threshold = new JComboBox<String>();
79
80   private StructureFilterPanel gStructureFilterPanel;
81
82   private StructureFilterPanel ngStructureFilterPanel;
83
84   private StructureFilterPanel currentStructureFilterPanel;
85
86   private SearchPanel currentSearchPanel;
87
88   private SearchPanel gSearchPanel;
89
90   private SearchPanel ngSearchPanel;
91
92   private FurtherActionPanel currentFurtherActionPanel;
93
94   private FurtherActionPanel gFurtherActionPanel;
95
96   private FurtherActionPanel ngFurtherActionPanel;
97
98   public static final int ACTION_OPTION_SELECT = 1;
99
100   public static int ACTION_OPTION_HIDE = 2;
101
102   public static String NO_GRAPH_VIEW = "0";
103
104   public static String GRAPH_VIEW = "1";
105
106   private int actionOption = ACTION_OPTION_SELECT;
107
108   private ColumnSelection oldColumnSelection;
109
110   public AnnotationColumnChooser()
111   {
112     try
113     {
114       jbInit();
115     } catch (Exception ex)
116     {
117       ex.printStackTrace();
118     }
119   }
120
121   public AnnotationColumnChooser(AlignViewport av, final AlignmentPanel ap)
122   {
123     super(av, ap);
124     frame = new JInternalFrame();
125     frame.setContentPane(this);
126     frame.setLayer(JLayeredPane.PALETTE_LAYER);
127     Desktop.addInternalFrame(frame,
128             MessageManager.getString("label.select_by_annotation"), 520,
129             215);
130
131     addSliderChangeListener();
132     addSliderMouseListeners();
133
134     if (av.getAlignment().getAlignmentAnnotation() == null)
135     {
136       return;
137     }
138     setOldColumnSelection(av.getColumnSelection());
139     adjusting = true;
140
141     setAnnotations(new JComboBox<String>(getAnnotationItems(false)));
142     populateThresholdComboBox(threshold);
143
144     // restore Object state from the previous session if one exists
145     if (av.getAnnotationColumnSelectionState() != null)
146     {
147       currentSearchPanel = av.getAnnotationColumnSelectionState()
148               .getCurrentSearchPanel();
149       currentStructureFilterPanel = av.getAnnotationColumnSelectionState()
150               .getCurrentStructureFilterPanel();
151       annotations.setSelectedIndex(av.getAnnotationColumnSelectionState()
152               .getAnnotations().getSelectedIndex());
153       threshold.setSelectedIndex(av.getAnnotationColumnSelectionState()
154               .getThreshold().getSelectedIndex());
155       actionOption = av.getAnnotationColumnSelectionState()
156               .getActionOption();
157     }
158
159     try
160     {
161       jbInit();
162     } catch (Exception ex)
163     {
164     }
165     adjusting = false;
166
167     updateView();
168     frame.invalidate();
169     frame.pack();
170   }
171
172   private void jbInit() throws Exception
173   {
174     ok.setOpaque(false);
175     ok.setText(MessageManager.getString("action.ok"));
176     ok.addActionListener(new ActionListener()
177     {
178       @Override
179       public void actionPerformed(ActionEvent e)
180       {
181         ok_actionPerformed();
182       }
183     });
184
185     cancel.setOpaque(false);
186     cancel.setText(MessageManager.getString("action.cancel"));
187     cancel.addActionListener(new ActionListener()
188     {
189       @Override
190       public void actionPerformed(ActionEvent e)
191       {
192         cancel_actionPerformed();
193       }
194     });
195
196     annotations.addItemListener(this);
197     annotations.setToolTipText(MessageManager
198             .getString("info.select_annotation_row"));
199     threshold.addActionListener(new ActionListener()
200     {
201       @Override
202       public void actionPerformed(ActionEvent e)
203       {
204         threshold_actionPerformed();
205       }
206     });
207
208     thresholdValue.setEnabled(false);
209     thresholdValue.setColumns(7);
210     thresholdValue.addActionListener(new ActionListener()
211     {
212       @Override
213       public void actionPerformed(ActionEvent e)
214       {
215         thresholdValue_actionPerformed();
216       }
217     });
218
219     slider.setPaintLabels(false);
220     slider.setPaintTicks(true);
221     slider.setBackground(Color.white);
222     slider.setEnabled(false);
223     slider.setOpaque(false);
224     slider.setPreferredSize(new Dimension(100, 32));
225
226     thresholdPanel.setBorder(new TitledBorder(MessageManager
227             .getString("label.threshold_filter")));
228     thresholdPanel.setBackground(Color.white);
229     thresholdPanel.setFont(JvSwingUtils.getLabelFont());
230     thresholdPanel.setLayout(new MigLayout("", "[left][right]", "[][]"));
231
232     actionPanel.setBackground(Color.white);
233     actionPanel.setFont(JvSwingUtils.getLabelFont());
234
235     graphFilterView.setLayout(new MigLayout("", "[left][right]", "[][]"));
236     graphFilterView.setBackground(Color.white);
237
238     noGraphFilterView.setLayout(new MigLayout("", "[left][right]", "[][]"));
239     noGraphFilterView.setBackground(Color.white);
240
241     annotationComboBoxPanel.setBackground(Color.white);
242     annotationComboBoxPanel.setFont(JvSwingUtils.getLabelFont());
243
244     gSearchPanel = new SearchPanel(this);
245     ngSearchPanel = new SearchPanel(this);
246     gFurtherActionPanel = new FurtherActionPanel(this);
247     ngFurtherActionPanel = new FurtherActionPanel(this);
248     gStructureFilterPanel = new StructureFilterPanel(this);
249     ngStructureFilterPanel = new StructureFilterPanel(this);
250
251     thresholdPanel.add(getThreshold());
252     thresholdPanel.add(thresholdValue, "wrap");
253     thresholdPanel.add(slider, "grow, span, wrap");
254
255     actionPanel.add(ok);
256     actionPanel.add(cancel);
257
258     graphFilterView.add(gSearchPanel, "grow, span, wrap");
259     graphFilterView.add(gStructureFilterPanel, "grow, span, wrap");
260     graphFilterView.add(thresholdPanel, "grow, span, wrap");
261     graphFilterView.add(gFurtherActionPanel);
262
263     noGraphFilterView.add(ngSearchPanel, "grow, span, wrap");
264     noGraphFilterView.add(ngStructureFilterPanel, "grow, span, wrap");
265     noGraphFilterView.add(ngFurtherActionPanel);
266
267     annotationComboBoxPanel.add(getAnnotations());
268     switchableViewsPanel.add(noGraphFilterView,
269             AnnotationColumnChooser.NO_GRAPH_VIEW);
270     switchableViewsPanel.add(graphFilterView,
271             AnnotationColumnChooser.GRAPH_VIEW);
272
273     this.setLayout(borderLayout1);
274     this.add(annotationComboBoxPanel, java.awt.BorderLayout.PAGE_START);
275     this.add(switchableViewsPanel, java.awt.BorderLayout.CENTER);
276     this.add(actionPanel, java.awt.BorderLayout.SOUTH);
277
278     selectedAnnotationChanged();
279     updateThresholdPanelToolTip();
280     this.validate();
281   }
282
283   public void updateThresholdPanelToolTip()
284   {
285     thresholdValue.setToolTipText("");
286     slider.setToolTipText("");
287
288     String defaultTtip = MessageManager
289             .getString("info.change_threshold_mode_to_enable");
290
291     String thresh = getThreshold().getSelectedItem().toString();
292     if (thresh.equalsIgnoreCase("No Threshold"))
293     {
294       thresholdValue.setToolTipText(defaultTtip);
295       slider.setToolTipText(defaultTtip);
296     }
297   }
298
299   @Override
300   public void reset()
301   {
302     if (this.getOldColumnSelection() != null)
303     {
304       av.getColumnSelection().clear();
305
306       if (av.getAnnotationColumnSelectionState() != null)
307       {
308         ColumnSelection oldSelection = av
309                 .getAnnotationColumnSelectionState()
310                 .getOldColumnSelection();
311         if (oldSelection != null && oldSelection.getHiddenColumns() != null
312                 && !oldSelection.getHiddenColumns().isEmpty())
313         {
314           for (Iterator<int[]> itr = oldSelection.getHiddenColumns()
315                   .iterator(); itr.hasNext();)
316           {
317             int positions[] = itr.next();
318             av.hideColumns(positions[0], positions[1]);
319           }
320         }
321         av.setColumnSelection(oldSelection);
322       }
323       ap.paintAlignment(true);
324     }
325
326   }
327
328   @Override
329   public void valueChanged(boolean updateAllAnnotation)
330   {
331     if (slider.isEnabled())
332     {
333       getCurrentAnnotation().threshold.value = slider.getValue() / 1000f;
334       updateView();
335       propagateSeqAssociatedThreshold(updateAllAnnotation,
336               getCurrentAnnotation());
337       ap.paintAlignment(false);
338     }
339   }
340
341   public JComboBox<String> getThreshold()
342   {
343     return threshold;
344   }
345
346   public void setThreshold(JComboBox<String> threshold)
347   {
348     this.threshold = threshold;
349   }
350
351   public JComboBox<String> getAnnotations()
352   {
353     return annotations;
354   }
355
356   public void setAnnotations(JComboBox<String> annotations)
357   {
358     this.annotations = annotations;
359   }
360
361   @Override
362   public void updateView()
363   {
364     // Check if combobox is still adjusting
365     if (adjusting)
366     {
367       return;
368     }
369
370     AnnotationFilterParameter filterParams = new AnnotationFilterParameter();
371
372     setCurrentAnnotation(av.getAlignment().getAlignmentAnnotation()[annmap[getAnnotations()
373             .getSelectedIndex()]]);
374
375     int selectedThresholdItem = getSelectedThresholdItem(getThreshold()
376             .getSelectedIndex());
377
378     slider.setEnabled(true);
379     thresholdValue.setEnabled(true);
380
381     if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD)
382     {
383       slider.setEnabled(false);
384       thresholdValue.setEnabled(false);
385       thresholdValue.setText("");
386       // build filter params
387     }
388     else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD)
389     {
390       if (getCurrentAnnotation().threshold == null)
391       {
392         getCurrentAnnotation()
393                 .setThreshold(
394                         new jalview.datamodel.GraphLine(
395                                 (getCurrentAnnotation().graphMax - getCurrentAnnotation().graphMin) / 2f,
396                                 "Threshold", Color.black));
397       }
398
399       adjusting = true;
400       float range = getCurrentAnnotation().graphMax * 1000
401               - getCurrentAnnotation().graphMin * 1000;
402
403       slider.setMinimum((int) (getCurrentAnnotation().graphMin * 1000));
404       slider.setMaximum((int) (getCurrentAnnotation().graphMax * 1000));
405       slider.setValue((int) (getCurrentAnnotation().threshold.value * 1000));
406       thresholdValue.setText(getCurrentAnnotation().threshold.value + "");
407       slider.setMajorTickSpacing((int) (range / 10f));
408       slider.setEnabled(true);
409       thresholdValue.setEnabled(true);
410       adjusting = false;
411
412       // build filter params
413       filterParams
414               .setThresholdType(AnnotationFilterParameter.ThresholdType.NO_THRESHOLD);
415       if (getCurrentAnnotation().graph != AlignmentAnnotation.NO_GRAPH)
416       {
417         filterParams
418                 .setThresholdValue(getCurrentAnnotation().threshold.value);
419
420         if (selectedThresholdItem == AnnotationColourGradient.ABOVE_THRESHOLD)
421         {
422           filterParams
423                   .setThresholdType(AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD);
424         }
425         else if (selectedThresholdItem == AnnotationColourGradient.BELOW_THRESHOLD)
426         {
427           filterParams
428                   .setThresholdType(AnnotationFilterParameter.ThresholdType.BELOW_THRESHOLD);
429         }
430       }
431     }
432
433     updateThresholdPanelToolTip();
434     if (currentStructureFilterPanel != null)
435     {
436       if (currentStructureFilterPanel.alphaHelix.isSelected())
437       {
438         filterParams.setFilterAlphaHelix(true);
439       }
440       if (currentStructureFilterPanel.betaStrand.isSelected())
441       {
442         filterParams.setFilterBetaSheet(true);
443       }
444       if (currentStructureFilterPanel.turn.isSelected())
445       {
446         filterParams.setFilterTurn(true);
447       }
448     }
449
450     if (currentSearchPanel != null)
451     {
452
453       if (!currentSearchPanel.searchBox.getText().isEmpty())
454       {
455         currentSearchPanel.description.setEnabled(true);
456         currentSearchPanel.displayName.setEnabled(true);
457         filterParams.setRegexString(currentSearchPanel.searchBox.getText());
458         if (currentSearchPanel.displayName.isSelected())
459         {
460           filterParams
461                   .addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DISPLAY_STRING);
462         }
463         if (currentSearchPanel.description.isSelected())
464         {
465           filterParams
466                   .addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DESCRIPTION);
467         }
468       }
469       else
470       {
471         currentSearchPanel.description.setEnabled(false);
472         currentSearchPanel.displayName.setEnabled(false);
473       }
474     }
475
476     av.getColumnSelection().filterAnnotations(
477             getCurrentAnnotation().annotations, filterParams);
478
479     av.showAllHiddenColumns();
480     if (getActionOption() == ACTION_OPTION_HIDE)
481     {
482       av.hideSelectedColumns();
483     }
484
485     filterParams = null;
486     av.setAnnotationColumnSelectionState(this);
487     ap.paintAlignment(true);
488   }
489
490   public ColumnSelection getOldColumnSelection()
491   {
492     return oldColumnSelection;
493   }
494
495   public void setOldColumnSelection(ColumnSelection currentColumnSelection)
496   {
497     if (currentColumnSelection != null)
498     {
499       this.oldColumnSelection = new ColumnSelection(currentColumnSelection);
500     }
501   }
502
503   public FurtherActionPanel getCurrentFutherActionPanel()
504   {
505     return currentFurtherActionPanel;
506   }
507
508   public void setCurrentFutherActionPanel(
509           FurtherActionPanel currentFutherActionPanel)
510   {
511     this.currentFurtherActionPanel = currentFutherActionPanel;
512   }
513
514   public SearchPanel getCurrentSearchPanel()
515   {
516     return currentSearchPanel;
517   }
518
519   public void setCurrentSearchPanel(SearchPanel currentSearchPanel)
520   {
521     this.currentSearchPanel = currentSearchPanel;
522   }
523
524   public int getActionOption()
525   {
526     return actionOption;
527   }
528
529   public void setActionOption(int actionOption)
530   {
531     this.actionOption = actionOption;
532   }
533
534   public StructureFilterPanel getCurrentStructureFilterPanel()
535   {
536     return currentStructureFilterPanel;
537   }
538
539   public void setCurrentStructureFilterPanel(
540           StructureFilterPanel currentStructureFilterPanel)
541   {
542     this.currentStructureFilterPanel = currentStructureFilterPanel;
543   }
544
545   public void select_action(ActionEvent actionEvent)
546   {
547     JRadioButton radioButton = (JRadioButton) actionEvent.getSource();
548     if (radioButton.isSelected())
549     {
550       setActionOption(ACTION_OPTION_SELECT);
551       updateView();
552     }
553   }
554
555   public void hide_action(ActionEvent actionEvent)
556   {
557     JRadioButton radioButton = (JRadioButton) actionEvent.getSource();
558     if (radioButton.isSelected())
559     {
560       setActionOption(ACTION_OPTION_HIDE);
561       updateView();
562     }
563   }
564
565   @Override
566   public void itemStateChanged(ItemEvent e)
567   {
568     selectedAnnotationChanged();
569   }
570
571   public void selectedAnnotationChanged()
572   {
573     String currentView = AnnotationColumnChooser.NO_GRAPH_VIEW;
574     if (av.getAlignment().getAlignmentAnnotation()[annmap[getAnnotations()
575             .getSelectedIndex()]].graph != AlignmentAnnotation.NO_GRAPH)
576     {
577       currentView = AnnotationColumnChooser.GRAPH_VIEW;
578     }
579
580     gSearchPanel.syncState();
581     gFurtherActionPanel.syncState();
582     gStructureFilterPanel.syncState();
583
584     ngSearchPanel.syncState();
585     ngFurtherActionPanel.syncState();
586     ngStructureFilterPanel.syncState();
587
588     switchableViewsLayout.show(switchableViewsPanel, currentView);
589     updateView();
590   }
591
592   public class FurtherActionPanel extends JPanel
593   {
594     private AnnotationColumnChooser aColChooser;
595
596     private JRadioButton hideOption = new JRadioButton();
597
598     private JRadioButton selectOption = new JRadioButton();
599
600     private ButtonGroup optionsGroup = new ButtonGroup();
601
602     public FurtherActionPanel(AnnotationColumnChooser aColChooser)
603     {
604       this.aColChooser = aColChooser;
605       JvSwingUtils.jvInitComponent(selectOption, "action.select");
606       selectOption.addActionListener(new ActionListener()
607       {
608         @Override
609         public void actionPerformed(ActionEvent actionEvent)
610         {
611           selectRadioAction(actionEvent);
612         }
613       });
614
615       JvSwingUtils.jvInitComponent(hideOption, "action.hide");
616       hideOption.addActionListener(new ActionListener()
617       {
618         @Override
619         public void actionPerformed(ActionEvent actionEvent)
620         {
621           hideRadioAction(actionEvent);
622         }
623       });
624
625       optionsGroup.add(selectOption);
626       optionsGroup.add(hideOption);
627       optionsGroup.setSelected(selectOption.getModel(), true);
628
629       JvSwingUtils.jvInitComponent(this);
630       syncState();
631
632       this.add(selectOption);
633       this.add(hideOption);
634     }
635
636     public void selectRadioAction(ActionEvent actionEvent)
637     {
638       aColChooser.setCurrentFutherActionPanel(this);
639       aColChooser.select_action(actionEvent);
640     }
641
642     public void hideRadioAction(ActionEvent actionEvent)
643     {
644       aColChooser.setCurrentFutherActionPanel(this);
645       aColChooser.hide_action(actionEvent);
646     }
647
648     public void syncState()
649     {
650       if (aColChooser.getActionOption() == AnnotationColumnChooser.ACTION_OPTION_HIDE)
651       {
652         this.optionsGroup.setSelected(this.hideOption.getModel(), true);
653       }
654       else
655       {
656         this.optionsGroup.setSelected(this.selectOption.getModel(), true);
657       }
658     }
659   }
660
661   public class StructureFilterPanel extends JPanel
662   {
663     private AnnotationColumnChooser aColChooser;
664
665     private JCheckBox alphaHelix = new JCheckBox();
666
667     private JCheckBox betaStrand = new JCheckBox();
668
669     private JCheckBox turn = new JCheckBox();
670
671     private JCheckBox all = new JCheckBox();
672
673     public StructureFilterPanel(AnnotationColumnChooser aColChooser)
674     {
675       this.aColChooser = aColChooser;
676
677       JvSwingUtils.jvInitComponent(alphaHelix, "label.alpha_helix");
678       alphaHelix.addActionListener(new ActionListener()
679       {
680         @Override
681         public void actionPerformed(ActionEvent actionEvent)
682         {
683           alphaHelix_actionPerformed();
684         }
685       });
686
687       JvSwingUtils.jvInitComponent(betaStrand, "label.beta_strand");
688       betaStrand.addActionListener(new ActionListener()
689       {
690         @Override
691         public void actionPerformed(ActionEvent actionEvent)
692         {
693           betaStrand_actionPerformed();
694         }
695       });
696
697       JvSwingUtils.jvInitComponent(turn, "label.turn");
698       turn.addActionListener(new ActionListener()
699       {
700         @Override
701         public void actionPerformed(ActionEvent actionEvent)
702         {
703           turn_actionPerformed();
704         }
705       });
706
707       JvSwingUtils.jvInitComponent(all, "label.select_all");
708       all.addActionListener(new ActionListener()
709       {
710         @Override
711         public void actionPerformed(ActionEvent actionEvent)
712         {
713           all_actionPerformed();
714         }
715       });
716
717       this.setBorder(new TitledBorder(MessageManager
718               .getString("label.structures_filter")));
719       JvSwingUtils.jvInitComponent(this);
720
721       this.add(all);
722       this.add(alphaHelix);
723       this.add(betaStrand);
724       this.add(turn);
725     }
726
727     public void alphaHelix_actionPerformed()
728     {
729       updateSelectAllState();
730       aColChooser.setCurrentStructureFilterPanel(this);
731       aColChooser.updateView();
732     }
733
734     public void betaStrand_actionPerformed()
735     {
736       updateSelectAllState();
737       aColChooser.setCurrentStructureFilterPanel(this);
738       aColChooser.updateView();
739     }
740
741     public void turn_actionPerformed()
742     {
743       updateSelectAllState();
744       aColChooser.setCurrentStructureFilterPanel(this);
745       aColChooser.updateView();
746     }
747
748     public void all_actionPerformed()
749     {
750       if (all.isSelected())
751       {
752         alphaHelix.setSelected(true);
753         betaStrand.setSelected(true);
754         turn.setSelected(true);
755       }
756       else
757       {
758         alphaHelix.setSelected(false);
759         betaStrand.setSelected(false);
760         turn.setSelected(false);
761       }
762       aColChooser.setCurrentStructureFilterPanel(this);
763       aColChooser.updateView();
764     }
765
766     public void updateSelectAllState()
767     {
768       if (alphaHelix.isSelected() && betaStrand.isSelected()
769               && turn.isSelected())
770       {
771         all.setSelected(true);
772       }
773       else
774       {
775         all.setSelected(false);
776       }
777     }
778
779     public void syncState()
780     {
781       StructureFilterPanel sfp = aColChooser
782               .getCurrentStructureFilterPanel();
783       if (sfp != null)
784       {
785         alphaHelix.setSelected(sfp.alphaHelix.isSelected());
786         betaStrand.setSelected(sfp.betaStrand.isSelected());
787         turn.setSelected(sfp.turn.isSelected());
788         if (sfp.all.isSelected())
789         {
790           all.setSelected(true);
791           alphaHelix.setSelected(true);
792           betaStrand.setSelected(true);
793           turn.setSelected(true);
794         }
795       }
796
797     }
798   }
799
800   public class SearchPanel extends JPanel
801   {
802     private AnnotationColumnChooser aColChooser;
803
804     private JCheckBox displayName = new JCheckBox();
805
806     private JCheckBox description = new JCheckBox();
807
808     private JTextField searchBox = new JTextField(10);
809
810     public SearchPanel(AnnotationColumnChooser aColChooser)
811     {
812
813       this.aColChooser = aColChooser;
814       JvSwingUtils.jvInitComponent(this);
815       this.setBorder(new TitledBorder(MessageManager
816               .getString("label.search_filter")));
817
818       JvSwingUtils.jvInitComponent(searchBox);
819       searchBox.setToolTipText(MessageManager
820               .getString("info.enter_search_text_here"));
821       searchBox.getDocument().addDocumentListener(new DocumentListener()
822       {
823         @Override
824         public void insertUpdate(DocumentEvent e)
825         {
826           searchStringAction();
827         }
828
829         @Override
830         public void removeUpdate(DocumentEvent e)
831         {
832           searchStringAction();
833         }
834
835         @Override
836         public void changedUpdate(DocumentEvent e)
837         {
838           searchStringAction();
839         }
840       });
841
842       JvSwingUtils.jvInitComponent(displayName, "label.label");
843       displayName.setEnabled(false);
844       displayName.addActionListener(new ActionListener()
845       {
846         @Override
847         public void actionPerformed(ActionEvent actionEvent)
848         {
849           displayNameCheckboxAction();
850         }
851       });
852
853       JvSwingUtils.jvInitComponent(description, "label.description");
854       description.setEnabled(false);
855       description.addActionListener(new ActionListener()
856       {
857         @Override
858         public void actionPerformed(ActionEvent actionEvent)
859         {
860           discriptionCheckboxAction();
861         }
862       });
863
864       syncState();
865       this.add(searchBox);
866       this.add(displayName);
867       this.add(description);
868     }
869
870     public void displayNameCheckboxAction()
871     {
872       aColChooser.setCurrentSearchPanel(this);
873       aColChooser.updateView();
874     }
875
876     public void discriptionCheckboxAction()
877     {
878       aColChooser.setCurrentSearchPanel(this);
879       aColChooser.updateView();
880     }
881
882     public void searchStringAction()
883     {
884       aColChooser.setCurrentSearchPanel(this);
885       aColChooser.updateView();
886       updateSearchPanelToolTips();
887     }
888
889     public void syncState()
890     {
891       SearchPanel sp = aColChooser.getCurrentSearchPanel();
892       if (sp != null)
893       {
894         description.setEnabled(sp.description.isEnabled());
895         description.setSelected(sp.description.isSelected());
896
897         displayName.setEnabled(sp.displayName.isEnabled());
898         displayName.setSelected(sp.displayName.isSelected());
899
900         searchBox.setText(sp.searchBox.getText());
901       }
902       updateSearchPanelToolTips();
903     }
904
905     public void updateSearchPanelToolTips()
906     {
907       String defaultTtip = MessageManager
908               .getString("info.enter_search_text_to_enable");
909       String labelTtip = MessageManager.formatMessage(
910               "info.search_in_annotation_label", annotations
911                       .getSelectedItem().toString());
912       String descTtip = MessageManager.formatMessage(
913               "info.search_in_annotation_description", annotations
914                       .getSelectedItem().toString());
915       displayName.setToolTipText(displayName.isEnabled() ? labelTtip
916               : defaultTtip);
917       description.setToolTipText(description.isEnabled() ? descTtip
918               : defaultTtip);
919     }
920   }
921
922 }