*/
package jalview.gui;
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Point;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
-import java.util.List;
-import java.util.Vector;
-
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.ToolTipManager;
-
import jalview.api.AlignViewportI;
+import jalview.bin.Cache;
import jalview.commands.EditCommand;
import jalview.commands.EditCommand.Action;
import jalview.commands.EditCommand.Edit;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.SearchResults;
import jalview.datamodel.SearchResults.Match;
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Point;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.ToolTipManager;
+
/**
* DOCUMENT ME!
*
StructureSelectionManager ssm;
+ SearchResults lastSearchResults;
+
/**
* Creates a new SeqPanel object.
*
}
int cHeight = av.getAlignment().getHeight() * av.getCharHeight()
- + hgap
- + seqCanvas.getAnnotationHeight();
+ + hgap + seqCanvas.getAnnotationHeight();
int y = evt.getY();
y -= hgap;
}
int cHeight = av.getAlignment().getHeight() * av.getCharHeight()
- + hgap
- + seqCanvas.getAnnotationHeight();
+ + hgap + seqCanvas.getAnnotationHeight();
y -= hgap;
void insertNucAtCursor(boolean group, String nuc)
{
+ // TODO not called - delete?
groupEditing = group;
startseq = seqCanvas.cursorY;
lastres = seqCanvas.cursorX;
{
lastMousePress = evt.getPoint();
- if (javax.swing.SwingUtilities.isMiddleMouseButton(evt))
+ if (SwingUtilities.isMiddleMouseButton(evt))
{
mouseWheelPressed = true;
return;
lastMessage = tmp;
}
+ /**
+ * Highlight the mapped region described by the search results object (unless
+ * unchanged). This supports highlight of protein while mousing over linked
+ * cDNA and vice versa. The status bar is also updated to show the location of
+ * the start of the highlighted region.
+ */
@Override
public void highlightSequence(SearchResults results)
{
+ if (results == null || results.equals(lastSearchResults))
+ {
+ return;
+ }
+ lastSearchResults = results;
+
if (av.isFollowHighlight())
{
/*
*
* @see AlignmentPanel#adjustmentValueChanged
*/
- ap.setFollowingComplementScroll(true);
+ ap.setDontScrollComplement(true);
if (ap.scrollToPosition(results, false))
{
seqCanvas.revalidate();
{
return this.ap == null ? null : this.ap.av;
}
+
@Override
public void updateColours(SequenceI seq, int index)
{
if (av.isShowSequenceFeatures())
{
int rpos;
- List<SequenceFeature> features = ap.getFeatureRenderer().findFeaturesAtRes(
- sequence.getDatasetSequence(),
- rpos = sequence.findPosition(res));
+ List<SequenceFeature> features = ap.getFeatureRenderer()
+ .findFeaturesAtRes(sequence.getDatasetSequence(),
+ rpos = sequence.findPosition(res));
seqARep.appendFeatures(tooltipText, rpos, features,
this.ap.getSeqPanel().seqCanvas.fr.getMinMax());
}
*
* @see javax.swing.JComponent#getToolTipLocation(java.awt.event.MouseEvent)
*/
+ @Override
public Point getToolTipLocation(MouseEvent event)
{
int x = event.getX(), w = getWidth();
String lastTooltip;
/**
+ * set when the current UI interaction has resulted in a change that requires
+ * overview shading to be recalculated. this could be changed to something
+ * more expressive that indicates what actually has changed, so selective
+ * redraws can be applied
+ */
+ private boolean needOverviewUpdate = false; // TODO: refactor to avcontroller
+
+ /**
+ * set if av.getSelectionGroup() refers to a group that is defined on the
+ * alignment view, rather than a transient selection
+ */
+ private boolean editingDefinedGroup = false; // TODO: refactor to avcontroller or viewModel
+
+ /**
* Set status message in alignment panel
*
* @param sequence
* Sequence number (if known), and sequence name.
*/
String seqno = seq == -1 ? "" : " " + (seq + 1);
- text.append("Sequence" + seqno + " ID: " + sequence.getName());
+ text.append("Sequence").append(seqno).append(" ID: ")
+ .append(sequence.getName());
String residue = null;
/*
}
else
{
- residue = "X".equalsIgnoreCase(displayChar) ? "X"
- : ResidueProperties.aa2Triplet.get(displayChar);
+ residue = "X".equalsIgnoreCase(displayChar) ? "X" : ("*"
+ .equals(displayChar) ? "STOP" : ResidueProperties.aa2Triplet
+ .get(displayChar));
if (residue != null)
{
text.append(" Residue: ").append(residue);
*/
private void setStatusMessage(SearchResults results)
{
- List<Match> matches = results.getResults();
- if (!matches.isEmpty())
+ AlignmentI al = this.av.getAlignment();
+ int sequenceIndex = al.findIndex(results);
+ if (sequenceIndex == -1)
+ {
+ return;
+ }
+ SequenceI ds = al.getSequenceAt(sequenceIndex).getDatasetSequence();
+ for (Match m : results.getResults())
{
- Match m = matches.get(0);
SequenceI seq = m.getSequence();
- int sequenceIndex = this.av.getAlignment().findIndex(seq);
+ if (seq.getDatasetSequence() != null)
+ {
+ seq = seq.getDatasetSequence();
+ }
- /*
- * Convert position in sequence (base 1) to sequence character array index
- * (base 0)
- */
- int start = m.getStart() - 1;
- setStatusMessage(seq, start, sequenceIndex);
+ if (seq == ds)
+ {
+ /*
+ * Convert position in sequence (base 1) to sequence character array
+ * index (base 0)
+ */
+ int start = m.getStart() - m.getSequence().getStart();
+ setStatusMessage(seq, start, sequenceIndex);
+ return;
+ }
}
}
message.append("Edit group:");
if (editCommand == null)
{
- editCommand = new EditCommand(MessageManager.getString("action.edit_group"));
+ editCommand = new EditCommand(
+ MessageManager.getString("action.edit_group"));
}
}
else
}
if (editCommand == null)
{
- editCommand = new EditCommand(MessageManager.formatMessage("label.edit_params", new String[]{label}));
+ editCommand = new EditCommand(MessageManager.formatMessage(
+ "label.edit_params", new String[] { label }));
}
}
{
for (int j = 0; j < startres - lastres; j++)
{
- if (!jalview.util.Comparison.isGap(groupSeqs[g]
- .getCharAt(fixedRight - j)))
+ if (!Comparison.isGap(groupSeqs[g].getCharAt(fixedRight - j)))
{
blank = false;
break;
continue;
}
- if (!jalview.util.Comparison.isGap(groupSeqs[g].getCharAt(j)))
+ if (!Comparison.isGap(groupSeqs[g].getCharAt(j)))
{
// Not a gap, block edit not valid
endEditing();
{
for (int j = lastres; j < startres; j++)
{
- insertChar(j, new SequenceI[]
- { seq }, fixedRight);
+ insertChar(j, new SequenceI[] { seq }, fixedRight);
}
}
else
{
- appendEdit(Action.INSERT_GAP, new SequenceI[]
- { seq }, lastres, startres - lastres);
+ appendEdit(Action.INSERT_GAP, new SequenceI[] { seq }, lastres,
+ startres - lastres);
}
}
else
endEditing();
break;
}
- deleteChar(startres, new SequenceI[]
- { seq }, fixedRight);
+ deleteChar(startres, new SequenceI[] { seq }, fixedRight);
}
}
else
if (max > 0)
{
- appendEdit(Action.DELETE_GAP, new SequenceI[]
- { seq }, startres, max);
+ appendEdit(Action.DELETE_GAP, new SequenceI[] { seq },
+ startres, max);
}
}
}
{
for (int j = lastres; j < startres; j++)
{
- insertChar(j, new SequenceI[]
- { seq }, fixedRight);
+ insertChar(j, new SequenceI[] { seq }, fixedRight);
}
}
else
{
- appendEdit(Action.INSERT_NUC, new SequenceI[]
- { seq }, lastres, startres - lastres);
+ appendEdit(Action.INSERT_NUC, new SequenceI[] { seq }, lastres,
+ startres - lastres);
}
}
}
for (blankColumn = fixedColumn; blankColumn > j; blankColumn--)
{
- if (jalview.util.Comparison.isGap(seq[s].getCharAt(blankColumn)))
+ if (Comparison.isGap(seq[s].getCharAt(blankColumn)))
{
// Theres a space, so break and insert the gap
break;
final Edit edit = new EditCommand().new Edit(action, seq, pos, count,
av.getAlignment().getGapCharacter());
- editCommand.appendEdit(edit, av.getAlignment(),
- true, null);
+ editCommand.appendEdit(edit, av.getAlignment(), true, null);
}
void deleteChar(int j, SequenceI[] seq, int fixedColumn)
av.setSelectionGroup(null);
}
- List<SequenceFeature> features = seqCanvas.getFeatureRenderer().findFeaturesAtRes(
- sequence.getDatasetSequence(),
- sequence.findPosition(findRes(evt)));
+ List<SequenceFeature> features = seqCanvas.getFeatureRenderer()
+ .findFeaturesAtRes(sequence.getDatasetSequence(),
+ sequence.findPosition(findRes(evt)));
- if (features != null && features.size()> 0)
+ if (features != null && features.size() > 0)
{
SearchResults highlight = new SearchResults();
- highlight.addResult(sequence, features.get(0).getBegin(),
- features.get(0).getEnd());
+ highlight.addResult(sequence, features.get(0).getBegin(), features
+ .get(0).getEnd());
seqCanvas.highlightSearchResults(highlight);
}
- if (features != null && features.size()> 0)
+ if (features != null && features.size() > 0)
{
- seqCanvas.getFeatureRenderer().amendFeatures(new SequenceI[]
- { sequence }, features.toArray(new SequenceFeature[features.size()]), false, ap);
+ seqCanvas.getFeatureRenderer().amendFeatures(
+ new SequenceI[] { sequence },
+ features.toArray(new SequenceFeature[features.size()]),
+ false, ap);
seqCanvas.highlightSearchResults(null);
}
&& (res < stretchGroup.getEndRes()))
{
av.setSelectionGroup(stretchGroup);
+ editingDefinedGroup = true;
}
else
{
stretchGroup = null;
+ editingDefinedGroup = false;
}
}
else if (!stretchGroup.getSequences(null).contains(sequence)
&& (allGroups[i].getEndRes() >= res))
{
stretchGroup = allGroups[i];
+ editingDefinedGroup = true;
break;
}
}
}
- if (javax.swing.SwingUtilities.isRightMouseButton(evt))
+ if (evt.isPopupTrigger())
{
- List<SequenceFeature> allFeatures = ap.getFeatureRenderer().findFeaturesAtRes(
- sequence.getDatasetSequence(), sequence.findPosition(res));
- Vector links = new Vector();
- for (SequenceFeature sf:allFeatures)
+ List<SequenceFeature> allFeatures = ap.getFeatureRenderer()
+ .findFeaturesAtRes(sequence.getDatasetSequence(),
+ sequence.findPosition(res));
+ List<String> links = new ArrayList<String>();
+ for (SequenceFeature sf : allFeatures)
{
if (sf.links != null)
{
- for (int j = 0; j < sf.links.size(); j++)
+ for (String link : sf.links)
{
- links.addElement(sf.links.elementAt(j));
+ links.add(link);
}
}
}
- jalview.gui.PopupMenu pop = new jalview.gui.PopupMenu(ap, null, links);
+ PopupMenu pop = new PopupMenu(ap, null, links);
pop.show(this, evt.getX(), evt.getY());
return;
}
sg.setEndRes(res);
sg.addSequence(sequence, false);
av.setSelectionGroup(sg);
-
+ editingDefinedGroup = false;
stretchGroup = sg;
if (av.getConservationSelected())
{
return;
}
-
- stretchGroup.recalcConservation(); // always do this - annotation has own
- // state
+ // always do this - annotation has own state
+ // but defer colourscheme update until hidden sequences are passed in
+ boolean vischange = stretchGroup.recalcConservation(true);
+ needOverviewUpdate |= vischange && editingDefinedGroup;
if (stretchGroup.cs != null)
{
stretchGroup.cs.alignmentChanged(stretchGroup,
}
}
PaintRefresher.Refresh(this, av.getSequenceSetId());
- ap.paintAlignment(true);
-
+ ap.paintAlignment(needOverviewUpdate);
+ needOverviewUpdate =false;
+ editingDefinedGroup = false;
changeEndRes = false;
changeStartRes = false;
stretchGroup = null;
if (res > (stretchGroup.getStartRes() - 1))
{
stretchGroup.setEndRes(res);
+ needOverviewUpdate |= editingDefinedGroup;
}
}
else if (changeStartRes)
if (res < (stretchGroup.getEndRes() + 1))
{
stretchGroup.setStartRes(res);
+ needOverviewUpdate |= editingDefinedGroup;
}
}
if (stretchGroup.getSequences(null).contains(nextSeq))
{
stretchGroup.deleteSequence(seq, false);
+ needOverviewUpdate |= editingDefinedGroup;
}
else
{
}
stretchGroup.addSequence(nextSeq, false);
+ needOverviewUpdate |= editingDefinedGroup;
}
}
// handles selection messages...
// TODO: extend config options to allow user to control if selections may be
// shared between viewports.
- boolean iSentTheSelection = (av == source
- || (source instanceof AlignViewport && ((AlignmentViewport) source)
+ boolean iSentTheSelection = (av == source || (source instanceof AlignViewport && ((AlignmentViewport) source)
.getSequenceSetId().equals(av.getSequenceSetId())));
if (iSentTheSelection || !av.followSelection)
{
// 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
+ /*
+ * only copy colsel if there is a real intersection between
+ * sequence selection and this panel's alignment
+ */
boolean repaint = false;
- boolean copycolsel = true;
+ boolean copycolsel = false;
SequenceGroup sgroup = null;
if (seqsel != null && seqsel.getSize() > 0)
{
if (av.getAlignment() == null)
{
- jalview.bin.Cache.log.warn("alignviewport av SeqSetId="
+ Cache.log.warn("alignviewport av SeqSetId="
+ av.getSequenceSetId() + " ViewId=" + av.getViewId()
+ " 's alignment is NULL! returning immediately.");
return;
}
sgroup = seqsel.intersect(av.getAlignment(),
(av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
- if ((sgroup == null || sgroup.getSize() == 0)
- || (colsel == null || colsel.size() == 0))
+ if ((sgroup != null && sgroup.getSize() > 0))
{
- // don't copy columns if the region didn't intersect.
- copycolsel = false;
+ copycolsel = true;
}
}
if (sgroup != null && sgroup.getSize() > 0)
{
// the current selection is unset or from a previous message
// so import the new colsel.
- if (colsel == null || colsel.size() == 0)
+ if (colsel == null || colsel.isEmpty())
{
if (av.getColumnSelection() != null)
{
protected boolean selectionFromTranslation(SequenceGroup seqsel,
ColumnSelection colsel, SelectionSource source)
{
- if (!(source instanceof AlignViewportI)) {
+ if (!(source instanceof AlignViewportI))
+ {
return false;
}
final AlignViewportI sourceAv = (AlignViewportI) source;
- if (sourceAv.getCodingComplement() != av && av.getCodingComplement() != sourceAv)
+ if (sourceAv.getCodingComplement() != av
+ && av.getCodingComplement() != sourceAv)
{
return false;
}
ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv,
av);
av.setColumnSelection(cs);
- av.isColSelChanged(true);
PaintRefresher.Refresh(this, av.getSequenceSetId());