import jalview.commands.EditCommand.Edit;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SearchResultMatchI;
import jalview.datamodel.SearchResults;
-import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.SearchResultsI;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceGroup;
import jalview.util.Comparison;
import jalview.util.MappingUtils;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import jalview.viewmodel.AlignmentViewport;
import java.awt.BorderLayout;
private final SequenceAnnotationReport seqARep;
- StringBuffer tooltipText = new StringBuffer();
+ StringBuilder tooltipText = new StringBuilder();
String tmpString;
StructureSelectionManager ssm;
- SearchResults lastSearchResults;
+ SearchResultsI lastSearchResults;
/**
* Creates a new SeqPanel object.
mouseDragging = false;
mouseWheelPressed = false;
+ if (evt.isPopupTrigger()) // Windows: mouseReleased
+ {
+ showPopupMenu(evt);
+ evt.consume();
+ return;
+ }
+
if (!editingSeqs)
{
doMouseReleasedDefineMode(evt);
return;
}
- if (evt.isShiftDown() || evt.isAltDown() || evt.isControlDown())
+ boolean isControlDown = Platform.isControlDown(evt);
+ if (evt.isShiftDown() || isControlDown)
{
- if (evt.isAltDown() || evt.isControlDown())
+ editingSeqs = true;
+ if (isControlDown)
{
groupEditing = true;
}
- editingSeqs = true;
}
else
{
* the start of the highlighted region.
*/
@Override
- public void highlightSequence(SearchResults results)
+ public void highlightSequence(SearchResultsI results)
{
if (results == null || results.equals(lastSearchResults))
{
seqARep.appendFeatures(tooltipText, rpos, features,
this.ap.getSeqPanel().seqCanvas.fr.getMinMax());
}
- if (tooltipText.length() == 6) // <html></html>
+ if (tooltipText.length() == 6) // <html>
{
setToolTipText(null);
lastTooltip = null;
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;
/*
*
* @param results
*/
- private void setStatusMessage(SearchResults results)
+ private void setStatusMessage(SearchResultsI results)
{
AlignmentI al = this.av.getAlignment();
int sequenceIndex = al.findIndex(results);
return;
}
SequenceI ds = al.getSequenceAt(sequenceIndex).getDatasetSequence();
- for (Match m : results.getResults())
+ for (SearchResultMatchI m : results.getResults())
{
SequenceI seq = m.getSequence();
if (seq.getDatasetSequence() != null)
if (features != null && features.size() > 0)
{
- SearchResults highlight = new SearchResults();
+ SearchResultsI highlight = new SearchResults();
highlight.addResult(sequence, features.get(0).getBegin(), features
.get(0).getEnd());
seqCanvas.highlightSearchResults(highlight);
*/
public void doMousePressedDefineMode(MouseEvent evt)
{
- int res = findRes(evt);
- int seq = findSeq(evt);
+ final int res = findRes(evt);
+ final int seq = findSeq(evt);
oldSeq = seq;
+ needOverviewUpdate = false;
startWrapBlock = wrappedBlock;
if (av.getWrapAlignment() && seq > av.getAlignment().getHeight())
{
- JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
+ JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
.getString("label.cannot_edit_annotations_in_wrapped_view"),
MessageManager.getString("label.wrapped_view_no_edit"),
- JOptionPane.WARNING_MESSAGE);
+ JvOptionPane.WARNING_MESSAGE);
return;
}
}
av.setSelectionGroup(stretchGroup);
-
}
- if (SwingUtilities.isRightMouseButton(evt))
+ if (evt.isPopupTrigger()) // Mac: mousePressed
{
- 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 (String link : sf.links)
- {
- links.add(link);
- }
- }
- }
+ showPopupMenu(evt);
+ return;
+ }
- PopupMenu pop = new PopupMenu(ap, null, links);
- pop.show(this, evt.getX(), evt.getY());
+ /*
+ * defer right-mouse click handling to mouseReleased on Windows
+ * (where isPopupTrigger() will answer true)
+ * NB isRightMouseButton is also true for Cmd-click on Mac
+ */
+ if (SwingUtilities.isRightMouseButton(evt) && !Platform.isAMac())
+ {
return;
}
sg.setEndRes(res);
sg.addSequence(sequence, false);
av.setSelectionGroup(sg);
-
stretchGroup = sg;
if (av.getConservationSelected())
}
/**
+ * Build and show a pop-up menu at the right-click mouse position
+ *
+ * @param evt
+ * @param res
+ * @param sequence
+ */
+ void showPopupMenu(MouseEvent evt)
+ {
+ final int res = findRes(evt);
+ final int seq = findSeq(evt);
+ SequenceI sequence = av.getAlignment().getSequenceAt(seq);
+ 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 (String link : sf.links)
+ {
+ links.add(link);
+ }
+ }
+ }
+
+ PopupMenu pop = new PopupMenu(ap, null, links);
+ pop.show(this, evt.getX(), evt.getY());
+ }
+
+ /**
* DOCUMENT ME!
*
* @param evt
{
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 && av.isSelectionDefinedGroup();
if (stretchGroup.cs != null)
{
stretchGroup.cs.alignmentChanged(stretchGroup,
}
}
PaintRefresher.Refresh(this, av.getSequenceSetId());
- ap.paintAlignment(true);
-
+ ap.paintAlignment(needOverviewUpdate);
+ needOverviewUpdate = false;
changeEndRes = false;
changeStartRes = false;
stretchGroup = null;
if (res > (stretchGroup.getStartRes() - 1))
{
stretchGroup.setEndRes(res);
+ needOverviewUpdate |= av.isSelectionDefinedGroup();
}
}
else if (changeStartRes)
if (res < (stretchGroup.getEndRes() + 1))
{
stretchGroup.setStartRes(res);
+ needOverviewUpdate |= av.isSelectionDefinedGroup();
}
}
if (stretchGroup.getSequences(null).contains(nextSeq))
{
stretchGroup.deleteSequence(seq, false);
+ needOverviewUpdate |= av.isSelectionDefinedGroup();
}
else
{
}
stretchGroup.addSequence(nextSeq, false);
+ needOverviewUpdate |= av.isSelectionDefinedGroup();
}
}
// 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)
{
- Cache.log.warn("alignviewport av SeqSetId="
- + av.getSequenceSetId() + " ViewId=" + av.getViewId()
+ 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.isEmpty()))
+ 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)
ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv,
av);
av.setColumnSelection(cs);
- av.isColSelChanged(true);
PaintRefresher.Refresh(this, av.getSequenceSetId());