*/
package jalview.gui;
+import jalview.api.AlignViewportI;
import jalview.commands.EditCommand;
import jalview.commands.EditCommand.Action;
+import jalview.commands.EditCommand.Edit;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.SearchResults;
import jalview.datamodel.Sequence;
import jalview.structure.SelectionSource;
import jalview.structure.SequenceListener;
import jalview.structure.StructureSelectionManager;
+import jalview.structure.VamsasSource;
+import jalview.util.Comparison;
+import jalview.util.MappingUtils;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
import java.awt.BorderLayout;
import java.awt.Color;
return seq;
}
+ /**
+ * When all of a sequence of edits are complete, put the resulting edit list
+ * on the history stack (undo list), and reset flags for editing in progress.
+ */
void endEditing()
{
- if (editCommand != null && editCommand.getSize() > 0)
+ try
+ {
+ if (editCommand != null && editCommand.getSize() > 0)
+ {
+ ap.alignFrame.addHistoryItem(editCommand);
+ av.firePropertyChange("alignment", null, av.getAlignment()
+ .getSequences());
+ }
+ } finally
{
- ap.alignFrame.addHistoryItem(editCommand);
- av.firePropertyChange("alignment", null, av.getAlignment()
- .getSequences());
+ /*
+ * Tidy up come what may...
+ */
+ startseq = -1;
+ lastres = -1;
+ editingSeqs = false;
+ groupEditing = false;
+ keyboardNo1 = null;
+ keyboardNo2 = null;
+ editCommand = null;
}
-
- startseq = -1;
- lastres = -1;
- editingSeqs = false;
- groupEditing = false;
- keyboardNo1 = null;
- keyboardNo2 = null;
- editCommand = null;
}
void setCursorRow()
}
@Override
+ public VamsasSource getVamsasSource()
+ {
+ return this.ap == null ? null : this.ap.av;
+ }
+ @Override
public void updateColours(SequenceI seq, int index)
{
System.out.println("update the seqPanel colours");
int setStatusMessage(SequenceI sequence, int res, int seq)
{
int pos = -1;
- StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: "
- + sequence.getName());
+ StringBuilder text = new StringBuilder(32);
+ text.append("Sequence " + (seq + 1) + " ID: " + sequence.getName());
- Object obj = null;
+ String residue = null;
+ /*
+ * Try to translate the display character to residue name (null for gap).
+ */
+ final String displayChar = String.valueOf(sequence.getCharAt(res));
if (av.getAlignment().isNucleotide())
{
- obj = ResidueProperties.nucleotideName.get(sequence.getCharAt(res)
- + "");
- if (obj != null)
+ residue = ResidueProperties.nucleotideName.get(displayChar);
+ if (residue != null)
{
- text.append(" Nucleotide: ");
+ text.append(" Nucleotide: ").append(residue);
}
}
else
{
- obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + "");
- if (obj != null)
+ residue = "X".equalsIgnoreCase(displayChar) ? "STOP"
+ : ResidueProperties.aa2Triplet.get(displayChar);
+ if (residue != null)
{
- text.append(" Residue: ");
+ text.append(" Residue: ").append(residue);
}
}
- if (obj != null)
+ if (residue != null)
{
pos = sequence.findPosition(res);
- if (obj != "")
- {
- text.append(obj + " (" + pos + ")");
- }
+ text.append(" (").append(Integer.toString(pos)).append(")");
}
ap.alignFrame.statusBar.setText(text.toString());
return pos;
}
}
- StringBuffer message = new StringBuffer();
+ StringBuilder message = new StringBuilder(64);
if (groupEditing)
{
message.append("Edit group:");
}
else
{
- editCommand.appendEdit(Action.INSERT_GAP, groupSeqs,
- startres, startres - lastres, av.getAlignment(), true);
+ appendEdit(Action.INSERT_GAP, groupSeqs, startres, startres
+ - lastres);
}
}
else
}
else
{
- editCommand.appendEdit(Action.DELETE_GAP, groupSeqs,
- startres, lastres - startres, av.getAlignment(), true);
+ appendEdit(Action.DELETE_GAP, groupSeqs, startres, lastres
+ - startres);
}
}
}
else
{
- editCommand.appendEdit(Action.INSERT_GAP, new SequenceI[]
- { seq }, lastres, startres - lastres, av.getAlignment(), true);
+ appendEdit(Action.INSERT_GAP, new SequenceI[]
+ { seq }, lastres, startres - lastres);
}
}
else
{
for (int j = lastres; j > startres; j--)
{
- if (!jalview.util.Comparison.isGap(seq.getCharAt(startres)))
+ if (!Comparison.isGap(seq.getCharAt(startres)))
{
endEditing();
break;
int max = 0;
for (int m = startres; m < lastres; m++)
{
- if (!jalview.util.Comparison.isGap(seq.getCharAt(m)))
+ if (!Comparison.isGap(seq.getCharAt(m)))
{
break;
}
if (max > 0)
{
- editCommand.appendEdit(Action.DELETE_GAP,
- new SequenceI[]
- { seq }, startres, max, av.getAlignment(), true);
+ appendEdit(Action.DELETE_GAP, new SequenceI[]
+ { seq }, startres, max);
}
}
}
}
else
{
- editCommand.appendEdit(Action.INSERT_NUC, new SequenceI[]
- { seq }, lastres, startres - lastres, av.getAlignment(), true);
+ appendEdit(Action.INSERT_NUC, new SequenceI[]
+ { seq }, lastres, startres - lastres);
}
}
}
}
}
- editCommand.appendEdit(Action.DELETE_GAP, seq, blankColumn, 1,
- av.getAlignment(), true);
+ appendEdit(Action.DELETE_GAP, seq, blankColumn, 1);
- editCommand.appendEdit(Action.INSERT_GAP, seq, j, 1,
- av.getAlignment(), true);
+ appendEdit(Action.INSERT_GAP, seq, j, 1);
}
+ /**
+ * Helper method to add and perform one edit action.
+ *
+ * @param action
+ * @param seq
+ * @param pos
+ * @param count
+ */
+ protected void appendEdit(Action action, SequenceI[] seq, int pos,
+ int count)
+ {
+
+ final Edit edit = new EditCommand().new Edit(action, seq, pos, count,
+ av.getAlignment().getGapCharacter());
+
+ editCommand.appendEdit(edit, av.getAlignment(),
+ true, null);
+ }
+
void deleteChar(int j, SequenceI[] seq, int fixedColumn)
{
- editCommand.appendEdit(Action.DELETE_GAP, seq, j, 1,
- av.getAlignment(), true);
+ appendEdit(Action.DELETE_GAP, seq, j, 1);
- editCommand.appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1,
- av.getAlignment(), true);
+ appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1);
}
/**
// handles selection messages...
// TODO: extend config options to allow user to control if selections may be
// shared between viewports.
- if (av == source
- || !av.followSelection
- || (av.isSelectionGroupChanged(false) || av
- .isColSelChanged(false))
- || (source instanceof AlignViewport && ((AlignViewport) source)
- .getSequenceSetId().equals(av.getSequenceSetId())))
+ boolean iSentTheSelection = (av == source
+ || (source instanceof AlignViewport && ((AlignmentViewport) source)
+ .getSequenceSetId().equals(av.getSequenceSetId())));
+ if (iSentTheSelection || !av.followSelection)
+ {
+ return;
+ }
+
+ /*
+ * Ignore the selection if there is one of our own pending.
+ */
+ if (av.isSelectionGroupChanged(false) || av.isColSelChanged(false))
+ {
+ return;
+ }
+
+ /*
+ * Check for selection in a view of which this one is a dna/protein
+ * complement.
+ */
+ if (selectionFromTranslation(seqsel, colsel, source))
{
return;
}
+
// do we want to thread this ? (contention with seqsel and colsel locks, I
// suspect)
// rules are: colsel is copied if there is a real intersection between
// sequence selection
- boolean repaint = false, copycolsel = true;
- // if (!av.isSelectionGroupChanged(false))
+ boolean repaint = false;
+ boolean copycolsel = true;
+
+ SequenceGroup sgroup = null;
+ if (seqsel != null && seqsel.getSize() > 0)
{
- SequenceGroup sgroup = null;
- if (seqsel != null && seqsel.getSize() > 0)
+ if (av.getAlignment() == null)
{
- if (av.getAlignment() == null)
- {
- jalview.bin.Cache.log.warn("alignviewport av SeqSetId="
- + av.getSequenceSetId() + " ViewId=" + av.getViewId()
- + " 's alignment is NULL! returning immediatly.");
- return;
- }
- sgroup = seqsel.intersect(av.getAlignment(),
- (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
- if ((sgroup == null || sgroup.getSize() == 0)
- || (colsel == null || colsel.size() == 0))
- {
- // don't copy columns if the region didn't intersect.
- copycolsel = false;
- }
+ jalview.bin.Cache.log.warn("alignviewport av SeqSetId="
+ + av.getSequenceSetId() + " ViewId=" + av.getViewId()
+ + " 's alignment is NULL! returning immediately.");
+ return;
}
- if (sgroup != null && sgroup.getSize() > 0)
+ sgroup = seqsel.intersect(av.getAlignment(),
+ (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
+ if ((sgroup == null || sgroup.getSize() == 0)
+ || (colsel == null || colsel.size() == 0))
{
- av.setSelectionGroup(sgroup);
+ // don't copy columns if the region didn't intersect.
+ copycolsel = false;
}
- else
- {
- av.setSelectionGroup(null);
- }
- av.isSelectionGroupChanged(true);
- repaint = true;
}
+ if (sgroup != null && sgroup.getSize() > 0)
+ {
+ av.setSelectionGroup(sgroup);
+ }
+ else
+ {
+ av.setSelectionGroup(null);
+ }
+ av.isSelectionGroupChanged(true);
+ repaint = true;
+
if (copycolsel)
{
// the current selection is unset or from a previous message
av.isColSelChanged(true);
repaint = true;
}
+
if (copycolsel
&& av.hasHiddenColumns()
&& (av.getColumnSelection() == null || av.getColumnSelection()
{
System.err.println("Bad things");
}
- if (repaint)
+ if (repaint) // always true!
{
// probably finessing with multiple redraws here
PaintRefresher.Refresh(this, av.getSequenceSetId());
// ap.paintAlignment(false);
}
}
+
+ /**
+ * If this panel is a cdna/protein translation view of the selection source,
+ * tries to map the source selection to a local one, and returns true. Else
+ * returns false.
+ *
+ * @param seqsel
+ * @param colsel
+ * @param source
+ */
+ protected boolean selectionFromTranslation(SequenceGroup seqsel,
+ ColumnSelection colsel, SelectionSource source)
+ {
+ if (!(source instanceof AlignViewportI)) {
+ return false;
+ }
+ final AlignViewportI sourceAv = (AlignViewportI) source;
+ if (sourceAv.getCodingComplement() != av && av.getCodingComplement() != sourceAv)
+ {
+ return false;
+ }
+
+ /*
+ * Map sequence selection
+ */
+ SequenceGroup sg = MappingUtils.mapSequenceGroup(seqsel, sourceAv, av);
+ av.setSelectionGroup(sg);
+ av.isSelectionGroupChanged(true);
+
+ /*
+ * Map column selection
+ */
+ ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv,
+ av);
+ av.setColumnSelection(cs);
+ av.isColSelChanged(true);
+
+ PaintRefresher.Refresh(this, av.getSequenceSetId());
+
+ return true;
+ }
}