From: Jim Procter Date: Wed, 21 Jan 2015 15:04:37 +0000 (+0000) Subject: Merge branch 'develop' into feature_29/JAL-1372_referenceseq X-Git-Tag: Jalview_2_9~108^2~14 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=e4868e3c7279d9c5719dc0394eadedbcd6f21348;hp=5f9c8558cfee09b2ba2a13226f5bd4188e299135;p=jalview.git Merge branch 'develop' into feature_29/JAL-1372_referenceseq --- diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 7adae2a..d944b5b 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -1178,3 +1178,16 @@ 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... +label.threshold_filter = Threshold Filter +action.hide = Hide +action.select = Select +label.alpha_helix = Alpha Helix +label.beta_strand = Beta Strand +label.turn = Turn +label.select_all = Select All +label.structures_filter = Structures Filter +label.search_filter = Search Filter +label.display_name = Display Label +label.description = Description diff --git a/src/jalview/controller/AlignViewController.java b/src/jalview/controller/AlignViewController.java index 21cf630..7b42a30 100644 --- a/src/jalview/controller/AlignViewController.java +++ b/src/jalview/controller/AlignViewController.java @@ -20,11 +20,6 @@ */ package jalview.controller; -import java.awt.Color; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.List; - import jalview.analysis.AlignmentSorter; import jalview.api.AlignViewControllerGuiI; import jalview.api.AlignViewControllerI; @@ -33,12 +28,20 @@ import jalview.api.AlignmentViewPanel; import jalview.api.FeatureRenderer; import jalview.commands.OrderCommand; import jalview.datamodel.AlignmentI; +import jalview.datamodel.Annotation; import jalview.datamodel.ColumnSelection; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.util.MessageManager; +import jalview.viewmodel.annotationfilter.AnnotationFilterParameter; +import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; public class AlignViewController implements AlignViewControllerI { @@ -100,7 +103,9 @@ public class AlignViewController implements AlignViewControllerI (int) (Math.random() * 255), (int) (Math.random() * 255)); col = col.brighter(); for (SequenceI sq : gps[g].getSequences(null)) + { viewport.setSequenceColour(sq, col); + } } return true; } @@ -300,6 +305,91 @@ public class AlignViewController implements AlignViewControllerI } } + public static boolean filterAnnotations(Annotation[] annotations, + AnnotationFilterParameter filterParams, ColumnSelection cs) + { + cs.revealAllHiddenColumns(); + cs.clear(); + int count = 0; + do + { + if (annotations[count] != null) + { + + boolean itemMatched = false; + + if (filterParams.getThresholdType() == AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD + && annotations[count].value > filterParams + .getThresholdValue()) + { + itemMatched = true; + } + if (filterParams.getThresholdType() == AnnotationFilterParameter.ThresholdType.BELOW_THRESHOLD + && annotations[count].value < filterParams + .getThresholdValue()) + { + itemMatched = true; + } + + if (filterParams.isFilterAlphaHelix() + && annotations[count].secondaryStructure == 'H') + { + itemMatched = true; + } + + if (filterParams.isFilterBetaSheet() + && annotations[count].secondaryStructure == 'E') + { + itemMatched = true; + } + + if (filterParams.isFilterTurn() + && annotations[count].secondaryStructure == 'S') + { + itemMatched = true; + } + + String regexSearchString = filterParams.getRegexString(); + if (regexSearchString != null + && !filterParams.getRegexSearchFields().isEmpty()) + { + List fields = filterParams + .getRegexSearchFields(); + try + { + if (fields.contains(SearchableAnnotationField.DISPLAY_STRING) + && annotations[count].displayCharacter + .matches(regexSearchString)) + { + itemMatched = true; + } + } 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; + } + } + + if (itemMatched) + { + cs.addElement(count); + } + } + count++; + } while (count < annotations.length); + return false; + } + @Override public void sortAlignmentByFeatureDensity(String[] typ) { diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 5c42418..0206c46 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -3325,6 +3325,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } @Override + public void annotationColumn_actionPerformed(ActionEvent e) + { + new AnnotationColumnChooser(viewport, alignPanel); + } + + @Override public void rnahelicesColour_actionPerformed(ActionEvent e) { new RNAHelicesColourChooser(viewport, alignPanel); diff --git a/src/jalview/gui/AlignViewport.java b/src/jalview/gui/AlignViewport.java index 38f0ea1..b8f575f 100644 --- a/src/jalview/gui/AlignViewport.java +++ b/src/jalview/gui/AlignViewport.java @@ -138,6 +138,9 @@ public class AlignViewport extends AlignmentViewport implements Color textColour = Color.black; Color textColour2 = Color.white; + private boolean rightAlignIds = false; + + private AnnotationColumnChooser annotationColumnSelectionState; /** * Creates a new AlignViewport object. * @@ -1231,4 +1234,31 @@ public class AlignViewport extends AlignmentViewport implements { this.showAutocalculatedAbove = showAutocalculatedAbove; } + + + public boolean isShowAnnotation() + { + return super.isShowAnnotation(); + } + + public boolean isRightAlignIds() + { + return rightAlignIds; + } + + public void setRightAlignIds(boolean rightAlignIds) + { + this.rightAlignIds = rightAlignIds; + } + + public AnnotationColumnChooser getAnnotationColumnSelectionState() + { + return annotationColumnSelectionState; + } + + public void setAnnotationColumnSelectionState( + AnnotationColumnChooser currentAnnotationColumnSelectionState) + { + this.annotationColumnSelectionState = currentAnnotationColumnSelectionState; + } } diff --git a/src/jalview/gui/AnnotationColourChooser.java b/src/jalview/gui/AnnotationColourChooser.java index b8996b6..3c6fd88 100644 --- a/src/jalview/gui/AnnotationColourChooser.java +++ b/src/jalview/gui/AnnotationColourChooser.java @@ -21,8 +21,6 @@ package jalview.gui; import jalview.bin.Cache; -import jalview.datamodel.AlignmentAnnotation; -import jalview.datamodel.GraphLine; import jalview.datamodel.SequenceGroup; import jalview.schemes.AnnotationColourGradient; import jalview.schemes.ColourSchemeI; @@ -37,51 +35,53 @@ import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Hashtable; -import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.JButton; -import javax.swing.JCheckBox; import javax.swing.JColorChooser; import javax.swing.JComboBox; import javax.swing.JInternalFrame; import javax.swing.JLayeredPane; import javax.swing.JPanel; -import javax.swing.JSlider; -import javax.swing.JTextField; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import net.miginfocom.swing.MigLayout; -public class AnnotationColourChooser extends JPanel +@SuppressWarnings("serial") +public class AnnotationColourChooser extends AnnotationRowFilter { - JInternalFrame frame; - - AlignViewport av; - - AlignmentPanel ap; ColourSchemeI oldcs; - Hashtable oldgroupColours; - - jalview.datamodel.AlignmentAnnotation currentAnnotation; - - boolean adjusting = false; + Hashtable oldgroupColours; /** * enabled if the user is dragging the slider - try to keep updates to a * minimun */ - boolean sliderDragging = false; + + JComboBox annotations; + + JButton defColours = new JButton(); + + JButton ok = new JButton(); + + JButton cancel = new JButton(); + + JPanel jPanel1 = new JPanel(); + + JPanel jPanel2 = new JPanel(); + + BorderLayout borderLayout1 = new BorderLayout(); + + private JComboBox threshold = new JComboBox(); public AnnotationColourChooser(AlignViewport av, final AlignmentPanel ap) { + super(av, ap); oldcs = av.getGlobalColourScheme(); if (av.getAlignment().getGroups() != null) { - oldgroupColours = new Hashtable(); + oldgroupColours = new Hashtable(); for (SequenceGroup sg : ap.av.getAlignment().getGroups()) { if (sg.cs != null) @@ -90,8 +90,6 @@ public class AnnotationColourChooser extends JPanel } } } - this.av = av; - this.ap = ap; frame = new JInternalFrame(); frame.setContentPane(this); frame.setLayer(JLayeredPane.PALETTE_LAYER); @@ -99,45 +97,8 @@ public class AnnotationColourChooser extends JPanel MessageManager.getString("label.colour_by_annotation"), 520, 215); - slider.addChangeListener(new ChangeListener() - { - @Override - public void stateChanged(ChangeEvent evt) - { - if (!adjusting) - { - thresholdValue.setText((slider.getValue() / 1000f) + ""); - valueChanged(!sliderDragging); - } - } - }); - slider.addMouseListener(new MouseAdapter() - { - @Override - public void mousePressed(MouseEvent e) - { - sliderDragging = true; - super.mousePressed(e); - } - - @Override - public void mouseDragged(MouseEvent e) - { - sliderDragging = true; - super.mouseDragged(e); - } - - @Override - public void mouseReleased(MouseEvent evt) - { - if (sliderDragging) - { - sliderDragging = false; - valueChanged(true); - } - ap.paintAlignment(true); - } - }); + addSliderChangeListener(); + addSliderMouseListeners(); if (av.getAlignment().getAlignmentAnnotation() == null) { @@ -161,15 +122,10 @@ public class AnnotationColourChooser extends JPanel seqAssociated.setSelected(acg.isSeqAssociated()); } - annotations = new JComboBox( + annotations = new JComboBox( getAnnotationItems(seqAssociated.isSelected())); - threshold.addItem(MessageManager - .getString("label.threshold_feature_no_thereshold")); - threshold.addItem(MessageManager - .getString("label.threshold_feature_above_thereshold")); - threshold.addItem(MessageManager - .getString("label.threshold_feature_below_thereshold")); + populateThresholdComboBox(threshold); if (oldcs instanceof AnnotationColourGradient) { @@ -178,13 +134,13 @@ public class AnnotationColourChooser extends JPanel switch (acg.getAboveThreshold()) { case AnnotationColourGradient.NO_THRESHOLD: - threshold.setSelectedIndex(0); + getThreshold().setSelectedIndex(0); break; case AnnotationColourGradient.ABOVE_THRESHOLD: - threshold.setSelectedIndex(1); + getThreshold().setSelectedIndex(1); break; case AnnotationColourGradient.BELOW_THRESHOLD: - threshold.setSelectedIndex(2); + getThreshold().setSelectedIndex(2); break; default: throw new Error(MessageManager.getString("error.implementation_error_dont_know_about_thereshold_setting")); @@ -199,62 +155,11 @@ public class AnnotationColourChooser extends JPanel } catch (Exception ex) { } - adjusting = false; - changeColour(); + updateView(); frame.invalidate(); frame.pack(); - - } - - private Vector getAnnotationItems(boolean isSeqAssociated) - { - Vector list = new Vector(); - int index = 1; - int[] anmap = new int[av.getAlignment().getAlignmentAnnotation().length]; - boolean enableSeqAss = false; - for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++) - { - if (av.getAlignment().getAlignmentAnnotation()[i].sequenceRef == null) - { - if (isSeqAssociated) - { - continue; - } - } - else - { - enableSeqAss = true; - } - String label = av.getAlignment().getAlignmentAnnotation()[i].label; - if (!list.contains(label)) - { - anmap[list.size()] = i; - list.add(label); - - } - else - { - if (!isSeqAssociated) - { - anmap[list.size()] = i; - list.add(label + "_" + (index++)); - } - } - } - seqAssociated.setEnabled(enableSeqAss); - this.annmap = new int[list.size()]; - System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length); - return list; - } - - private void setDefaultMinMax() - { - minColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", - Color.orange)); - maxColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", - Color.red)); } public AnnotationColourChooser() @@ -342,7 +247,7 @@ public class AnnotationColourChooser extends JPanel annotations_actionPerformed(e); } }); - threshold.addActionListener(new ActionListener() + getThreshold().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) @@ -400,7 +305,7 @@ public class AnnotationColourChooser extends JPanel @Override public void actionPerformed(ActionEvent arg0) { - seqAssociated_actionPerformed(arg0); + seqAssociated_actionPerformed(arg0, annotations, seqAssociated); } }); @@ -419,7 +324,7 @@ public class AnnotationColourChooser extends JPanel colpanel.add(minColour); colpanel.add(maxColour); jPanel2.add(colpanel, "wrap"); - jPanel2.add(threshold); + jPanel2.add(getThreshold()); jPanel2.add(defColours, "skip 1, wrap"); jPanel2.add(thresholdIsMin); jPanel2.add(slider, "grow"); @@ -429,72 +334,19 @@ public class AnnotationColourChooser extends JPanel this.validate(); } - protected void seqAssociated_actionPerformed(ActionEvent arg0) - { - adjusting = true; - String cursel = (String) annotations.getSelectedItem(); - boolean isvalid = false, isseqs = seqAssociated.isSelected(); - this.annotations.removeAllItems(); - for (String anitem : getAnnotationItems(seqAssociated.isSelected())) - { - if (anitem.equals(cursel) || (isseqs && cursel.startsWith(anitem))) - { - isvalid = true; - cursel = anitem; - } - this.annotations.addItem(anitem); - } - adjusting = false; - if (isvalid) - { - this.annotations.setSelectedItem(cursel); - } - else - { - if (annotations.getItemCount() > 0) - { - annotations.setSelectedIndex(0); - } - } - } - protected void resetColours_actionPerformed(ActionEvent arg0) { setDefaultMinMax(); - changeColour(); + updateView(); } - JComboBox annotations; - - int[] annmap; - - JPanel minColour = new JPanel(); - - JPanel maxColour = new JPanel(); - - JButton defColours = new JButton(); - - JButton ok = new JButton(); - - JButton cancel = new JButton(); - - JPanel jPanel1 = new JPanel(); - - JPanel jPanel2 = new JPanel(); - - BorderLayout borderLayout1 = new BorderLayout(); - - JComboBox threshold = new JComboBox(); - - JSlider slider = new JSlider(); - - JTextField thresholdValue = new JTextField(20); - - JCheckBox currentColours = new JCheckBox(); - - JCheckBox thresholdIsMin = new JCheckBox(); - - JCheckBox seqAssociated = new JCheckBox(); + private void setDefaultMinMax() + { + minColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", + Color.orange)); + maxColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", + Color.red)); + } public void minColour_actionPerformed() { @@ -505,7 +357,7 @@ public class AnnotationColourChooser extends JPanel minColour.setBackground(col); } minColour.repaint(); - changeColour(); + updateView(); } public void maxColour_actionPerformed() @@ -517,247 +369,115 @@ public class AnnotationColourChooser extends JPanel maxColour.setBackground(col); } maxColour.repaint(); - changeColour(); + updateView(); } - void changeColour() + public void reset() { - // Check if combobox is still adjusting - if (adjusting) - { - return; - } - - currentAnnotation = av.getAlignment().getAlignmentAnnotation()[annmap[annotations - .getSelectedIndex()]]; - - int aboveThreshold = -1; - if (threshold.getSelectedIndex() == 1) - { - aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD; - } - else if (threshold.getSelectedIndex() == 2) - { - aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD; - } - - slider.setEnabled(true); - thresholdValue.setEnabled(true); - thresholdIsMin.setEnabled(true); - - if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD) - { - slider.setEnabled(false); - thresholdValue.setEnabled(false); - thresholdValue.setText(""); - thresholdIsMin.setEnabled(false); - } - else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD - && currentAnnotation.threshold == null) - { - currentAnnotation - .setThreshold(new jalview.datamodel.GraphLine( - (currentAnnotation.graphMax - currentAnnotation.graphMin) / 2f, - "Threshold", Color.black)); - } - - if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD) - { - adjusting = true; - float range = currentAnnotation.graphMax * 1000 - - currentAnnotation.graphMin * 1000; - - slider.setMinimum((int) (currentAnnotation.graphMin * 1000)); - slider.setMaximum((int) (currentAnnotation.graphMax * 1000)); - slider.setValue((int) (currentAnnotation.threshold.value * 1000)); - thresholdValue.setText(currentAnnotation.threshold.value + ""); - slider.setMajorTickSpacing((int) (range / 10f)); - slider.setEnabled(true); - thresholdValue.setEnabled(true); - adjusting = false; - } - - AnnotationColourGradient acg = null; - if (currentColours.isSelected()) - { - acg = new AnnotationColourGradient(currentAnnotation, - av.getGlobalColourScheme(), aboveThreshold); - } - else - { - acg = new AnnotationColourGradient(currentAnnotation, - minColour.getBackground(), maxColour.getBackground(), - aboveThreshold); - } - acg.setSeqAssociated(seqAssociated.isSelected()); - - if (currentAnnotation.graphMin == 0f - && currentAnnotation.graphMax == 0f) - { - acg.setPredefinedColours(true); - } - - acg.thresholdIsMinMax = thresholdIsMin.isSelected(); - - av.setGlobalColourScheme(acg); - + av.setGlobalColourScheme(oldcs); if (av.getAlignment().getGroups() != null) { for (SequenceGroup sg : ap.av.getAlignment().getGroups()) { - if (sg.cs == null) - { - continue; - } - - if (currentColours.isSelected()) - { - sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs, - aboveThreshold); - ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated - .isSelected()); - - } - else - { - sg.cs = new AnnotationColourGradient(currentAnnotation, - minColour.getBackground(), maxColour.getBackground(), - aboveThreshold); - ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated - .isSelected()); - } - + sg.cs = oldgroupColours.get(sg); } } - ap.alignmentChanged(); - // ensure all associated views (overviews, structures, etc) are notified of - // updated colours. - ap.paintAlignment(true); - } - - public void ok_actionPerformed(ActionEvent e) - { - changeColour(); - try - { - frame.setClosed(true); - } catch (Exception ex) - { - } - } - - public void cancel_actionPerformed(ActionEvent e) - { - reset(); - // ensure all original colouring is propagated to listeners. - ap.paintAlignment(true); - try - { - frame.setClosed(true); - } catch (Exception ex) - { - } } - void reset() + public void valueChanged(boolean updateAllAnnotation) { - av.setGlobalColourScheme(oldcs); - if (av.getAlignment().getGroups() != null) + if (slider.isEnabled()) { - - for (SequenceGroup sg : ap.av.getAlignment().getGroups()) + if (currentColours.isSelected() + && !(av.getGlobalColourScheme() instanceof AnnotationColourGradient)) { - sg.cs = (ColourSchemeI) oldgroupColours.get(sg); + updateView(); } + getCurrentAnnotation().threshold.value = slider.getValue() / 1000f; + propagateSeqAssociatedThreshold(updateAllAnnotation, + getCurrentAnnotation()); + ap.paintAlignment(false); } } - public void thresholdCheck_actionPerformed(ActionEvent e) - { - changeColour(); - } - - public void annotations_actionPerformed(ActionEvent e) - { - changeColour(); - } - - public void threshold_actionPerformed(ActionEvent e) + public JComboBox getThreshold() { - changeColour(); + return threshold; } - public void thresholdValue_actionPerformed(ActionEvent e) + public void setThreshold(JComboBox threshold) { - try - { - float f = Float.parseFloat(thresholdValue.getText()); - slider.setValue((int) (f * 1000)); - } catch (NumberFormatException ex) - { - } + this.threshold = threshold; } - public void valueChanged(boolean updateAllAnnotation) + public void currentColours_actionPerformed(ActionEvent e) { - if (currentColours.isSelected() - && !(av.getGlobalColourScheme() instanceof AnnotationColourGradient)) + if (currentColours.isSelected()) { - changeColour(); + reset(); } - currentAnnotation.threshold.value = slider.getValue() / 1000f; - propagateSeqAssociatedThreshold(updateAllAnnotation); - ap.paintAlignment(false); + maxColour.setEnabled(!currentColours.isSelected()); + minColour.setEnabled(!currentColours.isSelected()); + updateView(); } - private void propagateSeqAssociatedThreshold(boolean allAnnotation) + @Override + public void updateView() { - if (currentAnnotation.sequenceRef == null - || currentAnnotation.threshold == null) + // Check if combobox is still adjusting + if (adjusting) { return; } - // TODO: JAL-1327 only update visible annotation thresholds if allAnnotation - // is false, since we only need to provide a quick visual indicator - float thr = currentAnnotation.threshold.value; - for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++) + setCurrentAnnotation(av.getAlignment().getAlignmentAnnotation()[annmap[annotations + .getSelectedIndex()]]); + + int selectedThresholdItem = getSelectedThresholdItem(getThreshold() + .getSelectedIndex()); + + slider.setEnabled(true); + thresholdValue.setEnabled(true); + thresholdIsMin.setEnabled(true); + + if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD) { - AlignmentAnnotation aa = av.getAlignment().getAlignmentAnnotation()[i]; - if (aa.label.equals(currentAnnotation.label) - && (currentAnnotation.getCalcId() == null ? aa.getCalcId() == null - : currentAnnotation.getCalcId() - .equals(aa.getCalcId()))) - { - if (aa.threshold == null) - { - aa.threshold = new GraphLine(currentAnnotation.threshold); - } - else - { - aa.threshold.value = thr; - } - } + slider.setEnabled(false); + thresholdValue.setEnabled(false); + thresholdValue.setText(""); + thresholdIsMin.setEnabled(false); } - } - - public void currentColours_actionPerformed(ActionEvent e) - { - if (currentColours.isSelected()) + else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD + && getCurrentAnnotation().threshold == null) { - reset(); + getCurrentAnnotation() + .setThreshold(new jalview.datamodel.GraphLine( + (getCurrentAnnotation().graphMax - getCurrentAnnotation().graphMin) / 2f, + "Threshold", Color.black)); } - maxColour.setEnabled(!currentColours.isSelected()); - minColour.setEnabled(!currentColours.isSelected()); + if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD) + { + adjusting = true; + float range = getCurrentAnnotation().graphMax * 1000 + - getCurrentAnnotation().graphMin * 1000; - changeColour(); - } + slider.setMinimum((int) (getCurrentAnnotation().graphMin * 1000)); + slider.setMaximum((int) (getCurrentAnnotation().graphMax * 1000)); + slider.setValue((int) (getCurrentAnnotation().threshold.value * 1000)); + thresholdValue.setText(getCurrentAnnotation().threshold.value + ""); + slider.setMajorTickSpacing((int) (range / 10f)); + slider.setEnabled(true); + thresholdValue.setEnabled(true); + adjusting = false; + } + colorAlignmContaining(getCurrentAnnotation(), selectedThresholdItem); - public void thresholdIsMin_actionPerformed(ActionEvent actionEvent) - { - changeColour(); + ap.alignmentChanged(); + // ensure all associated views (overviews, structures, etc) are notified of + // updated colours. + ap.paintAlignment(true); } } diff --git a/src/jalview/gui/AnnotationColumnChooser.java b/src/jalview/gui/AnnotationColumnChooser.java new file mode 100644 index 0000000..9f3aa7b --- /dev/null +++ b/src/jalview/gui/AnnotationColumnChooser.java @@ -0,0 +1,870 @@ +package jalview.gui; + +import jalview.controller.AlignViewController; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.ColumnSelection; +import jalview.schemes.AnnotationColourGradient; +import jalview.util.MessageManager; +import jalview.viewmodel.annotationfilter.AnnotationFilterParameter; + +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.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JInternalFrame; +import javax.swing.JLayeredPane; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JTextField; +import javax.swing.border.TitledBorder; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import net.miginfocom.swing.MigLayout; + +@SuppressWarnings("serial") +public class AnnotationColumnChooser extends AnnotationRowFilter implements + ItemListener +{ + + private JComboBox annotations; + + private JButton ok = new JButton(); + + private JButton cancel = new JButton(); + + private JPanel actionPanel = new JPanel(); + + private JPanel thresholdPanel = new JPanel(); + + private JPanel switchableViewsPanel = new JPanel(new CardLayout()); + + private CardLayout switchableViewsLayout = (CardLayout) (switchableViewsPanel + .getLayout()); + + private JPanel noGraphFilterView = new JPanel(); + + private JPanel graphFilterView = new JPanel(); + + private JPanel annotationComboBoxPanel = new JPanel(); + + private BorderLayout borderLayout1 = new BorderLayout(); + + private JComboBox threshold = new JComboBox(); + + private StructureFilterPanel gStructureFilterPanel; + + private StructureFilterPanel ngStructureFilterPanel; + + private StructureFilterPanel currentStructureFilterPanel; + + 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; + + private ColumnSelection oldColumnSelection; + + public AnnotationColumnChooser() + { + try + { + jbInit(); + } catch (Exception ex) + { + ex.printStackTrace(); + } + } + + public AnnotationColumnChooser(AlignViewport av, final AlignmentPanel ap) + { + super(av, ap); + frame = new JInternalFrame(); + frame.setContentPane(this); + frame.setLayer(JLayeredPane.PALETTE_LAYER); + Desktop.addInternalFrame(frame, + MessageManager.getString("label.select_by_annotation"), 520, + 215); + + addSliderChangeListener(); + addSliderMouseListeners(); + + if (av.getAlignment().getAlignmentAnnotation() == null) + { + return; + } + setOldColumnSelection(av.getColumnSelection()); + adjusting = true; + + setAnnotations(new JComboBox(getAnnotationItems(false))); + populateThresholdComboBox(threshold); + + // restore Object state from the previous session if one exists + if (av.getAnnotationColumnSelectionState() != null) + { + 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 + { + jbInit(); + } catch (Exception ex) + { + } + adjusting = false; + + updateView(); + frame.invalidate(); + frame.pack(); + } + + private void jbInit() throws Exception + { + ok.setOpaque(false); + ok.setText(MessageManager.getString("action.ok")); + ok.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + ok_actionPerformed(e); + } + }); + + cancel.setOpaque(false); + cancel.setText(MessageManager.getString("action.cancel")); + cancel.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + cancel_actionPerformed(e); + } + }); + + annotations.addItemListener(this); + threshold.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + threshold_actionPerformed(e); + } + }); + + thresholdValue.setEnabled(false); + thresholdValue.setColumns(7); + thresholdValue.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + thresholdValue_actionPerformed(e); + } + }); + + slider.setPaintLabels(false); + slider.setPaintTicks(true); + slider.setBackground(Color.white); + slider.setEnabled(false); + slider.setOpaque(false); + slider.setPreferredSize(new Dimension(100, 32)); + + thresholdPanel.setBorder(new TitledBorder(MessageManager + .getString("label.threshold_filter"))); + thresholdPanel.setBackground(Color.white); + thresholdPanel.setFont(JvSwingUtils.getLabelFont()); + thresholdPanel.setLayout(new MigLayout("", "[left][right]", "[][]")); + + actionPanel.setBackground(Color.white); + actionPanel.setFont(JvSwingUtils.getLabelFont()); + + 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.setLayout(borderLayout1); + 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() + { + 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.paintAlignment(true); + } + + } + + public void valueChanged(boolean updateAllAnnotation) + { + if (slider.isEnabled()) + { + getCurrentAnnotation().threshold.value = slider.getValue() / 1000f; + updateView(); + propagateSeqAssociatedThreshold(updateAllAnnotation, + getCurrentAnnotation()); + ap.paintAlignment(false); + } + } + + public JComboBox getThreshold() + { + return threshold; + } + + public void setThreshold(JComboBox threshold) + { + this.threshold = threshold; + } + + public JComboBox getAnnotations() + { + return annotations; + } + + public void setAnnotations(JComboBox annotations) + { + this.annotations = annotations; + } + + @Override + public void updateView() + { + // 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); + + if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD) + { + slider.setEnabled(false); + thresholdValue.setEnabled(false); + thresholdValue.setText(""); + // build filter params + } + else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD) + { + if (getCurrentAnnotation().threshold == null) + { + getCurrentAnnotation() + .setThreshold( + new jalview.datamodel.GraphLine( + (getCurrentAnnotation().graphMax - getCurrentAnnotation().graphMin) / 2f, + "Threshold", Color.black)); + } + + adjusting = true; + float range = getCurrentAnnotation().graphMax * 1000 + - getCurrentAnnotation().graphMin * 1000; + + slider.setMinimum((int) (getCurrentAnnotation().graphMin * 1000)); + slider.setMaximum((int) (getCurrentAnnotation().graphMax * 1000)); + slider.setValue((int) (getCurrentAnnotation().threshold.value * 1000)); + thresholdValue.setText(getCurrentAnnotation().threshold.value + ""); + slider.setMajorTickSpacing((int) (range / 10f)); + slider.setEnabled(true); + thresholdValue.setEnabled(true); + adjusting = false; + + // build filter params + filterParams + .setThresholdType(AnnotationFilterParameter.ThresholdType.NO_THRESHOLD); + if (getCurrentAnnotation().graph != AlignmentAnnotation.NO_GRAPH) + { + filterParams + .setThresholdValue(getCurrentAnnotation().threshold.value); + + 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.alphaHelix.isSelected()) + { + filterParams.setFilterAlphaHelix(true); + } + if (currentStructureFilterPanel.betaStrand.isSelected()) + { + filterParams.setFilterBetaSheet(true); + } + if (currentStructureFilterPanel.turn.isSelected()) + { + filterParams.setFilterTurn(true); + } + } + + if (currentSearchPanel != null) + { + + if (!currentSearchPanel.searchBox.getText().isEmpty()) + { + currentSearchPanel.description.setEnabled(true); + currentSearchPanel.displayName.setEnabled(true); + filterParams.setRegexString(currentSearchPanel.searchBox.getText()); + if (currentSearchPanel.displayName.isSelected()) + { + filterParams + .addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DISPLAY_STRING); + } + if (currentSearchPanel.description.isSelected()) + { + filterParams + .addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DESCRIPTION); + } + } + else + { + currentSearchPanel.description.setEnabled(false); + currentSearchPanel.displayName.setEnabled(false); + } + } + + AlignViewController.filterAnnotations( + getCurrentAnnotation().annotations, filterParams, + av.getColumnSelection()); + + av.showAllHiddenColumns(); + if (getActionOption() == ACTION_OPTION_HIDE) + { + av.hideSelectedColumns(); + } + + filterParams = null; + av.setAnnotationColumnSelectionState(this); + ap.paintAlignment(true); + } + + public ColumnSelection getOldColumnSelection() + { + return oldColumnSelection; + } + + public void setOldColumnSelection(ColumnSelection currentColumnSelection) + { + if (currentColumnSelection != null) + { + this.oldColumnSelection = new ColumnSelection(currentColumnSelection); + } + } + + 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; + } + + 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; + } + + gSearchPanel.syncState(); + gFurtherActionPanel.syncState(); + gStructureFilterPanel.syncState(); + + ngSearchPanel.syncState(); + ngFurtherActionPanel.syncState(); + ngStructureFilterPanel.syncState(); + + switchableViewsLayout.show(switchableViewsPanel, currentView); + updateView(); + } + + + 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; + JvSwingUtils.jvInitComponent(selectOption, "action.select"); + selectOption.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + selectRadioAction(actionEvent); + } + }); + + JvSwingUtils.jvInitComponent(hideOption, "action.hide"); + hideOption.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + hideRadioAction(actionEvent); + } + }); + + optionsGroup.add(selectOption); + optionsGroup.add(hideOption); + optionsGroup.setSelected(selectOption.getModel(), true); + + JvSwingUtils.jvInitComponent(this); + syncState(); + + this.add(selectOption); + this.add(hideOption); + } + + 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 void syncState() + { + if (aColChooser.getActionOption() == AnnotationColumnChooser.ACTION_OPTION_HIDE) + { + this.optionsGroup.setSelected(this.hideOption.getModel(), + true); + } + else + { + this.optionsGroup.setSelected(this.selectOption.getModel(), true); + } + } + } + + 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; + + JvSwingUtils.jvInitComponent(alphaHelix, "label.alpha_helix"); + alphaHelix.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + alphaHelix_actionPerformed(); + } + }); + + JvSwingUtils.jvInitComponent(betaStrand, "label.beta_strand"); + betaStrand.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + betaStrand_actionPerformed(); + } + }); + + JvSwingUtils.jvInitComponent(turn, "label.turn"); + turn.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + turn_actionPerformed(); + } + }); + + JvSwingUtils.jvInitComponent(all, "label.select_all"); + all.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + all_actionPerformed(); + } + }); + + this.setBorder(new TitledBorder(MessageManager + .getString("label.structures_filter"))); + JvSwingUtils.jvInitComponent(this); + + 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.alphaHelix.isSelected()); + betaStrand.setSelected(sfp.betaStrand.isSelected()); + turn.setSelected(sfp.turn.isSelected()); + if (sfp.all.isSelected()) + { + all.setSelected(true); + alphaHelix.setSelected(true); + betaStrand.setSelected(true); + turn.setSelected(true); + } + } + + } + } + + public class SearchPanel extends JPanel + { + private AnnotationColumnChooser aColChooser; + + private JCheckBox displayName = new JCheckBox(); + + private JCheckBox description = new JCheckBox(); + + private JTextField searchBox = new JTextField(10); + + public SearchPanel(AnnotationColumnChooser aColChooser) + { + + this.aColChooser = aColChooser; + JvSwingUtils.jvInitComponent(this); + this.setBorder(new TitledBorder(MessageManager + .getString("label.search_filter"))); + + JvSwingUtils.jvInitComponent(searchBox); + searchBox.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(); + } + }); + + JvSwingUtils.jvInitComponent(displayName, "label.display_name"); + displayName.setEnabled(false); + displayName.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + displayNameCheckboxAction(); + } + }); + + JvSwingUtils.jvInitComponent(description, "label.description"); + description.setEnabled(false); + description.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + discriptionCheckboxAction(); + } + }); + + syncState(); + this.add(searchBox); + this.add(displayName); + this.add(description); + } + + 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 void syncState() + { + SearchPanel sp = aColChooser.getCurrentSearchPanel(); + if (sp != null) + { + description.setEnabled(sp.description.isEnabled()); + description.setSelected(sp.description.isSelected()); + + displayName.setEnabled(sp.displayName.isEnabled()); + displayName.setSelected(sp.displayName.isSelected()); + + searchBox.setText(sp.searchBox.getText()); + } + } + } + +} diff --git a/src/jalview/gui/AnnotationRowFilter.java b/src/jalview/gui/AnnotationRowFilter.java new file mode 100644 index 0000000..c0eea38 --- /dev/null +++ b/src/jalview/gui/AnnotationRowFilter.java @@ -0,0 +1,378 @@ +package jalview.gui; + +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.GraphLine; +import jalview.datamodel.SequenceGroup; +import jalview.schemes.AnnotationColourGradient; +import jalview.util.MessageManager; + +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Vector; + +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JInternalFrame; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.JTextField; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +@SuppressWarnings("serial") +public abstract class AnnotationRowFilter extends JPanel +{ + protected AlignViewport av; + + protected AlignmentPanel ap; + + protected int[] annmap; + + protected boolean enableSeqAss = false; + + private jalview.datamodel.AlignmentAnnotation currentAnnotation; + + protected boolean adjusting = false; + + protected JCheckBox currentColours = new JCheckBox(); + + protected JPanel minColour = new JPanel(); + + protected JPanel maxColour = new JPanel(); + + protected JCheckBox seqAssociated = new JCheckBox(); + + protected JCheckBox thresholdIsMin = new JCheckBox(); + + protected JSlider slider = new JSlider(); + + protected JTextField thresholdValue = new JTextField(20); + + protected JInternalFrame frame; + /** + * enabled if the user is dragging the slider - try to keep updates to a + * minimun + */ + protected boolean sliderDragging = false; + + protected void addSliderChangeListener() + { + + slider.addChangeListener(new ChangeListener() + { + @Override + public void stateChanged(ChangeEvent evt) + { + if (!adjusting) + { + thresholdValue.setText((slider.getValue() / 1000f) + ""); + valueChanged(!sliderDragging); + } + } + }); + } + + protected void addSliderMouseListeners() + { + + slider.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent e) + { + sliderDragging = true; + super.mousePressed(e); + } + + @Override + public void mouseDragged(MouseEvent e) + { + sliderDragging = true; + super.mouseDragged(e); + } + + @Override + public void mouseReleased(MouseEvent evt) + { + if (sliderDragging) + { + sliderDragging = false; + valueChanged(true); + } + ap.paintAlignment(true); + } + }); + } + + + public AnnotationRowFilter(AlignViewport av, final AlignmentPanel ap) + { + this.av = av; + this.ap = ap; + } + + public AnnotationRowFilter() + { + + } + + public Vector getAnnotationItems(boolean isSeqAssociated) + { + Vector list = new Vector(); + int index = 1; + int[] anmap = new int[av.getAlignment().getAlignmentAnnotation().length]; + for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++) + { + if (av.getAlignment().getAlignmentAnnotation()[i].sequenceRef == null) + { + if (isSeqAssociated) + { + continue; + } + } + else + { + enableSeqAss = true; + } + String label = av.getAlignment().getAlignmentAnnotation()[i].label; + if (!list.contains(label)) + { + anmap[list.size()] = i; + list.add(label); + + } + else + { + if (!isSeqAssociated) + { + anmap[list.size()] = i; + list.add(label + "_" + (index++)); + } + } + } + this.annmap = new int[list.size()]; + System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length); + return list; + } + + protected int getSelectedThresholdItem(int indexValue) + { + int selectedThresholdItem = -1; + if (indexValue == 1) + { + selectedThresholdItem = AnnotationColourGradient.ABOVE_THRESHOLD; + } + else if (indexValue == 2) + { + selectedThresholdItem = AnnotationColourGradient.BELOW_THRESHOLD; + } + return selectedThresholdItem; + } + + public void modelChanged() + { + seqAssociated.setEnabled(enableSeqAss); + } + + public void ok_actionPerformed(ActionEvent e) + { + updateView(); + try + { + frame.setClosed(true); + } catch (Exception ex) + { + } + } + + public void cancel_actionPerformed(ActionEvent e) + { + reset(); + ap.paintAlignment(true); + try + { + frame.setClosed(true); + } catch (Exception ex) + { + } + } + + public void thresholdCheck_actionPerformed(ActionEvent e) + { + updateView(); + } + + public void annotations_actionPerformed(ActionEvent e) + { + updateView(); + } + + public void threshold_actionPerformed(ActionEvent e) + { + updateView(); + } + + public void thresholdValue_actionPerformed(ActionEvent e) + { + try + { + float f = Float.parseFloat(thresholdValue.getText()); + slider.setValue((int) (f * 1000)); + updateView(); + } catch (NumberFormatException ex) + { + } + } + + public void thresholdIsMin_actionPerformed(ActionEvent actionEvent) + { + updateView(); + } + + protected void populateThresholdComboBox(JComboBox threshold) + { + threshold.addItem(MessageManager + .getString("label.threshold_feature_no_thereshold")); + threshold.addItem(MessageManager + .getString("label.threshold_feature_above_thereshold")); + threshold.addItem(MessageManager + .getString("label.threshold_feature_below_thereshold")); + } + + protected void seqAssociated_actionPerformed(ActionEvent arg0, + JComboBox annotations, JCheckBox seqAssociated) + { + adjusting = true; + String cursel = (String) annotations.getSelectedItem(); + boolean isvalid = false, isseqs = seqAssociated.isSelected(); + annotations.removeAllItems(); + for (String anitem : getAnnotationItems(seqAssociated.isSelected())) + { + if (anitem.equals(cursel) || (isseqs && cursel.startsWith(anitem))) + { + isvalid = true; + cursel = anitem; + } + annotations.addItem(anitem); + } + adjusting = false; + if (isvalid) + { + annotations.setSelectedItem(cursel); + } + else + { + if (annotations.getItemCount() > 0) + { + annotations.setSelectedIndex(0); + } + } + } + + protected void propagateSeqAssociatedThreshold(boolean allAnnotation, + AlignmentAnnotation annotation) + { + if (annotation.sequenceRef == null || annotation.threshold == null) + { + return; + } + + float thr = annotation.threshold.value; + for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++) + { + AlignmentAnnotation aa = av.getAlignment().getAlignmentAnnotation()[i]; + if (aa.label.equals(annotation.label) + && (annotation.getCalcId() == null ? aa.getCalcId() == null + : annotation.getCalcId().equals(aa.getCalcId()))) + { + if (aa.threshold == null) + { + aa.threshold = new GraphLine(annotation.threshold); + } + else + { + aa.threshold.value = thr; + } + } + } + } + + protected boolean colorAlignmContaining( + AlignmentAnnotation currentAnnotation, int selectedThresholdItem) + { + + AnnotationColourGradient acg = null; + if (currentColours.isSelected()) + { + acg = new AnnotationColourGradient(currentAnnotation, + av.getGlobalColourScheme(), selectedThresholdItem); + } + else + { + acg = new AnnotationColourGradient(currentAnnotation, + minColour.getBackground(), maxColour.getBackground(), + selectedThresholdItem); + } + acg.setSeqAssociated(seqAssociated.isSelected()); + + if (currentAnnotation.graphMin == 0f + && currentAnnotation.graphMax == 0f) + { + acg.setPredefinedColours(true); + } + + acg.thresholdIsMinMax = thresholdIsMin.isSelected(); + + av.setGlobalColourScheme(acg); + + if (av.getAlignment().getGroups() != null) + { + + for (SequenceGroup sg : ap.av.getAlignment().getGroups()) + { + if (sg.cs == null) + { + continue; + } + + if (currentColours.isSelected()) + { + sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs, + selectedThresholdItem); + ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated + .isSelected()); + + } + else + { + sg.cs = new AnnotationColourGradient(currentAnnotation, + minColour.getBackground(), maxColour.getBackground(), + selectedThresholdItem); + ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated + .isSelected()); + } + + } + } + return false; + } + + + public jalview.datamodel.AlignmentAnnotation getCurrentAnnotation() + { + return currentAnnotation; + } + + public void setCurrentAnnotation( + jalview.datamodel.AlignmentAnnotation currentAnnotation) + { + this.currentAnnotation = currentAnnotation; + } + + public abstract void valueChanged(boolean updateAllAnnotation); + + public abstract void updateView(); + + public abstract void reset(); +} diff --git a/src/jalview/gui/JvSwingUtils.java b/src/jalview/gui/JvSwingUtils.java index e433243..c404e2f 100644 --- a/src/jalview/gui/JvSwingUtils.java +++ b/src/jalview/gui/JvSwingUtils.java @@ -20,11 +20,14 @@ */ package jalview.gui; +import jalview.util.MessageManager; + import java.awt.Color; import java.awt.Font; import java.awt.Rectangle; import java.awt.event.ActionListener; +import javax.swing.AbstractButton; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; @@ -209,4 +212,28 @@ public final class JvSwingUtils } } + public static void jvInitComponent(AbstractButton comp, String i18nString) + { + setColorAndFont(comp); + if (i18nString != null && !i18nString.isEmpty()) + { + comp.setText(MessageManager.getString(i18nString)); + } + } + + public static void jvInitComponent(JComponent comp) + { + setColorAndFont(comp); + } + + // public static void jvInitComponent(JComponent comp, String name){ + // setColorAndFont(comp); + // comp.setText(MessageManager.getString("label.select_all")); + // } + + private static void setColorAndFont(JComponent comp) + { + comp.setBackground(Color.white); + comp.setFont(JvSwingUtils.getLabelFont()); + } } 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/io/AppletFormatAdapter.java b/src/jalview/io/AppletFormatAdapter.java index 505f609..89adead 100755 --- a/src/jalview/io/AppletFormatAdapter.java +++ b/src/jalview/io/AppletFormatAdapter.java @@ -64,16 +64,16 @@ public class AppletFormatAdapter * that are writable by the application. */ public static final String[] WRITABLE_EXTENSIONS = new String[] - { "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa", - "jvp", "sto,stk", "jar", PhylipFile.FILE_EXT }; + { "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa", + "sto,stk", PhylipFile.FILE_EXT, "jvp" }; /** * List of writable formats by the application. Order must correspond with the * WRITABLE_EXTENSIONS list of formats. */ public static final String[] WRITABLE_FNAMES = new String[] - { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Jalview", - "STH", "Jalview", PhylipFile.FILE_DESC }; + { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "STH", + PhylipFile.FILE_DESC, "Jalview" }; /** * List of readable format file extensions by application in order diff --git a/src/jalview/jbgui/GAlignFrame.java b/src/jalview/jbgui/GAlignFrame.java index 4bf8176..4ecedaf 100755 --- a/src/jalview/jbgui/GAlignFrame.java +++ b/src/jalview/jbgui/GAlignFrame.java @@ -268,6 +268,8 @@ public class GAlignFrame extends JInternalFrame JMenuItem annotationColour = new JMenuItem(); + JMenuItem annotationColumn = new JMenuItem(); + protected JMenuItem rnahelicesColour = new JMenuItem(); JMenuItem associatedData = new JMenuItem(); @@ -1874,6 +1876,17 @@ public class GAlignFrame extends JInternalFrame } }); + annotationColumn.setText(MessageManager + .getString("action.select_by_annotation")); + annotationColumn.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + annotationColumn_actionPerformed(e); + } + }); + rnahelicesColour.setText(MessageManager .getString("action.by_rna_helixes")); rnahelicesColour.addActionListener(new ActionListener() @@ -2408,6 +2421,7 @@ public class GAlignFrame extends JInternalFrame selectMenu.add(unGroup); selectMenu.add(grpsFromSelection); selectMenu.add(deleteGroups); + selectMenu.add(annotationColumn); calculateMenu.add(expandAlignment); // TODO - determine if the listenToViewSelections button is needed : see bug // JAL-574 @@ -2986,6 +3000,11 @@ public class GAlignFrame extends JInternalFrame } + public void annotationColumn_actionPerformed(ActionEvent e) + { + + } + public void rnahelicesColour_actionPerformed(ActionEvent e) { diff --git a/src/jalview/viewmodel/annotationfilter/AnnotationFilterParameter.java b/src/jalview/viewmodel/annotationfilter/AnnotationFilterParameter.java new file mode 100644 index 0000000..3cd4ef7 --- /dev/null +++ b/src/jalview/viewmodel/annotationfilter/AnnotationFilterParameter.java @@ -0,0 +1,101 @@ +package jalview.viewmodel.annotationfilter; + +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, DESCRIPTION; + } + 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; + } + +}