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);
}
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;
}
@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<SequenceI> 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<SequenceI> seqs = sqcol.getSequences();
int nseq = 0;
for (SequenceI sq : seqs)
{
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
// counting
int i = sq.findIndex(sfpos.getBegin());
- int ist = sq.findIndex(sq.getStart());
- if (i < ist)
+ int j = sq.findIndex(sfpos.getEnd());
+ if (j<alStart || i>alw)
+ {
+ // 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;
}
}
}
+ 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
{
}
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;
}
}
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));
}
}
}
}
});
-
+ table.setToolTipText("<html>"+JvSwingUtils
+ .wrapTooltip("Click/drag feature types up or down to change render order.<br/>Double click to select columns containing feature in alignment/current selection<br/>Pressing Alt will select columns outside features rather than inside<br/>Pressing Shift to modify current selection (rather than clear current selection)<br/>Press CTRL or Command/Meta to toggle columns in/outside features<br/>")+"</html>");
scrollPane.setViewportView(table);
dassourceBrowser = new DasSourceBrowser(this);
@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"));
@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);