X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FSeqPanel.java;h=791a371f0cfe8a1b90840d336b8c470fa78c428d;hb=ec1a819de862ef12fdb650f673a11d160c496331;hp=94d5ca8e9f13abb11f7d1fd5ae0b94e7bc1413da;hpb=a3fc7900ca2fd44261167a99f9ab2a0e85ea7aae;p=jalview.git diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 94d5ca8..791a371 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -1,36 +1,64 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8) - * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along with Jalview. If not, see . + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. */ - package jalview.gui; -import java.util.*; +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.awt.*; -import java.awt.event.*; - -import javax.swing.*; - -import jalview.commands.*; -import jalview.datamodel.*; +import java.util.Vector; + +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.ToolTipManager; + +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.SearchResults.Match; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceFeature; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; import jalview.io.SequenceAnnotationReport; -import jalview.schemes.*; -import jalview.structure.*; +import jalview.schemes.ResidueProperties; +import jalview.structure.SelectionListener; +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; /** * DOCUMENT ME! @@ -92,7 +120,7 @@ public class SeqPanel extends JPanel implements MouseListener, private final SequenceAnnotationReport seqARep; - StringBuffer tooltipText = new StringBuffer(""); + StringBuffer tooltipText = new StringBuffer(); String tmpString; @@ -144,16 +172,17 @@ public class SeqPanel extends JPanel implements MouseListener, int res = 0; int x = evt.getX(); - if (av.wrapAlignment) + if (av.getWrapAlignment()) { - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = av.getCharHeight(); + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += av.getCharHeight(); } - int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap + int cHeight = av.getAlignment().getHeight() * av.getCharHeight() + + hgap + seqCanvas.getAnnotationHeight(); int y = evt.getY(); @@ -197,15 +226,16 @@ public class SeqPanel extends JPanel implements MouseListener, int seq = 0; int y = evt.getY(); - if (av.wrapAlignment) + if (av.getWrapAlignment()) { - int hgap = av.charHeight; - if (av.scaleAboveWrapped) + int hgap = av.getCharHeight(); + if (av.getScaleAboveWrapped()) { - hgap += av.charHeight; + hgap += av.getCharHeight(); } - int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap + int cHeight = av.getAlignment().getHeight() * av.getCharHeight() + + hgap + seqCanvas.getAnnotationHeight(); y -= hgap; @@ -222,58 +252,33 @@ public class SeqPanel extends JPanel implements MouseListener, return seq; } - SequenceFeature[] findFeaturesAtRes(SequenceI sequence, int res) + /** + * 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() { - Vector tmp = new Vector(); - SequenceFeature[] features = sequence.getSequenceFeatures(); - if (features != null) + try { - for (int i = 0; i < features.length; i++) + if (editCommand != null && editCommand.getSize() > 0) { - if (av.featuresDisplayed == null - || !av.featuresDisplayed.containsKey(features[i].getType())) - { - continue; - } - - if (features[i].featureGroup != null - && seqCanvas.fr.featureGroups != null - && seqCanvas.fr.featureGroups - .containsKey(features[i].featureGroup) - && !((Boolean) seqCanvas.fr.featureGroups - .get(features[i].featureGroup)).booleanValue()) - continue; - - if ((features[i].getBegin() <= res) - && (features[i].getEnd() >= res)) - { - tmp.addElement(features[i]); - } + ap.alignFrame.addHistoryItem(editCommand); + av.firePropertyChange("alignment", null, av.getAlignment() + .getSequences()); } - } - - features = new SequenceFeature[tmp.size()]; - tmp.copyInto(features); - - return features; - } - - void endEditing() - { - if (editCommand != null && editCommand.getSize() > 0) + } 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() @@ -357,7 +362,7 @@ public class SeqPanel extends JPanel implements MouseListener, } endEditing(); - if (av.wrapAlignment) + if (av.getWrapAlignment()) { ap.scrollToWrappedVisible(seqCanvas.cursorX); } @@ -371,7 +376,7 @@ public class SeqPanel extends JPanel implements MouseListener, { ap.scrollUp(false); } - if (!av.wrapAlignment) + if (!av.getWrapAlignment()) { while (seqCanvas.cursorX < av.getColumnSelection() .adjustForHiddenColumns(av.startRes)) @@ -517,29 +522,34 @@ public class SeqPanel extends JPanel implements MouseListener, int getKeyboardNo1() { - try { - if (keyboardNo1 != null) + try { - int value = Integer.parseInt(keyboardNo1.toString()); - keyboardNo1 = null; - return value; - } + if (keyboardNo1 != null) + { + int value = Integer.parseInt(keyboardNo1.toString()); + keyboardNo1 = null; + return value; + } } catch (Exception x) - {} + { + } keyboardNo1 = null; return 1; } int getKeyboardNo2() { - try { - if (keyboardNo2!=null){ - int value = Integer.parseInt(keyboardNo2.toString()); - keyboardNo2 = null; - return value; - } + try + { + if (keyboardNo2 != null) + { + int value = Integer.parseInt(keyboardNo2.toString()); + keyboardNo2 = null; + return value; + } } catch (Exception x) - {} + { + } keyboardNo2 = null; return 1; } @@ -637,17 +647,30 @@ public class SeqPanel extends JPanel implements MouseListener, @Override public void highlightSequence(SearchResults results) { - if (av.followHighlight) - { + if (av.isFollowHighlight()) + { + /* + * if scrollToPosition requires scroll adjustment, this flag prevents + * another scroll event being propagated back to the originator + * + * @see AlignmentPanel#adjustmentValueChanged + */ + ap.setFollowingComplementScroll(true); if (ap.scrollToPosition(results, false)) { seqCanvas.revalidate(); } } + setStatusMessage(results); seqCanvas.highlightSearchResults(results); } @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"); @@ -687,7 +710,9 @@ public class SeqPanel extends JPanel implements MouseListener, pos = setStatusMessage(sequence, res, seq); if (ssm != null && pos > -1) + { mouseOverSequence(sequence, res, pos); + } tooltipText.setLength(6); // Cuts the buffer back to @@ -698,11 +723,6 @@ public class SeqPanel extends JPanel implements MouseListener, { if (groups[g].getStartRes() <= res && groups[g].getEndRes() >= res) { - if (tooltipText.length() > 6) - { - tooltipText.append("
"); - } - if (!groups[g].getName().startsWith("JTreeGroup") && !groups[g].getName().startsWith("JGroup")) { @@ -718,14 +738,14 @@ public class SeqPanel extends JPanel implements MouseListener, } // use aa to see if the mouse pointer is on a - if (av.showSequenceFeatures) + if (av.isShowSequenceFeatures()) { int rpos; - SequenceFeature[] features = findFeaturesAtRes( + List features = ap.getFeatureRenderer().findFeaturesAtRes( sequence.getDatasetSequence(), rpos = sequence.findPosition(res)); seqARep.appendFeatures(tooltipText, rpos, features, - this.ap.seqPanel.seqCanvas.fr.minmax); + this.ap.getSeqPanel().seqCanvas.fr.getMinMax()); } if (tooltipText.length() == 6) // { @@ -734,11 +754,13 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - tooltipText.append(""); if (lastTooltip == null || !lastTooltip.equals(tooltipText.toString())) { - setToolTipText(tooltipText.toString()); + String formatedTooltipText = JvSwingUtils.wrapTooltip(true, + tooltipText.toString()); + // String formatedTooltipText = tooltipText.toString(); + setToolTipText(formatedTooltipText); lastTooltip = tooltipText.toString(); } @@ -785,42 +807,72 @@ public class SeqPanel extends JPanel implements MouseListener, */ 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); - Object obj = null; + /* + * Sequence number (if known), and sequence name. + */ + String seqno = seq == -1 ? "" : " " + (seq + 1); + text.append("Sequence" + seqno + " ID: " + sequence.getName()); + + 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) ? "X" + : ResidueProperties.aa2Triplet.get(displayChar); + if (residue != null) { - text.append(" Residue: "); + text.append(" Residue: ").append(residue); } } - if (obj != null) + int pos = -1; + 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; } /** + * Set the status bar message to highlight the first matched position in + * search results. + * + * @param results + */ + private void setStatusMessage(SearchResults results) + { + List matches = results.getResults(); + if (!matches.isEmpty()) + { + Match m = matches.get(0); + SequenceI seq = m.getSequence(); + int sequenceIndex = this.av.getAlignment().findIndex(seq); + + /* + * Convert position in sequence (base 1) to sequence character array index + * (base 0) + */ + int start = m.getStart() - 1; + setStatusMessage(seq, start, sequenceIndex); + } + } + + /** * DOCUMENT ME! * * @param evt @@ -831,7 +883,7 @@ public class SeqPanel extends JPanel implements MouseListener, { if (mouseWheelPressed) { - int oldWidth = av.charWidth; + int oldWidth = av.getCharWidth(); // Which is bigger, left-right or up-down? if (Math.abs(evt.getY() - lastMousePress.getY()) > Math.abs(evt @@ -853,26 +905,28 @@ public class SeqPanel extends JPanel implements MouseListener, fontSize = 1; } - av.setFont(new Font(av.font.getName(), av.font.getStyle(), fontSize)); - av.charWidth = oldWidth; + av.setFont( + new Font(av.font.getName(), av.font.getStyle(), fontSize), + true); + av.setCharWidth(oldWidth); ap.fontChanged(); } else { - if (evt.getX() < lastMousePress.getX() && av.charWidth > 1) + if (evt.getX() < lastMousePress.getX() && av.getCharWidth() > 1) { - av.charWidth--; + av.setCharWidth(av.getCharWidth() - 1); } else if (evt.getX() > lastMousePress.getX()) { - av.charWidth++; + av.setCharWidth(av.getCharWidth() + 1); } ap.paintAlignment(false); } FontMetrics fm = getFontMetrics(av.getFont()); - av.validCharWidth = fm.charWidth('M') <= av.charWidth; + av.validCharWidth = fm.charWidth('M') <= av.getCharWidth(); lastMousePress = evt.getPoint(); @@ -935,13 +989,13 @@ public class SeqPanel extends JPanel implements MouseListener, } } - StringBuffer message = new StringBuffer(); + StringBuilder message = new StringBuilder(64); if (groupEditing) { message.append("Edit group:"); if (editCommand == null) { - editCommand = new EditCommand("Edit Group"); + editCommand = new EditCommand(MessageManager.getString("action.edit_group")); } } else @@ -954,7 +1008,7 @@ public class SeqPanel extends JPanel implements MouseListener, } if (editCommand == null) { - editCommand = new EditCommand("Edit " + label); + editCommand = new EditCommand(MessageManager.formatMessage("label.edit_params", new String[]{label})); } } @@ -1160,8 +1214,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - editCommand.appendEdit(EditCommand.INSERT_GAP, groupSeqs, - startres, startres - lastres, av.getAlignment(), true); + appendEdit(Action.INSERT_GAP, groupSeqs, startres, startres + - lastres); } } else @@ -1176,8 +1230,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - editCommand.appendEdit(EditCommand.DELETE_GAP, groupSeqs, - startres, lastres - startres, av.getAlignment(), true); + appendEdit(Action.DELETE_GAP, groupSeqs, startres, lastres + - startres); } } @@ -1198,8 +1252,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - editCommand.appendEdit(EditCommand.INSERT_GAP, new SequenceI[] - { seq }, lastres, startres - lastres, av.getAlignment(), true); + appendEdit(Action.INSERT_GAP, new SequenceI[] + { seq }, lastres, startres - lastres); } } else @@ -1211,7 +1265,7 @@ public class SeqPanel extends JPanel implements MouseListener, { for (int j = lastres; j > startres; j--) { - if (!jalview.util.Comparison.isGap(seq.getCharAt(startres))) + if (!Comparison.isGap(seq.getCharAt(startres))) { endEditing(); break; @@ -1226,7 +1280,7 @@ public class SeqPanel extends JPanel implements MouseListener, 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; } @@ -1235,9 +1289,8 @@ public class SeqPanel extends JPanel implements MouseListener, if (max > 0) { - editCommand.appendEdit(EditCommand.DELETE_GAP, - new SequenceI[] - { seq }, startres, max, av.getAlignment(), true); + appendEdit(Action.DELETE_GAP, new SequenceI[] + { seq }, startres, max); } } } @@ -1253,8 +1306,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - editCommand.appendEdit(EditCommand.INSERT_NUC, new SequenceI[] - { seq }, lastres, startres - lastres, av.getAlignment(), true); + appendEdit(Action.INSERT_NUC, new SequenceI[] + { seq }, lastres, startres - lastres); } } } @@ -1289,22 +1342,37 @@ public class SeqPanel extends JPanel implements MouseListener, } } - editCommand.appendEdit(EditCommand.DELETE_GAP, seq, blankColumn, 1, - av.getAlignment(), true); + appendEdit(Action.DELETE_GAP, seq, blankColumn, 1); + + 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) + { - editCommand.appendEdit(EditCommand.INSERT_GAP, seq, j, 1, - av.getAlignment(), true); + 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(EditCommand.DELETE_GAP, seq, j, 1, - av.getAlignment(), true); + appendEdit(Action.DELETE_GAP, seq, j, 1); - editCommand.appendEdit(EditCommand.INSERT_GAP, seq, fixedColumn, 1, - av.getAlignment(), true); + appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1); } /** @@ -1362,21 +1430,21 @@ public class SeqPanel extends JPanel implements MouseListener, av.setSelectionGroup(null); } - SequenceFeature[] features = findFeaturesAtRes( + List features = seqCanvas.getFeatureRenderer().findFeaturesAtRes( sequence.getDatasetSequence(), sequence.findPosition(findRes(evt))); - if (features != null && features.length > 0) + if (features != null && features.size()> 0) { SearchResults highlight = new SearchResults(); - highlight.addResult(sequence, features[0].getBegin(), - features[0].getEnd()); + highlight.addResult(sequence, features.get(0).getBegin(), + features.get(0).getEnd()); seqCanvas.highlightSearchResults(highlight); } - if (features != null && features.length > 0) + if (features != null && features.size()> 0) { seqCanvas.getFeatureRenderer().amendFeatures(new SequenceI[] - { sequence }, features, false, ap); + { sequence }, features.toArray(new SequenceFeature[features.size()]), false, ap); seqCanvas.highlightSearchResults(null); } @@ -1427,11 +1495,12 @@ public class SeqPanel extends JPanel implements MouseListener, startWrapBlock = wrappedBlock; - if (av.wrapAlignment && seq > av.getAlignment().getHeight()) + if (av.getWrapAlignment() && seq > av.getAlignment().getHeight()) { - JOptionPane.showInternalMessageDialog(Desktop.desktop, - "Cannot edit annotations in wrapped view.", - "Wrapped view - no edit", JOptionPane.WARNING_MESSAGE); + JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager + .getString("label.cannot_edit_annotations_in_wrapped_view"), + MessageManager.getString("label.wrapped_view_no_edit"), + JOptionPane.WARNING_MESSAGE); return; } @@ -1490,16 +1559,16 @@ public class SeqPanel extends JPanel implements MouseListener, if (javax.swing.SwingUtilities.isRightMouseButton(evt)) { - SequenceFeature[] allFeatures = findFeaturesAtRes( + List allFeatures = ap.getFeatureRenderer().findFeaturesAtRes( sequence.getDatasetSequence(), sequence.findPosition(res)); Vector links = new Vector(); - for (int i = 0; i < allFeatures.length; i++) + for (SequenceFeature sf:allFeatures) { - if (allFeatures[i].links != null) + if (sf.links != null) { - for (int j = 0; j < allFeatures[i].links.size(); j++) + for (int j = 0; j < sf.links.size(); j++) { - links.addElement(allFeatures[i].links.elementAt(j)); + links.addElement(sf.links.elementAt(j)); } } } @@ -1809,52 +1878,68 @@ public class SeqPanel extends JPanel implements MouseListener, // 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) - { - 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; - } - } - if (sgroup != null && sgroup.getSize() > 0) + if (av.getAlignment() == null) { - av.setSelectionGroup(sgroup); + jalview.bin.Cache.log.warn("alignviewport av SeqSetId=" + + av.getSequenceSetId() + " ViewId=" + av.getViewId() + + " 's alignment is NULL! returning immediately."); + return; } - else + sgroup = seqsel.intersect(av.getAlignment(), + (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null); + if ((sgroup == null || sgroup.getSize() == 0) + || (colsel == null || colsel.size() == 0)) { - av.setSelectionGroup(null); + // don't copy columns if the region didn't intersect. + copycolsel = false; } - 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 @@ -1882,6 +1967,7 @@ public class SeqPanel extends JPanel implements MouseListener, av.isColSelChanged(true); repaint = true; } + if (copycolsel && av.hasHiddenColumns() && (av.getColumnSelection() == null || av.getColumnSelection() @@ -1889,11 +1975,52 @@ public class SeqPanel extends JPanel implements MouseListener, { 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; + } }