From c03d2649512cdc491a46dda1d1370273241b5253 Mon Sep 17 00:00:00 2001 From: Charles Ofoegbu Date: Tue, 20 Jan 2015 12:16:27 +0000 Subject: [PATCH] JAL-1553 enhancement of column selection by annotation row to include the query filter interface and ability to perform further actions like hide/select on the filterd columns --- resources/lang/Messages.properties | 2 + .../datamodel/AnnotationFilterParameter.java | 107 +++++ src/jalview/gui/AlignViewport.java | 10 +- src/jalview/gui/AnnotationColourChooser.java | 21 +- src/jalview/gui/AnnotationColumnChooser.java | 433 ++++++++++++++++---- src/jalview/gui/AnnotationRowFilter.java | 131 +++--- src/jalview/gui/ScalePanel.java | 41 +- src/jalview/jbgui/FurtherActionPanel.java | 139 +++++++ src/jalview/jbgui/GAlignFrame.java | 3 +- src/jalview/jbgui/SearchPanel.java | 182 ++++++++ src/jalview/jbgui/StructureFilterPanel.java | 200 +++++++++ 11 files changed, 1092 insertions(+), 177 deletions(-) create mode 100644 src/jalview/datamodel/AnnotationFilterParameter.java create mode 100644 src/jalview/jbgui/FurtherActionPanel.java create mode 100644 src/jalview/jbgui/SearchPanel.java create mode 100644 src/jalview/jbgui/StructureFilterPanel.java diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index fce8470..57bcd5f 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -1176,3 +1176,5 @@ label.show_logo = Show Logo label.normalise_logo = Normalise Logo label.no_colour_selection_in_scheme = Please, make a colour selection before to apply colour scheme label.no_colour_selection_warn = Error saving colour scheme +label.select_by_annotation = Select By Annotation +action.select_by_annotation = Select by annotation... diff --git a/src/jalview/datamodel/AnnotationFilterParameter.java b/src/jalview/datamodel/AnnotationFilterParameter.java new file mode 100644 index 0000000..cb45c00 --- /dev/null +++ b/src/jalview/datamodel/AnnotationFilterParameter.java @@ -0,0 +1,107 @@ +package jalview.datamodel; + +import java.util.ArrayList; +import java.util.List; + +public class AnnotationFilterParameter +{ + public enum ThresholdType + { + NO_THRESHOLD, BELOW_THRESHOLD, ABOVE_THRESHOLD; + } + + public enum SearchableAnnotationField + { + DISPLAY_STRING("Display Character"), DESCRIPTION("Description"); + private String fieldName; + + SearchableAnnotationField(String fieldName) + { + this.fieldName = fieldName; + } + } + private ThresholdType thresholdType; + + private float thresholdValue; + + private boolean filterAlphaHelix = false; + + private boolean filterBetaSheet = false; + + private boolean filterTurn = false; + + private String regexString; + + private List regexSearchFields = new ArrayList(); + + public ThresholdType getThresholdType() + { + return thresholdType; + } + + public void setThresholdType(ThresholdType thresholdType) + { + this.thresholdType = thresholdType; + } + + public float getThresholdValue() + { + return thresholdValue; + } + + public void setThresholdValue(float thresholdValue) + { + this.thresholdValue = thresholdValue; + } + + public String getRegexString() + { + return regexString; + } + + public void setRegexString(String regexString) + { + this.regexString = regexString; + } + + public List getRegexSearchFields() + { + return regexSearchFields; + } + + public void addRegexSearchField(SearchableAnnotationField regexSearchField) + { + this.regexSearchFields.add(regexSearchField); + } + + public boolean isFilterAlphaHelix() + { + return filterAlphaHelix; + } + + public void setFilterAlphaHelix(boolean alphaHelix) + { + this.filterAlphaHelix = alphaHelix; + } + + public boolean isFilterBetaSheet() + { + return filterBetaSheet; + } + + public void setFilterBetaSheet(boolean betaSheet) + { + this.filterBetaSheet = betaSheet; + } + + public boolean isFilterTurn() + { + return filterTurn; + } + + public void setFilterTurn(boolean turn) + { + this.filterTurn = turn; + } + +} diff --git a/src/jalview/gui/AlignViewport.java b/src/jalview/gui/AlignViewport.java index 29d936f..b8f575f 100644 --- a/src/jalview/gui/AlignViewport.java +++ b/src/jalview/gui/AlignViewport.java @@ -140,7 +140,7 @@ public class AlignViewport extends AlignmentViewport implements Color textColour2 = Color.white; private boolean rightAlignIds = false; - private AnnotationColumnChooser currentAnnotationColumnSelectionState; + private AnnotationColumnChooser annotationColumnSelectionState; /** * Creates a new AlignViewport object. * @@ -1251,14 +1251,14 @@ public class AlignViewport extends AlignmentViewport implements this.rightAlignIds = rightAlignIds; } - public AnnotationColumnChooser getCurrentAnnotationColumnSelectionState() + public AnnotationColumnChooser getAnnotationColumnSelectionState() { - return currentAnnotationColumnSelectionState; + return annotationColumnSelectionState; } - public void setCurrentAnnotationColumnSelectionState( + public void setAnnotationColumnSelectionState( AnnotationColumnChooser currentAnnotationColumnSelectionState) { - this.currentAnnotationColumnSelectionState = currentAnnotationColumnSelectionState; + this.annotationColumnSelectionState = currentAnnotationColumnSelectionState; } } diff --git a/src/jalview/gui/AnnotationColourChooser.java b/src/jalview/gui/AnnotationColourChooser.java index 699b560..3c6fd88 100644 --- a/src/jalview/gui/AnnotationColourChooser.java +++ b/src/jalview/gui/AnnotationColourChooser.java @@ -387,15 +387,18 @@ public class AnnotationColourChooser extends AnnotationRowFilter public void valueChanged(boolean updateAllAnnotation) { - if (currentColours.isSelected() - && !(av.getGlobalColourScheme() instanceof AnnotationColourGradient)) + if (slider.isEnabled()) { - updateView(); + if (currentColours.isSelected() + && !(av.getGlobalColourScheme() instanceof AnnotationColourGradient)) + { + updateView(); + } + getCurrentAnnotation().threshold.value = slider.getValue() / 1000f; + propagateSeqAssociatedThreshold(updateAllAnnotation, + getCurrentAnnotation()); + ap.paintAlignment(false); } - getCurrentAnnotation().threshold.value = slider.getValue() / 1000f; - propagateSeqAssociatedThreshold(updateAllAnnotation, - getCurrentAnnotation()); - ap.paintAlignment(false); } public JComboBox getThreshold() @@ -422,10 +425,6 @@ public class AnnotationColourChooser extends AnnotationRowFilter @Override public void updateView() { - changeColour(); - } - void changeColour() - { // Check if combobox is still adjusting if (adjusting) { diff --git a/src/jalview/gui/AnnotationColumnChooser.java b/src/jalview/gui/AnnotationColumnChooser.java index 87e2d78..3db148d 100644 --- a/src/jalview/gui/AnnotationColumnChooser.java +++ b/src/jalview/gui/AnnotationColumnChooser.java @@ -1,25 +1,38 @@ package jalview.gui; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AnnotationFilterParameter; import jalview.datamodel.ColumnSelection; +import jalview.jbgui.FurtherActionPanel; +import jalview.jbgui.SearchPanel; +import jalview.jbgui.StructureFilterPanel; import jalview.schemes.AnnotationColourGradient; import jalview.util.MessageManager; import java.awt.BorderLayout; +import java.awt.CardLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.Iterator; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JInternalFrame; +import javax.swing.JLabel; import javax.swing.JLayeredPane; import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.border.TitledBorder; import net.miginfocom.swing.MigLayout; @SuppressWarnings("serial") -public class AnnotationColumnChooser extends AnnotationRowFilter +public class AnnotationColumnChooser extends AnnotationRowFilter implements + ItemListener { private ColumnSelection oldColumnSelection; @@ -30,14 +43,54 @@ public class AnnotationColumnChooser extends AnnotationRowFilter JButton cancel = new JButton(); - JPanel jPanel1 = new JPanel(); + JPanel actionPanel = new JPanel(); - JPanel jPanel2 = new JPanel(); + JPanel thresholdPanel = new JPanel(); + + JPanel switchableViewsPanel = new JPanel(new CardLayout()); + + CardLayout switchableViewsLayout = (CardLayout) (switchableViewsPanel + .getLayout()); + + JPanel noGraphFilterView = new JPanel(); + + JPanel graphFilterView = new JPanel(); + + JPanel annotationComboBoxPanel = new JPanel(); + + StructureFilterPanel gStructureFilterPanel; + + StructureFilterPanel ngStructureFilterPanel; + + private StructureFilterPanel currentStructureFilterPanel; + + JLabel annotationLabel = new JLabel(); BorderLayout borderLayout1 = new BorderLayout(); private JComboBox threshold = new JComboBox(); + private SearchPanel currentSearchPanel; + + private SearchPanel gSearchPanel; + + private SearchPanel ngSearchPanel; + + private FurtherActionPanel currentFurtherActionPanel; + + private FurtherActionPanel gFurtherActionPanel; + + private FurtherActionPanel ngFurtherActionPanel; + + public static final int ACTION_OPTION_SELECT = 1; + + public static int ACTION_OPTION_HIDE = 2; + + public static String NO_GRAPH_VIEW = "0"; + + public static String GRAPH_VIEW = "1"; + + private int actionOption = ACTION_OPTION_SELECT; public AnnotationColumnChooser(AlignViewport av, final AlignmentPanel ap) { @@ -45,7 +98,9 @@ public class AnnotationColumnChooser extends AnnotationRowFilter frame = new JInternalFrame(); frame.setContentPane(this); frame.setLayer(JLayeredPane.PALETTE_LAYER); - Desktop.addInternalFrame(frame, "Select By Annotation", 520, 215); + Desktop.addInternalFrame(frame, + MessageManager.getString("label.select_by_annotation"), 520, + 215); addSliderChangeListener(); addSliderMouseListeners(); @@ -57,18 +112,23 @@ public class AnnotationColumnChooser extends AnnotationRowFilter setOldColumnSelection(av.getColumnSelection()); adjusting = true; - setAnnotations(new JComboBox( - getAnnotationItems(seqAssociated.isSelected()))); + setAnnotations(new JComboBox(getAnnotationItems(false))); populateThresholdComboBox(threshold); - if (av.getCurrentAnnotationColumnSelectionState() != null) + // restore the Object state from the previous session if one exists + if (av.getAnnotationColumnSelectionState() != null) { - annotations.setSelectedIndex(av - .getCurrentAnnotationColumnSelectionState().getAnnotations() - .getSelectedIndex()); - threshold.setSelectedIndex(av - .getCurrentAnnotationColumnSelectionState().getThreshold() - .getSelectedIndex()); + currentSearchPanel = av.getAnnotationColumnSelectionState() + .getCurrentSearchPanel(); + currentStructureFilterPanel = av.getAnnotationColumnSelectionState() + .getCurrentStructureFilterPanel(); + annotations.setSelectedIndex(av.getAnnotationColumnSelectionState() + .getAnnotations().getSelectedIndex()); + threshold.setSelectedIndex(av.getAnnotationColumnSelectionState() + .getThreshold().getSelectedIndex()); + actionOption = av.getAnnotationColumnSelectionState() + .getActionOption(); + } try @@ -84,7 +144,6 @@ public class AnnotationColumnChooser extends AnnotationRowFilter frame.pack(); } - public AnnotationColumnChooser() { try @@ -119,14 +178,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter } }); - getAnnotations().addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - annotations_actionPerformed(e); - } - }); + getAnnotations().addItemListener(this); getThreshold().addActionListener(new ActionListener() { @Override @@ -135,6 +187,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter threshold_actionPerformed(e); } }); + thresholdValue.addActionListener(new ActionListener() { @Override @@ -151,64 +204,106 @@ public class AnnotationColumnChooser extends AnnotationRowFilter slider.setPreferredSize(new Dimension(100, 32)); thresholdValue.setEnabled(false); thresholdValue.setColumns(7); - thresholdIsMin.setBackground(Color.white); - thresholdIsMin.setFont(JvSwingUtils.getLabelFont()); - thresholdIsMin.setText(MessageManager - .getString("label.threshold_minmax")); - thresholdIsMin.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent actionEvent) - { - thresholdIsMin_actionPerformed(actionEvent); - } - }); - seqAssociated.setBackground(Color.white); - seqAssociated.setFont(JvSwingUtils.getLabelFont()); - seqAssociated.setText(MessageManager - .getString("label.per_sequence_only")); - seqAssociated.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent arg0) - { - seqAssociated_actionPerformed(arg0, annotations, seqAssociated); - } - }); + annotationLabel.setBackground(Color.white); + annotationLabel.setFont(JvSwingUtils.getLabelFont()); + annotationLabel.setText("Select Annotation : "); + + thresholdPanel.setBorder(new TitledBorder("Threshold Filter")); + thresholdPanel.setBackground(Color.white); + thresholdPanel.setFont(JvSwingUtils.getLabelFont()); + thresholdPanel.setLayout(new MigLayout("", "[left][right]", "[][]")); + + actionPanel.setBackground(Color.white); + actionPanel.setFont(JvSwingUtils.getLabelFont()); this.setLayout(borderLayout1); - jPanel2.setLayout(new MigLayout("", "[left][center][right]", "[][][]")); - jPanel1.setBackground(Color.white); - jPanel2.setBackground(Color.white); - - jPanel1.add(ok); - jPanel1.add(cancel); - jPanel2.add(getAnnotations(), "grow, wrap"); - jPanel2.add(seqAssociated, "wrap"); - jPanel2.add(getThreshold(), "grow, wrap"); - jPanel2.add(thresholdIsMin, "wrap"); - jPanel2.add(slider, "grow"); - jPanel2.add(thresholdValue, "grow"); - this.add(jPanel1, java.awt.BorderLayout.SOUTH); - this.add(jPanel2, java.awt.BorderLayout.CENTER); + graphFilterView.setLayout(new MigLayout("", "[left][right]", "[][]")); + graphFilterView.setBackground(Color.white); + + noGraphFilterView.setLayout(new MigLayout("", "[left][right]", "[][]")); + noGraphFilterView.setBackground(Color.white); + annotationComboBoxPanel.setBackground(Color.white); + annotationComboBoxPanel.setFont(JvSwingUtils.getLabelFont()); + + gSearchPanel = new SearchPanel(this); + ngSearchPanel = new SearchPanel(this); + gFurtherActionPanel = new FurtherActionPanel(this); + ngFurtherActionPanel = new FurtherActionPanel(this); + gStructureFilterPanel = new StructureFilterPanel(this); + ngStructureFilterPanel = new StructureFilterPanel(this); + + + thresholdPanel.add(getThreshold()); + thresholdPanel.add(thresholdValue, "wrap"); + thresholdPanel.add(slider, "grow, span, wrap"); + + actionPanel.add(ok); + actionPanel.add(cancel); + + graphFilterView.add(gSearchPanel, "grow, span, wrap"); + graphFilterView.add(gStructureFilterPanel, "grow, span, wrap"); + graphFilterView.add(thresholdPanel, "grow, span, wrap"); + graphFilterView.add(gFurtherActionPanel); + + noGraphFilterView.add(ngSearchPanel, "grow, span, wrap"); + noGraphFilterView.add(ngStructureFilterPanel, "grow, span, wrap"); + noGraphFilterView.add(ngFurtherActionPanel); + + annotationComboBoxPanel.add(getAnnotations()); + switchableViewsPanel.add(noGraphFilterView, + AnnotationColumnChooser.NO_GRAPH_VIEW); + switchableViewsPanel.add(graphFilterView, + AnnotationColumnChooser.GRAPH_VIEW); + + this.add(annotationComboBoxPanel, java.awt.BorderLayout.PAGE_START); + this.add(switchableViewsPanel, java.awt.BorderLayout.CENTER); + this.add(actionPanel, java.awt.BorderLayout.SOUTH); + + selectedAnnotationChanged(); this.validate(); } - + @SuppressWarnings("unchecked") public void reset() { - av.getColumnSelection().clear(); - av.setColumnSelection(this.getOldColumnSelection()); + if (this.getOldColumnSelection() != null) + { + av.getColumnSelection().clear(); + + if (av.getAnnotationColumnSelectionState() != null) + { + ColumnSelection oldSelection = av + .getAnnotationColumnSelectionState() + .getOldColumnSelection(); + if (oldSelection != null && oldSelection.getHiddenColumns() != null + && !oldSelection.getHiddenColumns().isEmpty()) + { + for (Iterator itr = oldSelection.getHiddenColumns() + .iterator(); itr.hasNext();) + { + int positions[] = itr.next(); + av.hideColumns(positions[0], positions[1]); + } + } + av.setColumnSelection(oldSelection); + } + // ap.alignmentChanged(); + ap.paintAlignment(true); + } + } public void valueChanged(boolean updateAllAnnotation) { - getCurrentAnnotation().threshold.value = slider.getValue() / 1000f; - updateView(); - propagateSeqAssociatedThreshold(updateAllAnnotation, - getCurrentAnnotation()); - ap.paintAlignment(false); + if (slider.isEnabled()) + { + getCurrentAnnotation().threshold.value = slider.getValue() / 1000f; + updateView(); + propagateSeqAssociatedThreshold(updateAllAnnotation, + getCurrentAnnotation()); + ap.paintAlignment(false); + } } public JComboBox getThreshold() @@ -234,45 +329,41 @@ public class AnnotationColumnChooser extends AnnotationRowFilter @Override public void updateView() { - changeColumnSelection(); - } - void changeColumnSelection() - { // Check if combobox is still adjusting if (adjusting) { return; } + AnnotationFilterParameter filterParams = new AnnotationFilterParameter(); + setCurrentAnnotation(av.getAlignment().getAlignmentAnnotation()[annmap[getAnnotations() .getSelectedIndex()]]); - int selectedThresholdItem = getSelectedThresholdItem(getThreshold() .getSelectedIndex()); slider.setEnabled(true); thresholdValue.setEnabled(true); - thresholdIsMin.setEnabled(true); if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD) { slider.setEnabled(false); thresholdValue.setEnabled(false); thresholdValue.setText(""); - thresholdIsMin.setEnabled(false); + // build filter params } - else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD - && getCurrentAnnotation().threshold == null) + else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD) { - getCurrentAnnotation() - .setThreshold(new jalview.datamodel.GraphLine( - (getCurrentAnnotation().graphMax - getCurrentAnnotation().graphMin) / 2f, - "Threshold", Color.black)); - } + if (getCurrentAnnotation().threshold == null) + { + getCurrentAnnotation() + .setThreshold( + new jalview.datamodel.GraphLine( + (getCurrentAnnotation().graphMax - getCurrentAnnotation().graphMin) / 2f, + "Threshold", Color.black)); + } - if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD) - { adjusting = true; float range = getCurrentAnnotation().graphMax * 1000 - getCurrentAnnotation().graphMin * 1000; @@ -285,11 +376,78 @@ public class AnnotationColumnChooser extends AnnotationRowFilter slider.setEnabled(true); thresholdValue.setEnabled(true); adjusting = false; + + // build filter params + filterParams + .setThresholdType(AnnotationFilterParameter.ThresholdType.NO_THRESHOLD); + if (getCurrentAnnotation().graph != AlignmentAnnotation.NO_GRAPH) + { + + if (selectedThresholdItem == AnnotationColourGradient.ABOVE_THRESHOLD) + { + filterParams + .setThresholdType(AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD); + } + else if (selectedThresholdItem == AnnotationColourGradient.BELOW_THRESHOLD) + { + filterParams + .setThresholdType(AnnotationFilterParameter.ThresholdType.BELOW_THRESHOLD); + } + } + } + + if (currentStructureFilterPanel != null) + { + if (currentStructureFilterPanel.getAlphaHelix().isSelected()) + { + filterParams.setFilterAlphaHelix(true); + } + if (currentStructureFilterPanel.getBetaStrand().isSelected()) + { + filterParams.setFilterBetaSheet(true); + } + if (currentStructureFilterPanel.getTurn().isSelected()) + { + filterParams.setFilterTurn(true); + } + } + + if (currentSearchPanel != null) + { + if (!currentSearchPanel.getSearchString().isEmpty()) + { + currentSearchPanel.getDescription().setEnabled(true); + currentSearchPanel.getDisplayName().setEnabled(true); + filterParams.setRegexString(currentSearchPanel.getSearchString()); + if (currentSearchPanel.isDisplayNameChecked()) + { + filterParams + .addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DISPLAY_STRING); + } + if (currentSearchPanel.isDescriptionChecked()) + { + filterParams + .addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DESCRIPTION); + } + } + else + { + currentSearchPanel.getDescription().setEnabled(false); + currentSearchPanel.getDisplayName().setEnabled(false); + } } - markColumnsContaining(getCurrentAnnotation(), selectedThresholdItem); - av.setCurrentAnnotationColumnSelectionState(this); - ap.alignmentChanged(); + filterAnnotations(getCurrentAnnotation().annotations, filterParams, + av.getColumnSelection()); + + av.showAllHiddenColumns(); + if (getActionOption() == ACTION_OPTION_HIDE) + { + av.hideSelectedColumns(); + } + + filterParams = null; + av.setAnnotationColumnSelectionState(this); ap.paintAlignment(true); } @@ -302,8 +460,105 @@ public class AnnotationColumnChooser extends AnnotationRowFilter { if (currentColumnSelection != null) { - this.oldColumnSelection = new ColumnSelection(); - this.oldColumnSelection.setElementsFrom(currentColumnSelection); + this.oldColumnSelection = new ColumnSelection(currentColumnSelection); } } + + + public void select_action(ActionEvent actionEvent) + { + JRadioButton radioButton = (JRadioButton) actionEvent.getSource(); + if (radioButton.isSelected()) + { + setActionOption(ACTION_OPTION_SELECT); + updateView(); + } + } + + public void hide_action(ActionEvent actionEvent) + { + JRadioButton radioButton = (JRadioButton) actionEvent.getSource(); + if (radioButton.isSelected()) + { + setActionOption(ACTION_OPTION_HIDE); + updateView(); + } + } + + + @Override + public void itemStateChanged(ItemEvent e) + { + selectedAnnotationChanged(); + } + + public void selectedAnnotationChanged() + { + String currentView = AnnotationColumnChooser.NO_GRAPH_VIEW; + if (av.getAlignment().getAlignmentAnnotation()[annmap[getAnnotations() + .getSelectedIndex()]].graph != AlignmentAnnotation.NO_GRAPH) + { + currentView = AnnotationColumnChooser.GRAPH_VIEW; + } + // else{ + // threshold.setSelectedIndex(AlignmentAnnotation.NO_GRAPH); + // } + + gSearchPanel.syncState(); + gFurtherActionPanel.syncState(); + gFurtherActionPanel.syncState(); + gFurtherActionPanel.syncState(); + + ngSearchPanel.syncState(); + ngFurtherActionPanel.syncState(); + ngStructureFilterPanel.syncState(); + ngFurtherActionPanel.syncState(); + + switchableViewsLayout.show(switchableViewsPanel, currentView); + updateView(); + } + + + public FurtherActionPanel getCurrentFutherActionPanel() + { + return currentFurtherActionPanel; + } + + public void setCurrentFutherActionPanel( + FurtherActionPanel currentFutherActionPanel) + { + this.currentFurtherActionPanel = currentFutherActionPanel; + } + + public SearchPanel getCurrentSearchPanel() + { + return currentSearchPanel; + } + + public void setCurrentSearchPanel(SearchPanel currentSearchPanel) + { + this.currentSearchPanel = currentSearchPanel; + } + + public int getActionOption() + { + return actionOption; + } + + public void setActionOption(int actionOption) + { + this.actionOption = actionOption; + } + + public StructureFilterPanel getCurrentStructureFilterPanel() + { + return currentStructureFilterPanel; + } + + public void setCurrentStructureFilterPanel( + StructureFilterPanel currentStructureFilterPanel) + { + this.currentStructureFilterPanel = currentStructureFilterPanel; + } + } diff --git a/src/jalview/gui/AnnotationRowFilter.java b/src/jalview/gui/AnnotationRowFilter.java index 9e205c4..ed59ef6 100644 --- a/src/jalview/gui/AnnotationRowFilter.java +++ b/src/jalview/gui/AnnotationRowFilter.java @@ -3,6 +3,8 @@ package jalview.gui; import jalview.api.AnnotationRowFilterI; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.Annotation; +import jalview.datamodel.AnnotationFilterParameter; +import jalview.datamodel.AnnotationFilterParameter.SearchableAnnotationField; import jalview.datamodel.ColumnSelection; import jalview.datamodel.GraphLine; import jalview.datamodel.SequenceGroup; @@ -12,6 +14,7 @@ import jalview.util.MessageManager; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.List; import java.util.Vector; import javax.swing.JCheckBox; @@ -156,7 +159,6 @@ public abstract class AnnotationRowFilter extends JPanel implements } } } - // seqAssociated.setEnabled(enableSeqAss); this.annmap = new int[list.size()]; System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length); return list; @@ -364,76 +366,87 @@ public abstract class AnnotationRowFilter extends JPanel implements return false; } - protected boolean markColumnsContaining( - AlignmentAnnotation currentAnnotation, int thresholdComparisonType) + protected boolean filterAnnotations(Annotation[] annotations, + AnnotationFilterParameter filterParams, ColumnSelection cs) { - try + av.showAllHiddenColumns(); + cs.clear(); + int count = 0; + do { - if (currentAnnotation != null) + if (annotations[count] != null) { - Annotation[] annotations = currentAnnotation.annotations; - ColumnSelection cs = av.getColumnSelection(); - cs.clear(); - if (thresholdComparisonType == AnnotationColourGradient.NO_THRESHOLD) + + boolean itemMatched = false; + + if (filterParams.getThresholdType() == AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD + && annotations[count].value > currentAnnotation.threshold.value) { - int count = 0; - do - { - if (annotations[count] != null) - { - if (currentAnnotation.label.equals("Secondary Structure") - && annotations[count].secondaryStructure != ' ') - { - cs.addElement(count); - } - else if (currentAnnotation.label - .equals("Iron Sulphur Contacts")) - { - cs.addElement(count); - } - else if (annotations[count].value != 0.0) - { - cs.addElement(count); - } + itemMatched = true; + } + if (filterParams.getThresholdType() == AnnotationFilterParameter.ThresholdType.BELOW_THRESHOLD + && annotations[count].value < currentAnnotation.threshold.value) + { + itemMatched = true; + } - } - count++; - } while (count < annotations.length); + if (filterParams.isFilterAlphaHelix() + && annotations[count].secondaryStructure == 'H') + { + itemMatched = true; } - else + + if (filterParams.isFilterBetaSheet() + && annotations[count].secondaryStructure == 'E') + { + itemMatched = true; + } + + if (filterParams.isFilterTurn() + && annotations[count].secondaryStructure == 'S') { - int count = 0; - do + itemMatched = true; + } + + String regexSearchString = filterParams.getRegexString(); + if (regexSearchString != null + && !filterParams.getRegexSearchFields().isEmpty()) + { + List fields = filterParams + .getRegexSearchFields(); + try { - if (annotations[count] != null) + if (fields.contains(SearchableAnnotationField.DISPLAY_STRING) + && annotations[count].displayCharacter + .matches(regexSearchString)) { - if (thresholdComparisonType == AnnotationColourGradient.ABOVE_THRESHOLD) - { - if (annotations[count].value > currentAnnotation.threshold.value) - { - cs.addElement(count); - } - } - else if (thresholdComparisonType == AnnotationColourGradient.BELOW_THRESHOLD) - { - if (annotations[count].value < currentAnnotation.threshold.value) - { - cs.addElement(count); - } - } - + itemMatched = true; } - count++; - } while (count < annotations.length); + } catch (java.util.regex.PatternSyntaxException pse) + { + if (annotations[count].displayCharacter + .equals(regexSearchString)) + { + itemMatched = true; + } + } + if (fields.contains(SearchableAnnotationField.DESCRIPTION) + && annotations[count].description != null + && annotations[count].description + .matches(regexSearchString)) + { + itemMatched = true; + } } - } - return true; - } catch (Exception e) - { - e.printStackTrace(); - return false; - } + if (itemMatched) + { + cs.addElement(count); + } + } + count++; + } while (count < annotations.length); + return false; } public jalview.datamodel.AlignmentAnnotation getCurrentAnnotation() diff --git a/src/jalview/gui/ScalePanel.java b/src/jalview/gui/ScalePanel.java index 568062b..01e4284 100755 --- a/src/jalview/gui/ScalePanel.java +++ b/src/jalview/gui/ScalePanel.java @@ -20,14 +20,28 @@ */ package jalview.gui; -import java.awt.*; -import java.awt.event.*; - -import javax.swing.*; - -import jalview.datamodel.*; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; import jalview.util.MessageManager; +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import javax.swing.ToolTipManager; + /** * DOCUMENT ME! * @@ -355,6 +369,8 @@ public class ScalePanel extends JPanel implements MouseMotionListener, res = av.getColumnSelection().adjustForHiddenColumns(res); reveal = null; + if (av.getColumnSelection().getHiddenColumns() != null) + { for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++) { int[] region = (int[]) av.getColumnSelection().getHiddenColumns() @@ -373,7 +389,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener, } } - + } repaint(); } @@ -466,18 +482,18 @@ public class ScalePanel extends JPanel implements MouseMotionListener, } gg.drawLine( - (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)), + ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), y + 2, - (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)), + ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), y + (fm.getDescent() * 2)); } else { gg.drawLine( - (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)), + ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), y + fm.getDescent(), - (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)), + ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), y + (fm.getDescent() * 2)); } } @@ -486,7 +502,8 @@ public class ScalePanel extends JPanel implements MouseMotionListener, { gg.setColor(Color.blue); int res; - if (av.getShowHiddenMarkers()) + if (av.getShowHiddenMarkers() + && av.getColumnSelection().getHiddenColumns() != null) { for (int i = 0; i < av.getColumnSelection().getHiddenColumns() .size(); i++) diff --git a/src/jalview/jbgui/FurtherActionPanel.java b/src/jalview/jbgui/FurtherActionPanel.java new file mode 100644 index 0000000..1f91b35 --- /dev/null +++ b/src/jalview/jbgui/FurtherActionPanel.java @@ -0,0 +1,139 @@ +package jalview.jbgui; + +import jalview.gui.AnnotationColumnChooser; +import jalview.gui.JvSwingUtils; + +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.ButtonGroup; +import javax.swing.JPanel; +import javax.swing.JRadioButton; + +@SuppressWarnings("serial") +public class FurtherActionPanel extends JPanel +{ + private AnnotationColumnChooser aColChooser; + + private JRadioButton hideOption = new JRadioButton(); + + private JRadioButton selectOption = new JRadioButton(); + + private ButtonGroup optionsGroup = new ButtonGroup(); + + public FurtherActionPanel(AnnotationColumnChooser aColChooser) + { + + this.aColChooser = aColChooser; + + + getSelectOption().setBackground(Color.white); + getSelectOption().setFont(JvSwingUtils.getLabelFont()); + getSelectOption().setText("Select"); + getSelectOption().addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + selectRadioAction(actionEvent); + } + }); + + getHideOption().setBackground(Color.white); + getHideOption().setFont(JvSwingUtils.getLabelFont()); + getHideOption().setText("Hide"); + getHideOption().addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + hideRadioAction(actionEvent); + } + }); + + getOptionsGroup().add(getSelectOption()); + getOptionsGroup().add(getHideOption()); + getOptionsGroup().setSelected(getSelectOption().getModel(), true); + + this.setBackground(Color.white); + this.setFont(JvSwingUtils.getLabelFont()); + syncState(); + + this.add(getSelectOption()); + this.add(getHideOption()); + } + + public void selectRadioAction(ActionEvent actionEvent) + { + aColChooser.setCurrentFutherActionPanel(this); + aColChooser.select_action(actionEvent); + } + + public void hideRadioAction(ActionEvent actionEvent) + { + aColChooser.setCurrentFutherActionPanel(this); + aColChooser.hide_action(actionEvent); + } + + // public abstract void selectRadioAction(ActionEvent actionEvent); + // + // public abstract void hideRadioAction(ActionEvent actionEvent); + + public JRadioButton getHideOption() + { + return hideOption; + } + + public void setHideOption(JRadioButton hideOption) + { + this.hideOption = hideOption; + } + + public JRadioButton getSelectOption() + { + return selectOption; + } + + public void setSelectOption(JRadioButton selectOption) + { + this.selectOption = selectOption; + } + + public ButtonGroup getOptionsGroup() + { + return optionsGroup; + } + + public void setOptionsGroup(ButtonGroup optionsGroup) + { + this.optionsGroup = optionsGroup; + } + + public void syncState() + { + // FurtherActionPanel fap = aColChooser.getCurrentFutherActionPanel(); + // if (fap != null) + // { + // + // // description.setEnabled(sp.getDescription().isEnabled()); + // // description.setSelected(sp.getDescription().isSelected()); + // // + // // displayName.setEnabled(sp.getDisplayName().isEnabled()); + // // displayName.setSelected(sp.getDisplayName().isSelected()); + // // + // // searchBox.setText(sp.getSearchBox().getText()); + // } + + if (aColChooser.getActionOption() == AnnotationColumnChooser.ACTION_OPTION_HIDE) + { + this.getOptionsGroup().setSelected(this.getHideOption().getModel(), + true); + } + else + { + this.getOptionsGroup().setSelected(this.getSelectOption().getModel(), + true); + } + } +} diff --git a/src/jalview/jbgui/GAlignFrame.java b/src/jalview/jbgui/GAlignFrame.java index 7a5dc54..4ecedaf 100755 --- a/src/jalview/jbgui/GAlignFrame.java +++ b/src/jalview/jbgui/GAlignFrame.java @@ -1876,7 +1876,8 @@ public class GAlignFrame extends JInternalFrame } }); - annotationColumn.setText("Select by annotation..."); + annotationColumn.setText(MessageManager + .getString("action.select_by_annotation")); annotationColumn.addActionListener(new ActionListener() { @Override diff --git a/src/jalview/jbgui/SearchPanel.java b/src/jalview/jbgui/SearchPanel.java new file mode 100644 index 0000000..6a58335 --- /dev/null +++ b/src/jalview/jbgui/SearchPanel.java @@ -0,0 +1,182 @@ +package jalview.jbgui; + +import jalview.gui.AnnotationColumnChooser; +import jalview.gui.JvSwingUtils; + +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.border.TitledBorder; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +@SuppressWarnings("serial") +public class SearchPanel extends JPanel +{ + + private AnnotationColumnChooser aColChooser; + + private JCheckBox displayName = new JCheckBox(); + + private JCheckBox description = new JCheckBox(); + + private JTextField searchBox = new JTextField(10); + + private JCheckBox structuresFilter = new JCheckBox(); + + public SearchPanel(AnnotationColumnChooser aColChooser) + { + + this.aColChooser = aColChooser; + this.setBorder(new TitledBorder("Search Filter")); + this.setBackground(Color.white); + this.setFont(JvSwingUtils.getLabelFont()); + + + getSearchBox().setBackground(Color.white); + getSearchBox().setFont(JvSwingUtils.getLabelFont()); + getSearchBox().getDocument().addDocumentListener(new DocumentListener() + { + @Override + public void insertUpdate(DocumentEvent e) + { + searchStringAction(); + } + + @Override + public void removeUpdate(DocumentEvent e) + { + searchStringAction(); + } + + @Override + public void changedUpdate(DocumentEvent e) + { + searchStringAction(); + } + }); + + getDisplayName().setBackground(Color.white); + getDisplayName().setFont(JvSwingUtils.getLabelFont()); + getDisplayName().setText("Display Name"); + getDisplayName().setEnabled(false); + getDisplayName().addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + displayNameCheckboxAction(); + } + }); + + getDescription().setBackground(Color.white); + getDescription().setFont(JvSwingUtils.getLabelFont()); + getDescription().setText("Description"); + getDescription().setEnabled(false); + getDescription().addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + discriptionCheckboxAction(); + } + }); + + syncState(); + this.add(getSearchBox()); + this.add(getDisplayName()); + this.add(getDescription()); + } + + public boolean isDescriptionChecked() + { + return getDescription().isSelected(); + } + + public boolean isDisplayNameChecked() + { + return getDisplayName().isSelected(); + } + + public String getSearchString() + { + return getSearchBox().getText(); + } + + public void displayNameCheckboxAction() + { + aColChooser.setCurrentSearchPanel(this); + aColChooser.updateView(); + } + + public void discriptionCheckboxAction() + { + aColChooser.setCurrentSearchPanel(this); + aColChooser.updateView(); + } + + public void searchStringAction() + { + aColChooser.setCurrentSearchPanel(this); + aColChooser.updateView(); + } + + public JCheckBox getDisplayName() + { + return displayName; + } + + public void setDisplayName(JCheckBox displayName) + { + this.displayName = displayName; + } + + public JCheckBox getDescription() + { + return description; + } + + public void setDescription(JCheckBox description) + { + this.description = description; + } + + public JTextField getSearchBox() + { + return searchBox; + } + + public void setSearchBox(JTextField searchBox) + { + this.searchBox = searchBox; + } + + public JCheckBox getStructuresFilter() + { + return structuresFilter; + } + + public void setStructuresFilter(JCheckBox structuresFilter) + { + this.structuresFilter = structuresFilter; + } + + public void syncState() + { + SearchPanel sp = aColChooser.getCurrentSearchPanel(); + if (sp != null) + { + description.setEnabled(sp.getDescription().isEnabled()); + description.setSelected(sp.getDescription().isSelected()); + + displayName.setEnabled(sp.getDisplayName().isEnabled()); + displayName.setSelected(sp.getDisplayName().isSelected()); + + searchBox.setText(sp.getSearchBox().getText()); + } + } +} diff --git a/src/jalview/jbgui/StructureFilterPanel.java b/src/jalview/jbgui/StructureFilterPanel.java new file mode 100644 index 0000000..ae3c161 --- /dev/null +++ b/src/jalview/jbgui/StructureFilterPanel.java @@ -0,0 +1,200 @@ +package jalview.jbgui; + +import jalview.gui.AnnotationColumnChooser; +import jalview.gui.JvSwingUtils; + +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import javax.swing.border.TitledBorder; + +@SuppressWarnings("serial") +public class StructureFilterPanel extends JPanel +{ + private AnnotationColumnChooser aColChooser; + + private JCheckBox alphaHelix = new JCheckBox(); + + private JCheckBox betaStrand = new JCheckBox(); + + private JCheckBox turn = new JCheckBox(); + + private JCheckBox all = new JCheckBox(); + + public StructureFilterPanel(AnnotationColumnChooser aColChooser) + { + this.aColChooser = aColChooser; + + alphaHelix.setBackground(Color.white); + alphaHelix.setFont(JvSwingUtils.getLabelFont()); + alphaHelix.setText("Alpha Helix"); + alphaHelix.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + alphaHelix_actionPerformed(); + } + }); + + betaStrand.setBackground(Color.white); + betaStrand.setFont(JvSwingUtils.getLabelFont()); + betaStrand.setText("Beta Strand"); + betaStrand.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + betaStrand_actionPerformed(); + } + }); + + turn.setBackground(Color.white); + turn.setFont(JvSwingUtils.getLabelFont()); + turn.setText("Turn"); + turn.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + turn_actionPerformed(); + } + }); + + all.setBackground(Color.white); + all.setFont(JvSwingUtils.getLabelFont()); + all.setText("Select all"); + all.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + all_actionPerformed(); + } + }); + + this.setBorder(new TitledBorder("Structures Filter")); + this.setBackground(Color.white); + this.setFont(JvSwingUtils.getLabelFont()); + + this.add(all); + this.add(alphaHelix); + this.add(betaStrand); + this.add(turn); + } + + public void alphaHelix_actionPerformed() + { + updateSelectAllState(); + aColChooser.setCurrentStructureFilterPanel(this); + aColChooser.updateView(); + } + + public void betaStrand_actionPerformed() + { + updateSelectAllState(); + aColChooser.setCurrentStructureFilterPanel(this); + aColChooser.updateView(); + } + + public void turn_actionPerformed() + { + updateSelectAllState(); + aColChooser.setCurrentStructureFilterPanel(this); + aColChooser.updateView(); + } + + public void all_actionPerformed() + { + if (all.isSelected()) + { + alphaHelix.setSelected(true); + betaStrand.setSelected(true); + turn.setSelected(true); + } + else + { + alphaHelix.setSelected(false); + betaStrand.setSelected(false); + turn.setSelected(false); + } + aColChooser.setCurrentStructureFilterPanel(this); + aColChooser.updateView(); + } + + public void updateSelectAllState() + { + if (alphaHelix.isSelected() && betaStrand.isSelected() + && turn.isSelected()) + { + all.setSelected(true); + } + else + { + all.setSelected(false); + } + } + + public void syncState() + { + StructureFilterPanel sfp = aColChooser.getCurrentStructureFilterPanel(); + if (sfp != null) + { + alphaHelix.setSelected(sfp.getAlphaHelix().isSelected()); + betaStrand.setSelected(sfp.getBetaStrand().isSelected()); + turn.setSelected(sfp.getTurn().isSelected()); + if (sfp.getAll().isSelected()) + { + all.setSelected(true); + alphaHelix.setSelected(true); + betaStrand.setSelected(true); + turn.setSelected(true); + } + } + + } + + public JCheckBox getAlphaHelix() + { + return alphaHelix; + } + + public void setAlphaHelix(JCheckBox alphaHelix) + { + this.alphaHelix = alphaHelix; + } + + public JCheckBox getBetaStrand() + { + return betaStrand; + } + + public void setBetaStrand(JCheckBox betaStrand) + { + this.betaStrand = betaStrand; + } + + public JCheckBox getTurn() + { + return turn; + } + + public void setTurn(JCheckBox turn) + { + this.turn = turn; + } + + public JCheckBox getAll() + { + return all; + } + + public void setAll(JCheckBox all) + { + this.all = all; + + } +} \ No newline at end of file -- 1.7.10.2