From 5146792501661f7d07d4357651cb1b04fd4d9a46 Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Fri, 23 May 2014 11:57:27 +0100 Subject: [PATCH] JAL-1445 extend functionality to select or toggle selection for columns containing/not containing features in alignment or currently selected region --- src/jalview/api/AlignViewControllerI.java | 10 ++- src/jalview/controller/AlignViewController.java | 76 ++++++++++++++++++----- src/jalview/gui/FeatureSettings.java | 9 +-- 3 files changed, 73 insertions(+), 22 deletions(-) diff --git a/src/jalview/api/AlignViewControllerI.java b/src/jalview/api/AlignViewControllerI.java index 1d1e5fb..cac3776 100644 --- a/src/jalview/api/AlignViewControllerI.java +++ b/src/jalview/api/AlignViewControllerI.java @@ -21,6 +21,14 @@ public interface AlignViewControllerI public void setViewportAndAlignmentPanel(AlignViewportI viewport, AlignmentViewPanel alignPanel); - boolean markColumnsContainingFeatures(boolean invert, String featureType); + /** + * Mark columns in the current column selection according to positions of sequence features + * @param invert - when set, mark all but columns containing given type + * @param extendCurrent - when set, do not clear existing column selection + * @param toggle - rather than explicitly set, toggle selection state + * @param featureType - feature type string + * @return true if operation affected state + */ + boolean markColumnsContainingFeatures(boolean invert, boolean extendCurrent, boolean clearColumns, String featureType); } diff --git a/src/jalview/controller/AlignViewController.java b/src/jalview/controller/AlignViewController.java index 1a1d219..329267e 100644 --- a/src/jalview/controller/AlignViewController.java +++ b/src/jalview/controller/AlignViewController.java @@ -8,7 +8,10 @@ import jalview.api.AlignViewControllerGuiI; import jalview.api.AlignViewControllerI; import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.AnnotatedCollectionI; import jalview.datamodel.ColumnSelection; +import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; @@ -109,14 +112,16 @@ public class AlignViewController implements AlignViewControllerI } @Override - public boolean markColumnsContainingFeatures(boolean invert, - String featureType) + public boolean markColumnsContainingFeatures(boolean invert, boolean extendCurrent, boolean toggle, String featureType) { // JBPNote this routine could also mark rows, not just columns. // need a decent query structure to allow all types of feature searches BitSet bs = new BitSet(); - List seqs = viewport.getAlignment().getSequences(); - int alw = viewport.getAlignment().getWidth(); + int alw,alStart; + SequenceCollectionI sqcol = (viewport.getSelectionGroup() == null ? viewport.getAlignment() : viewport.getSelectionGroup()); + alStart = sqcol.getStartRes(); + alw = sqcol.getEndRes()+1; + List seqs = sqcol.getSequences(); int nseq = 0; for (SequenceI sq : seqs) { @@ -132,6 +137,13 @@ public class AlignViewController implements AlignViewControllerI SequenceFeature[] sf = dsq.getSequenceFeatures(); if (sf != null) { + int ist = sq.findIndex(sq.getStart()); + int iend = sq.findIndex(sq.getEnd()); + if (iend < alStart || ist> alw) + { + // sequence not in region + continue; + } for (SequenceFeature sfpos : sf) { // future functionalty - featureType == null means mark columns @@ -144,12 +156,19 @@ public class AlignViewController implements AlignViewControllerI // counting int i = sq.findIndex(sfpos.getBegin()); - int ist = sq.findIndex(sq.getStart()); - if (i < ist) + int j = sq.findIndex(sfpos.getEnd()); + if (jalw) + { + // feature is outside selected region + continue; + } + if (i < alStart) { + i = alStart; + } + if (i< ist) { i = ist; } - int j = sq.findIndex(sfpos.getEnd()); if (j > alw) { j = alw; @@ -168,21 +187,33 @@ public class AlignViewController implements AlignViewControllerI } } } + ColumnSelection cs = viewport.getColumnSelection(); if (bs.cardinality() > 0 || invert) { - ColumnSelection cs = viewport.getColumnSelection(); if (cs == null) { cs = new ColumnSelection(); + } else { + if (!extendCurrent) + { + cs.clear(); + } } if (invert) { - for (int i = bs.nextClearBit(0), ibs = bs.nextSetBit(0); i >= 0 - && i < alw;) + // invert only in the currently selected sequence region + for (int i = bs.nextClearBit(alStart), ibs = bs.nextSetBit(alStart); i >= alStart + && i < (alw);) { if (ibs < 0 || i < ibs) { - cs.addElement(i++); + if (toggle && cs.contains(i)) + { + cs.removeElement(i++); + } else + { + cs.addElement(i++); + } } else { @@ -193,22 +224,33 @@ public class AlignViewController implements AlignViewControllerI } else { - for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) + for (int i = bs.nextSetBit(alStart); i >= alStart; i = bs.nextSetBit(i + 1)) { - cs.addElement(i); + if (toggle && cs.contains(i)) + { + cs.removeElement(i); + } else + { + cs.addElement(i); + } } } viewport.setColumnSelection(cs); alignPanel.paintAlignment(true); - avcg.setStatus("Marked " - + (invert ? alw - bs.cardinality() : bs.cardinality()) - + " columns containing features of type " + featureType - + " across " + nseq); + avcg.setStatus((toggle ? "Toggled ": "Marked ") + + (invert ? (alw-alStart) - bs.cardinality() : bs.cardinality()) + + " columns "+(invert ? "not " : "") + "containing features of type " + featureType + + " across " + nseq + " sequence(s)"); return true; } else { avcg.setStatus("No features of type " + featureType + " found."); + if (!extendCurrent && cs!=null) + { + cs.clear(); + alignPanel.paintAlignment(true); + } return false; } } diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index 2bd98d5..3787efa 100644 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -108,7 +108,7 @@ public class FeatureSettings extends JPanel else if (evt.getClickCount() == 2) { fr.ap.alignFrame.avc.markColumnsContainingFeatures( - evt.isShiftDown(), + evt.isAltDown(),evt.isShiftDown() || evt.isMetaDown(), evt.isMetaDown(), (String) table.getValueAt(selectedRow, 0)); } } @@ -138,7 +138,8 @@ public class FeatureSettings extends JPanel } } }); - + table.setToolTipText(""+JvSwingUtils + .wrapTooltip("Click/drag feature types up or down to change render order.
Double click to select columns containing feature in alignment/current selection
Pressing Alt will select columns outside features rather than inside
Pressing Shift to modify current selection (rather than clear current selection)
Press CTRL or Command/Meta to toggle columns in/outside features
")+""); scrollPane.setViewportView(table); dassourceBrowser = new DasSourceBrowser(this); @@ -304,7 +305,7 @@ public class FeatureSettings extends JPanel @Override public void actionPerformed(ActionEvent arg0) { - fr.ap.alignFrame.avc.markColumnsContainingFeatures(false, type); + fr.ap.alignFrame.avc.markColumnsContainingFeatures(false, false, false, type); } }); JMenuItem clearCols = new JMenuItem(MessageManager.getString("label.select_columns_not_containing")); @@ -314,7 +315,7 @@ public class FeatureSettings extends JPanel @Override public void actionPerformed(ActionEvent arg0) { - fr.ap.alignFrame.avc.markColumnsContainingFeatures(true, type); + fr.ap.alignFrame.avc.markColumnsContainingFeatures(true, false, false, type); } }); men.add(selCols); -- 1.7.10.2