X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Fgui%2FSeqPanel.java;h=2fe27b381bf84bffe35aac5fb94700b32ef764fa;hb=e25f63a72efddff9e071abdeff0ae5599431e4f8;hp=8146be0314bd1be23d4188153ce7c6111886cd20;hpb=8da7acff9214ddaf0e6d28e76219ab51bd38e62d;p=jalview.git diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 8146be0..2fe27b3 100755 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -18,8 +18,6 @@ */ package jalview.gui; -import jalview.analysis.*; - import jalview.datamodel.*; import jalview.schemes.*; @@ -27,8 +25,6 @@ import jalview.schemes.*; import java.awt.*; import java.awt.event.*; -import java.util.*; - import javax.swing.*; @@ -38,7 +34,9 @@ import javax.swing.*; * @author $author$ * @version $Revision$ */ -public class SeqPanel extends JPanel +public class SeqPanel extends JPanel implements MouseListener, + MouseMotionListener, MouseWheelListener + { /** DOCUMENT ME!! */ public SeqCanvas seqCanvas; @@ -52,7 +50,7 @@ public class SeqPanel extends JPanel protected AlignViewport av; // if character is inserted or deleted, we will need to recalculate the conservation - int seqEditOccurred = -1; + boolean seqEditOccurred = false; ScrollThread scrollThread = null; boolean mouseDragging = false; boolean editingSeqs = false; @@ -91,116 +89,12 @@ public class SeqPanel extends JPanel ap = p; - addMouseMotionListener(new MouseMotionAdapter() - { - public void mouseMoved(MouseEvent evt) - { - doMouseMoved(evt); - } - - public void mouseDragged(MouseEvent evt) - { - if (editingSeqs) - { - doMouseDragged(evt); - } - else - { - doMouseDraggedDefineMode(evt); - } - } - }); - - addMouseWheelListener(new MouseWheelListener() - { - public void mouseWheelMoved(MouseWheelEvent e) - { - - if (mouseWheelPressed) - { - Font font = av.getFont(); - int fontSize = font.getSize(); - if (e.getWheelRotation() > 0 && fontSize < 30) - fontSize++; - else if (fontSize > 1) - fontSize--; - - av.setFont(new Font(font.getName(), font.getStyle(), fontSize)); - ap.fontChanged(); - } - else - { - if (e.getWheelRotation() > 0) - ap.scrollUp(false); - else - ap.scrollUp(true); - } - - } - }); - - - addMouseListener(new MouseAdapter() - { - public void mouseReleased(MouseEvent evt) - { - mouseWheelPressed = false; - - if (editingSeqs) - { - doMouseReleased(evt); - } - else - { - doMouseReleasedDefineMode(evt); - } - } - - public void mousePressed(MouseEvent evt) - { - if( javax.swing.SwingUtilities.isMiddleMouseButton(evt)) - { - mouseWheelPressed = true; - return; - } - - if (evt.isShiftDown() || evt.isAltDown() || - evt.isControlDown()) - { - if (evt.isAltDown() || evt.isControlDown()) - { - groupEditing = true; - } - - editingSeqs = true; - doMousePressed(evt); - } - else - { - doMousePressedDefineMode(evt); - } - } - - public void mouseExited(MouseEvent evt) - { - if (editingSeqs) - { - return; - } - - doMouseExitedDefineMode(evt); - } - - public void mouseEntered(MouseEvent evt) - { - if (editingSeqs) - { - return; - } - - doMouseEnteredDefineMode(evt); - } - }); + if(!av.isDataset()) + { + addMouseMotionListener(this); + addMouseListener(this); + addMouseWheelListener(this); + } } int startWrapBlock=-1; @@ -212,36 +106,57 @@ public class SeqPanel extends JPanel if (av.wrapAlignment) { + + int hgap = av.charHeight; + if (av.scaleAboveWrapped) + hgap += av.charHeight; + + int cHeight = av.getAlignment().getHeight() * av.charHeight + + hgap + seqCanvas.getAnnotationHeight(); + int y = evt.getY(); - y -= (2 * av.charHeight); + y -= hgap; x -= seqCanvas.LABEL_WEST; - int chunkHeight = (av.getAlignment().getHeight() + 2) * av.charHeight; + int cwidth = seqCanvas.getWrappedCanvasWidth(this.getWidth()); - wrappedBlock = y/chunkHeight; - wrappedBlock += av.getStartRes()/cwidth; - res = wrappedBlock*cwidth + x / av.getCharWidth(); + wrappedBlock = y / cHeight; + wrappedBlock += av.getStartRes() / cwidth; + + res = wrappedBlock * cwidth + x / av.getCharWidth(); + } else { res = (x / av.getCharWidth()) + av.getStartRes(); } + if(av.hasHiddenColumns) + res = av.getColumnSelection().adjustForHiddenColumns(res); + return res; } int findSeq(MouseEvent evt) { + int seq = 0; int y = evt.getY(); if (av.wrapAlignment) { - y -= (2 * av.charHeight); - int chunkHeight = (av.getAlignment().getHeight() + 2) * av.charHeight; - seq = ( (y % chunkHeight) / av.getCharHeight()); + int hgap = av.charHeight; + if (av.scaleAboveWrapped) + hgap += av.charHeight; + + int cHeight = av.getAlignment().getHeight() * av.charHeight + + hgap + seqCanvas.getAnnotationHeight(); + + y -= hgap; + + seq = ( (y % cHeight) / av.getCharHeight()); } else { @@ -251,35 +166,70 @@ public class SeqPanel extends JPanel return seq; } + void endEditing() + { + startseq = -1; + lastres = -1; + seqEditOccurred = false; + editingSeqs = false; + groupEditing = false; + } /** * DOCUMENT ME! * * @param evt DOCUMENT ME! */ - public void doMouseReleased(MouseEvent evt) + public void mouseReleased(MouseEvent evt) { - if (seqEditOccurred > -1) + mouseDragging = false; + + if (!editingSeqs) + { + doMouseReleasedDefineMode(evt); + return; + } + + if (seqEditOccurred) { - editOccurred(seqEditOccurred); + editOccurred(); } - startseq = -1; - lastres = -1; - seqEditOccurred = -1; - editingSeqs = false; - groupEditing = false; - + endEditing(); ap.repaint(); } + + /** * DOCUMENT ME! * * @param evt DOCUMENT ME! */ - public void doMousePressed(MouseEvent evt) + public void mousePressed(MouseEvent evt) { + if (javax.swing.SwingUtilities.isMiddleMouseButton(evt)) + { + mouseWheelPressed = true; + return; + } + + if (evt.isShiftDown() || evt.isAltDown() || + evt.isControlDown()) + { + if (evt.isAltDown() || evt.isControlDown()) + { + groupEditing = true; + } + editingSeqs = true; + } + else + { + doMousePressedDefineMode(evt); + return; + } + + ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence", av.alignment, HistoryItem.EDIT)); @@ -312,8 +262,15 @@ public class SeqPanel extends JPanel * * @param evt DOCUMENT ME! */ - public void doMouseMoved(MouseEvent evt) + public void mouseMoved(MouseEvent evt) { + if (editingSeqs) + { + // This is because MacOSX creates a mouseMoved + // If control is down, other platforms will not. + mouseDragged(evt); + } + int res = findRes(evt); int seq = findSeq(evt); @@ -324,25 +281,41 @@ public class SeqPanel extends JPanel if (res > sequence.getLength()) { - return; - } + return; + } - Object obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + - ""); - String aa = ""; + if(seqCanvas.pdbCanvas!=null && sequence==seqCanvas.pdbCanvas.sequence) + { + seqCanvas.pdbCanvas.highlightRes(sequence.findPosition(res)); + } - if (obj != null) - { - aa = obj.toString(); - } StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: " + sequence.getName()); - if (aa != "") + Object obj = null; + if (av.alignment.isNucleotide()) { - text.append(" Residue: " + aa + " (" + - av.getAlignment().getSequenceAt(seq).findPosition(res) + ")"); + obj = ResidueProperties.nucleotideName.get(sequence.getCharAt(res) + + ""); + if(obj!=null) + text.append(" Nucleotide: "); + } + else + { + obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + ""); + if(obj!=null) + text.append(" Residue: "); + } + + if (obj != null) + { + + if (obj != "") + { + text.append( obj + " (" + + av.getAlignment().getSequenceAt(seq).findPosition(res) + ")"); + } } ap.alignFrame.statusBar.setText(text.toString()); @@ -350,32 +323,62 @@ public class SeqPanel extends JPanel // use aa to see if the mouse pointer is on a if (av.showSequenceFeatures) { - Vector features = sequence.getSequenceFeatures(); - Enumeration e = features.elements(); - StringBuffer sbuffer = new StringBuffer(); - - while (e.hasMoreElements()) + SequenceFeature [] features = sequence.getDatasetSequence().getSequenceFeatures(); + if(features!=null) { - SequenceFeature sf = (SequenceFeature) e.nextElement(); + StringBuffer sbuffer = new StringBuffer(""); - if ((sf.getStart() <= sequence.findPosition(res)) && - (sf.getEnd() >= sequence.findPosition(res))) + for (int i = 0; i < features.length; i++) + { + + if ( (features[i].getBegin() <= sequence.findPosition(res)) && + (features[i].getEnd() >= sequence.findPosition(res))) { - if (sbuffer.length() > 0) + if(!av.featuresDisplayed.containsKey(features[i].getType())) + continue; + + + if (features[i].getType().equals("disulfide bond")) + { + if (features[i].getBegin() == sequence.findPosition(res) + || features[i].getEnd() == sequence.findPosition(res)) { - sbuffer.append("; "); + if (sbuffer.length() > 6) + sbuffer.append("
"); + sbuffer.append("disulfide bond " + features[i].getBegin() + ":" + + features[i].getEnd()); } + } + else + { + if (sbuffer.length() > 6) + sbuffer.append("
"); + if(features[i].featureGroup!=null) + sbuffer.append(features[i].featureGroup+";"); - sbuffer.append(sf.getType() + " " + sf.getDescription()); + sbuffer.append(features[i].getType()); - if (sf.getStatus().length() > 0) + if (features[i].getDescription() != null + && !features[i].description.equals(features[i].getType())) + sbuffer.append("; " + features[i].getDescription()); + + if (features[i].getStatus() != null && features[i].getStatus().length()>0) { - sbuffer.append(" (" + sf.getStatus() + ")"); + sbuffer.append("; (" + features[i].getStatus() + ")"); } + } } - } - this.setToolTipText(sbuffer.toString()); + } + + sbuffer.append(""); + if(sbuffer.length()==13) // + setToolTipText(""); + else + setToolTipText(sbuffer.toString()); + } + else + setToolTipText(""); } } @@ -384,9 +387,14 @@ public class SeqPanel extends JPanel * * @param evt DOCUMENT ME! */ - public void doMouseDragged(MouseEvent evt) + public void mouseDragged(MouseEvent evt) { - // If we're dragging we're editing + if (!editingSeqs) + { + doMouseDraggedDefineMode(evt); + return; + } + int res = findRes(evt); if (res < 0) @@ -405,25 +413,131 @@ public class SeqPanel extends JPanel { dragRight = false; } + else if(av.hasHiddenColumns) + { + //Stop editing if the user has dragged beyond hiddenBoundary + int lastCol = av.getColumnSelection().getHiddenRegionBoundary(lastres); + if( lastCol < res) + { + if(lastres!=lastCol) + { + endEditing(); + return; + } + } + } + + if(!groupEditing && av.hasHiddenRows) + { + if(av.alignment.getSequenceAt(startseq).getHiddenSequences()!=null) + { + groupEditing = true; + } + } + if (res != lastres) { + SequenceI seq; // Group editing if (groupEditing) { SequenceGroup sg = av.getSelectionGroup(); - if (sg == null) + if (av.hasHiddenRows) { - lastres = -1; + //sg might be null as the user may only see 1 sequence + if(sg==null) + { + sg = new SequenceGroup(); + sg.addSequence(av.alignment.getSequenceAt(startseq), false); + } + SequenceGroup tmp = new SequenceGroup(); + + //Do any of the sequences have hidden associates? + for (int s = 0; s < sg.getSize(); s++) + { + seq = sg.getSequenceAt(s); + tmp.addSequence(seq, false); + if (seq.getHiddenSequences()!=null) + { + for(int h=0; h 1) + { + res = lastres+1; + } + + + int lastCol = av.getColumnSelection(). + getHiddenRegionBoundary(res); + + if(lastCol!=res) + { + for (blankColumn = lastCol; + blankColumn > lastres; + blankColumn--) + { + boolean blank = true; + for (int s = 0; s < sg.getSize(); s++) + { + seq = sg.getSequenceAt(s); + + if (seq.getSequence().length() <= blankColumn) + { + continue; + } + + if (!jalview.util.Comparison.isGap( + seq.getSequence().charAt(blankColumn))) + { + blank = false; + continue; + } + } + if (blank) + break; + } + + + if (blankColumn <= lastres) + { + endEditing(); + return; + } + } + else + blankColumn = -1; + + } + + sg.setEndRes(sg.getEndRes() + (res - lastres)); } // drag to left @@ -431,11 +545,10 @@ public class SeqPanel extends JPanel { /// Are we able to delete? // ie are all columns blank? - boolean deleteAllowed = false; for (int s = 0; s < sg.getSize(); s++) { - SequenceI seq = sg.getSequenceAt(s); + seq = sg.getSequenceAt(s); for (int j = res; j < lastres; j++) { @@ -448,37 +561,29 @@ public class SeqPanel extends JPanel seq.getSequence().charAt(j))) { // Not a gap, block edit not valid - res = j + 1; - deleteAllowed = false; - - continue; + endEditing(); + return; } - - deleteAllowed = true; } } - if (!deleteAllowed) + if(res j) + if (seq.getLength()-1 > res) { - deleteChar(res, k); + deleteChar(res, seq); } } } @@ -497,12 +602,13 @@ public class SeqPanel extends JPanel } else /////Editing a single sequence/////////// { + seq = av.alignment.getSequenceAt(startseq); if ((res < av.getAlignment().getWidth()) && (res > lastres)) { // dragging to the right for (int j = lastres; j < res; j++) { - insertChar(j, startseq); + insertChar(j, seq, j); } } else if ((res < av.getAlignment().getWidth()) && @@ -515,7 +621,7 @@ public class SeqPanel extends JPanel av.alignment.getSequenceAt(startseq) .getSequence().charAt(res))) { - deleteChar(res, startseq); + deleteChar(res, seq); } else { @@ -526,6 +632,10 @@ public class SeqPanel extends JPanel } } + mouseDragging = true; + if(scrollThread!=null) + scrollThread.setEvent(evt); + endEdit = res; lastres = res; seqCanvas.repaint(); @@ -534,27 +644,111 @@ public class SeqPanel extends JPanel /** * DOCUMENT ME! * - * @param seqstart DOCUMENT ME! - * @param seqend DOCUMENT ME! - * @param start DOCUMENT ME! + * @param e DOCUMENT ME! */ - public void drawChars(int seqstart, int seqend, int start) + public void mouseEntered(MouseEvent e) { - seqCanvas.drawPanel(seqCanvas.gg, start, av.getEndRes(), seqstart, - seqend, av.getStartRes(), av.getStartSeq(), 0); - seqCanvas.repaint(); + if(oldSeq < 0) + oldSeq = 0; + + if (scrollThread != null) + { + scrollThread.running = false; + scrollThread = null; + } + } + + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ + public void mouseExited(MouseEvent e) + { + if (av.getWrapAlignment()) + { + return; + } + + if (mouseDragging) + { + scrollThread = new ScrollThread(); + } + } + + public void mouseClicked(MouseEvent evt) + {} + + public void mouseWheelMoved(MouseWheelEvent e) + { + if (mouseWheelPressed) + { + Font font = av.getFont(); + int fontSize = font.getSize(); + if (e.getWheelRotation() > 0 && fontSize < 51) + fontSize++; + else if (fontSize > 1) + fontSize--; + + av.setFont(new Font(font.getName(), font.getStyle(), fontSize)); + ap.fontChanged(); + } + else + { + if (e.getWheelRotation() > 0) + ap.scrollUp(false); + else + ap.scrollUp(true); + } + } + /** * DOCUMENT ME! * * @param j DOCUMENT ME! * @param seq DOCUMENT ME! */ - public void insertChar(int j, int seq) + void insertChar(int j, SequenceI seq, int blankColumn) { - av.alignment.getSequenceAt(seq).insertCharAt(j, av.getGapCharacter()); - seqEditOccurred = seq; + if(av.hasHiddenColumns) + { + //Find the next gap before the end of the visible region boundary + int lastCol = av.getColumnSelection().getHiddenRegionBoundary(j); + if(lastCol != j) + { + if (!groupEditing || lastCol <= j) + { + blankColumn = lastCol; + //If lastCol > j, theres a boundary after the gap insertion + if (lastCol > j) + { + for (blankColumn = lastCol; blankColumn > j; blankColumn--) + { + if (jalview.util.Comparison.isGap(seq.getCharAt(blankColumn))) + { + //Theres a space, so break and insert the gap + break; + } + } + + if (blankColumn <= j) + { + endEditing(); + return; + } + } + + } + + // Editing with hidden regions only!! + seq.deleteCharAt(blankColumn); + } + } + + seq.insertCharAt(j, av.getGapCharacter()); + seqEditOccurred = true; } /** @@ -563,12 +757,23 @@ public class SeqPanel extends JPanel * @param j DOCUMENT ME! * @param seq DOCUMENT ME! */ - public void deleteChar(int j, int seq) + public void deleteChar(int j, SequenceI seq) { - av.alignment.getSequenceAt(seq).deleteCharAt(j); - seqEditOccurred = seq; + if (av.hasHiddenColumns) + { + //Find the next gap before the end of the visible region boundary + int lastCol = av.getColumnSelection().getHiddenRegionBoundary(j); + + //If lastCol > j, theres a boundary after the gap insertion + if (lastCol > j) + { + seq.insertCharAt(lastCol, av.getGapCharacter()); + } + } + + seq.deleteCharAt(j); + seqEditOccurred = true; - av.alignment.getWidth(); seqCanvas.repaint(); } @@ -577,7 +782,7 @@ public class SeqPanel extends JPanel * * @param i DOCUMENT ME! */ - void editOccurred(int i) + void editOccurred() { if (endEdit == startEdit) { @@ -602,8 +807,18 @@ public class SeqPanel extends JPanel startWrapBlock=wrappedBlock; - if(seq<0 || res<0) + if(av.wrapAlignment && seq>av.alignment.getHeight()) + { + JOptionPane.showInternalMessageDialog(Desktop.desktop, + "Cannot edit annotations in wrapped view.", + "Wrapped view - no edit", + JOptionPane.WARNING_MESSAGE); return; + } + + if(seq<0 || res<0) + return; + SequenceI sequence = (Sequence) av.getAlignment().getSequenceAt(seq); @@ -705,17 +920,12 @@ public class SeqPanel extends JPanel */ public void doMouseReleasedDefineMode(MouseEvent evt) { - if (mouseDragging) - { - stretchGroup.recalcConservation(); - mouseDragging = false; - } - if (stretchGroup == null) { return; } + if(stretchGroup.cs!=null) { if (stretchGroup.cs instanceof ClustalxColourScheme) @@ -729,6 +939,7 @@ public class SeqPanel extends JPanel { SliderPanel.setConservationSlider(ap, stretchGroup.cs, stretchGroup.getName()); + stretchGroup.recalcConservation(); } else { @@ -755,14 +966,15 @@ public class SeqPanel extends JPanel if(wrappedBlock!=startWrapBlock) return; - if (stretchGroup == null) - { + if (stretchGroup == null) + { return; - } + } + - if (res > av.alignment.getWidth()) + if(y > av.alignment.getHeight()) { - res = av.alignment.getWidth() - 1; + y = av.alignment.getHeight() -1; } if (stretchGroup.getEndRes() == res) @@ -780,10 +992,6 @@ public class SeqPanel extends JPanel { res = av.getStartRes(); } - else if (res > av.getEndRes() && !av.getWrapAlignment()) - { - res = av.getEndRes(); - } if (changeEndRes) { @@ -811,7 +1019,8 @@ public class SeqPanel extends JPanel dragDirection = -1; } - while ((y != oldSeq) && (oldSeq > 0) && (y < av.alignment.getHeight())) + + while ((y != oldSeq) && (oldSeq > -1) && (y < av.alignment.getHeight())) { // This routine ensures we don't skip any sequences, as the // selection is quite slow. @@ -819,6 +1028,9 @@ public class SeqPanel extends JPanel oldSeq += dragDirection; + if(oldSeq<0) + break; + Sequence nextSeq = (Sequence) av.getAlignment().getSequenceAt(oldSeq); if (stretchGroup.sequences.contains(nextSeq)) @@ -836,7 +1048,9 @@ public class SeqPanel extends JPanel } } - oldSeq = y; + if(oldSeq < 0) + oldSeq = -1; + mouseDragging = true; if (scrollThread != null) @@ -847,36 +1061,7 @@ public class SeqPanel extends JPanel seqCanvas.repaint(); } - /** - * DOCUMENT ME! - * - * @param e DOCUMENT ME! - */ - public void doMouseEnteredDefineMode(MouseEvent e) - { - if (scrollThread != null) - { - scrollThread.running = false; - } - } - /** - * DOCUMENT ME! - * - * @param e DOCUMENT ME! - */ - public void doMouseExitedDefineMode(MouseEvent e) - { - if (av.getWrapAlignment()) - { - return; - } - - if (mouseDragging) - { - scrollThread = new ScrollThread(); - } - } // this class allows scrolling off the bottom of the visible alignment class ScrollThread extends Thread @@ -931,7 +1116,7 @@ public class SeqPanel extends JPanel try { - Thread.sleep(75); + Thread.sleep(20); } catch (Exception ex) {