From f7d45a21db810c5f8f7ca668d1a28f1403defe32 Mon Sep 17 00:00:00 2001 From: amwaterhouse Date: Tue, 4 Apr 2006 10:47:57 +0000 Subject: [PATCH] Keyboard editing added to applet --- src/jalview/appletgui/AlignFrame.java | 127 ++++- src/jalview/appletgui/AlignViewport.java | 5 + src/jalview/appletgui/AlignmentPanel.java | 3 +- src/jalview/appletgui/SeqCanvas.java | 15 +- src/jalview/appletgui/SeqPanel.java | 716 +++++++++++++++++++++------ src/jalview/appletgui/SequenceRenderer.java | 18 + 6 files changed, 725 insertions(+), 159 deletions(-) diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java index 189a36d..7a0052f 100755 --- a/src/jalview/appletgui/AlignFrame.java +++ b/src/jalview/appletgui/AlignFrame.java @@ -250,6 +250,13 @@ public class AlignFrame extends Frame implements ActionListener, public void keyPressed(KeyEvent evt) { + if (viewport.cursorMode + && evt.getKeyCode() >= KeyEvent.VK_0 + && evt.getKeyCode() <= KeyEvent.VK_9) + { + alignPanel.seqPanel.numberPressed(evt.getKeyChar()); + } + switch (evt.getKeyCode()) { case 27: // escape key @@ -262,6 +269,10 @@ public class AlignFrame extends Frame implements ActionListener, } break; case KeyEvent.VK_C: + if (viewport.cursorMode) + { + alignPanel.seqPanel.setCursorColumn(); + } if (evt.isControlDown() || evt.isMetaDown()) { copy_actionPerformed(); @@ -280,21 +291,110 @@ public class AlignFrame extends Frame implements ActionListener, } break; case KeyEvent.VK_DOWN: - moveSelectedSequences(false); + if(viewport.cursorMode) + { + alignPanel.seqPanel.moveCursor(0,1); + } + else + moveSelectedSequences(false); break; + case KeyEvent.VK_UP: - moveSelectedSequences(true); + if (viewport.cursorMode) + { + alignPanel.seqPanel.moveCursor(0,-1); + } + else + moveSelectedSequences(true); + break; + + case KeyEvent.VK_LEFT: + if(viewport.cursorMode) + { + alignPanel.seqPanel.moveCursor(-1,0); + } + break; + + case KeyEvent.VK_RIGHT: + if (viewport.cursorMode) + { + alignPanel.seqPanel.moveCursor(1,0); + } + break; + case KeyEvent.VK_SPACE: + if(viewport.cursorMode) + { + alignPanel.seqPanel.insertGapAtCursor(evt.isControlDown()); + } + break; + + case KeyEvent.VK_DELETE: + if(viewport.cursorMode) + { + alignPanel.seqPanel.deleteGapAtCursor(evt.isControlDown()); + } + break; + + case KeyEvent.VK_BACK_SPACE: + if(!viewport.cursorMode) + { + cut_actionPerformed(); + alignPanel.seqPanel.seqCanvas.repaint(); + } + break; + + case KeyEvent.VK_S: + if(viewport.cursorMode) + { + alignPanel.seqPanel.setCursorRow(); + } + break; + case KeyEvent.VK_P: + if(viewport.cursorMode) + { + alignPanel.seqPanel.setCursorPosition(); + } + break; + + case KeyEvent.VK_ENTER: + case KeyEvent.VK_COMMA: + if(viewport.cursorMode) + { + alignPanel.seqPanel.setCursorRowAndColumn(); + } break; + + case KeyEvent.VK_Q: + if(viewport.cursorMode) + { + alignPanel.seqPanel.setSelectionAreaAtCursor(true); + } + break; + case KeyEvent.VK_M: + if(viewport.cursorMode) + { + alignPanel.seqPanel.setSelectionAreaAtCursor(false); + } + break; + + case KeyEvent.VK_F2: + viewport.cursorMode = ! viewport.cursorMode; + statusBar.setText("Keyboard editing mode is "+ + (viewport.cursorMode ? "on" : "off")); + if(viewport.cursorMode) + { + alignPanel.seqPanel.seqCanvas.cursorX = viewport.startRes; + alignPanel.seqPanel.seqCanvas.cursorY = viewport.startSeq; + } + alignPanel.seqPanel.seqCanvas.repaint(); + break; + case KeyEvent.VK_F: if (evt.isControlDown()) { findMenuItem_actionPerformed(); } break; - case KeyEvent.VK_BACK_SPACE: - case KeyEvent.VK_DELETE: - cut_actionPerformed(); - break; } } public void keyReleased(KeyEvent evt) @@ -335,6 +435,8 @@ public void itemStateChanged(ItemEvent evt) abovePIDThreshold_actionPerformed(); else if(evt.getSource()==applyToAllGroups) applyToAllGroups_actionPerformed(); + else if(evt.getSource()==autoCalculate) + viewport.autocalculateConsensus = autoCalculate.getState(); } public void actionPerformed(ActionEvent evt) { @@ -1003,8 +1105,13 @@ public void itemStateChanged(ItemEvent evt) public void alignmentChanged() { - viewport.updateConsensus(); - viewport.updateConservation (); + viewport.alignment.padGaps(); + if(viewport.autocalculateConsensus) + { + viewport.updateConsensus(); + viewport.updateConservation(); + } + resetAllColourSchemes(); if(alignPanel.overviewPanel!=null) alignPanel.overviewPanel.updateOverviewImage(); @@ -1749,6 +1856,8 @@ public void itemStateChanged(ItemEvent evt) protected CheckboxMenuItem scaleRight = new CheckboxMenuItem(); MenuItem modifyPID = new MenuItem(); MenuItem modifyConservation = new MenuItem(); + protected CheckboxMenuItem autoCalculate + = new CheckboxMenuItem("Autocalculate Consensus", true); protected Menu sortByTreeMenu = new Menu(); Menu sort = new Menu(); Menu calculate = new Menu(); @@ -1926,6 +2035,7 @@ public void itemStateChanged(ItemEvent evt) sortByTreeMenu.setLabel("By Tree Order"); sort.setLabel("Sort"); calculate.setLabel("Calculate Tree"); + autoCalculate.addItemListener(this); inputText.setLabel("Input from textbox"); inputText.addActionListener(this); @@ -2021,6 +2131,7 @@ public void itemStateChanged(ItemEvent evt) calculateMenu.addSeparator(); calculateMenu.add(pairwiseAlignmentMenuItem); calculateMenu.add(PCAMenuItem); + calculateMenu.add(autoCalculate); this.add(statusBar, BorderLayout.SOUTH); pasteMenu.add(pasteNew); pasteMenu.add(pasteThis); diff --git a/src/jalview/appletgui/AlignViewport.java b/src/jalview/appletgui/AlignViewport.java index bef5e1a..36b0a31 100755 --- a/src/jalview/appletgui/AlignViewport.java +++ b/src/jalview/appletgui/AlignViewport.java @@ -36,6 +36,9 @@ public class AlignViewport int startSeq; int endSeq; + + boolean cursorMode = false; + boolean showJVSuffix = true; boolean showText = true; boolean showColourText = false; @@ -83,6 +86,8 @@ public class AlignViewport AlignmentAnnotation conservation; AlignmentAnnotation quality; + boolean autocalculateConsensus = true; + public int ConsPercGaps = 25; // JBPNote : This should be a scalable property! private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(this); diff --git a/src/jalview/appletgui/AlignmentPanel.java b/src/jalview/appletgui/AlignmentPanel.java index e0c327f..30e1d70 100755 --- a/src/jalview/appletgui/AlignmentPanel.java +++ b/src/jalview/appletgui/AlignmentPanel.java @@ -306,6 +306,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener } setScrollValues(hscroll.getValue(), vscroll.getValue()+1); } + repaint(); return true; } @@ -313,7 +314,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener public boolean scrollRight(boolean right) { - if (right) + if (!right) { if (hscroll.getValue() < 1) { diff --git a/src/jalview/appletgui/SeqCanvas.java b/src/jalview/appletgui/SeqCanvas.java index 465dd38..f6ef577 100755 --- a/src/jalview/appletgui/SeqCanvas.java +++ b/src/jalview/appletgui/SeqCanvas.java @@ -37,12 +37,13 @@ public class SeqCanvas SearchResults searchResults = null; - int chunkHeight; - int chunkWidth; - boolean fastPaint = false; + int cursorX = 0; + int cursorY = 0; + + public SeqCanvas(AlignViewport av) { this.av = av; @@ -468,6 +469,14 @@ public class SeqCanvas av.charWidth, av.charHeight); } } + + if (av.cursorMode && cursorY == i + && cursorX >= startRes && cursorX <= endRes) + { + sr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * av.charWidth, + offset + ( (i - startSeq) * av.charHeight)); + } + } // diff --git a/src/jalview/appletgui/SeqPanel.java b/src/jalview/appletgui/SeqPanel.java index e29f4e1..021a5dc 100755 --- a/src/jalview/appletgui/SeqPanel.java +++ b/src/jalview/appletgui/SeqPanel.java @@ -19,8 +19,6 @@ package jalview.appletgui; -import java.util.*; - import java.awt.*; import java.awt.event.*; @@ -36,20 +34,27 @@ public class SeqPanel protected int lastres; protected int startseq; - int startEdit = -1; - int endEdit = -1; 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; boolean groupEditing = false; + int oldSeq = -1; + boolean changeEndSeq = false; + boolean changeStartSeq = false; + boolean changeEndRes = false; + boolean changeStartRes = false; + SequenceGroup stretchGroup = null; + + StringBuffer keyboardNo1; + StringBuffer keyboardNo2; + public SeqPanel(AlignViewport avp, AlignmentPanel p) { this.av = avp; @@ -66,23 +71,281 @@ public class SeqPanel seqCanvas.repaint(); } + void endEditing() + { + startseq = -1; + lastres = -1; + seqEditOccurred = false; + editingSeqs = false; + groupEditing = false; + keyboardNo1 = null; + keyboardNo2 = null; + } + + void setCursorRow() + { + seqCanvas.cursorY = getKeyboardNo(keyboardNo1)-1; + scrollToVisible(); + } + + void setCursorColumn() + { + seqCanvas.cursorX = getKeyboardNo(keyboardNo1)-1; + scrollToVisible(); + } + + void setCursorRowAndColumn() + { + if(keyboardNo2==null) + { + keyboardNo2 = new StringBuffer(); + } + else + { + seqCanvas.cursorX = getKeyboardNo(keyboardNo1) - 1; + seqCanvas.cursorY = getKeyboardNo(keyboardNo2) - 1; + scrollToVisible(); + } + } + + void setCursorPosition() + { + SequenceI sequence = + (Sequence) av.getAlignment().getSequenceAt(seqCanvas.cursorY); + + seqCanvas.cursorX = sequence.findIndex( + getKeyboardNo(keyboardNo1)-1 + ); + scrollToVisible(); + } + + void moveCursor(int dx, int dy) + { + seqCanvas.cursorX += dx; + seqCanvas.cursorY += dy; + scrollToVisible(); + } + + void scrollToVisible() + { + if (seqCanvas.cursorX < 0) + seqCanvas.cursorX = 0; + else if (seqCanvas.cursorX > av.alignment.getWidth() - 1) + seqCanvas.cursorX = av.alignment.getWidth() - 1; + + if (seqCanvas.cursorY < 0) + seqCanvas.cursorY = 0; + else if (seqCanvas.cursorY > av.alignment.getHeight() - 1) + seqCanvas.cursorY = av.alignment.getHeight() - 1; + + + endEditing(); + while (seqCanvas.cursorY < av.startSeq) + { + ap.scrollUp(true); + } + while (seqCanvas.cursorY + 1 > av.endSeq) + { + ap.scrollUp(false); + } + while (seqCanvas.cursorX < av.startRes) + { + + if(!ap.scrollRight(false)) + break; + } + while (seqCanvas.cursorX > av.endRes) + { + if(!ap.scrollRight(true)) + break; + } + + setStatusMessage(av.alignment.getSequenceAt(seqCanvas.cursorY), + seqCanvas.cursorX, seqCanvas.cursorY); + + seqCanvas.repaint(); + } + + void setSelectionAreaAtCursor(boolean topLeft) + { + SequenceI sequence = + (Sequence) av.getAlignment().getSequenceAt(seqCanvas.cursorY); + + if(av.getSelectionGroup()!=null) + { + SequenceGroup sg = av.selectionGroup; + //Find the top and bottom of this group + int min = av.alignment.getHeight(), max = 0; + for(int i=0; i max) + max = index; + if(index < min) + min = index; + } + + max ++; + + if(topLeft) + { + sg.setStartRes(seqCanvas.cursorX); + if(sg.getEndRes()seqCanvas.cursorX) + sg.setStartRes(seqCanvas.cursorX); + + max = seqCanvas.cursorY+1; + } + + if(min>max) + { + // Only the user can do this + av.setSelectionGroup(null); + } + else + { + // Now add any sequences between min and max + sg.sequences.removeAllElements(); + for (int i = min; i < max; i++) + { + sg.addSequence(av.alignment.getSequenceAt(i), false); + } + } + } + + if (av.getSelectionGroup() == null) + { + SequenceGroup sg = new SequenceGroup(); + sg.setStartRes(seqCanvas.cursorX); + sg.setEndRes(seqCanvas.cursorX); + sg.addSequence(sequence, false); + av.setSelectionGroup(sg); + } + + + ap.repaint(); + } + + void insertGapAtCursor(boolean group) + { + ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence", + av.alignment, HistoryItem.EDIT)); + groupEditing = group; + startseq = seqCanvas.cursorY; + lastres = seqCanvas.cursorX; + editSequence(true, seqCanvas.cursorX+getKeyboardNo(keyboardNo1)); + editOccurred(); + } + + void deleteGapAtCursor(boolean group) + { + ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence", + av.alignment, HistoryItem.EDIT)); + groupEditing = group; + startseq = seqCanvas.cursorY; + lastres = seqCanvas.cursorX+getKeyboardNo(keyboardNo1); + editSequence(false, seqCanvas.cursorX); + editOccurred(); + } + + void numberPressed(char value) + { + if(keyboardNo1==null) + keyboardNo1 = new StringBuffer(); + + if(keyboardNo2!=null) + keyboardNo2.append(value); + else + keyboardNo1.append(value); + } + + int getKeyboardNo(StringBuffer kb) + { + if(kb==null) + return 1; + else + return Integer.parseInt(kb.toString()); + } + + void setStatusMessage(SequenceI sequence, int res, int seq) + { + StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: " + + sequence.getName()); + + Object obj = null; + if (av.alignment.isNucleotide()) + { + 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 + " (" + sequence.findPosition(res) + + ")"); + } + } + ap.alignFrame.statusBar.setText(text.toString()); + + } public void mousePressed(MouseEvent evt) { - if (evt.isShiftDown() || evt.isAltDown() || evt.isControlDown()) + if (evt.isShiftDown() || evt.isAltDown() || + evt.isControlDown()) { if (evt.isAltDown() || evt.isControlDown()) { groupEditing = true; } - editingSeqs = true; - doMousePressed(evt); } else { doMousePressedDefineMode(evt); + return; } + + + int seq = findSeq(evt); + int res = findRes(evt); + + if(seq<0 || res<0) + return; + + ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence", + av.alignment, HistoryItem.EDIT)); + + if ((seq < av.getAlignment().getHeight()) && + (res < av.getAlignment().getSequenceAt(seq).getLength())) + { + startseq = seq; + lastres = res; + } + else + { + startseq = -1; + lastres = -1; + } + + return; } public void mouseClicked(MouseEvent evt){} @@ -90,24 +353,18 @@ public class SeqPanel public void mouseReleased(MouseEvent evt) { + mouseDragging = false; + if (!editingSeqs) { - doMouseReleasedDefineMode(evt); - return; + doMouseReleasedDefineMode(evt); + return; } + editOccurred(); - if (seqEditOccurred > -1) - { - editOccurred(seqEditOccurred); - } - - startseq = -1; - lastres = -1; - seqEditOccurred = -1; - editingSeqs = false; - groupEditing = false; - ap.repaint(); + endEditing(); + ap.repaint(); } int startWrapBlock=-1; @@ -304,191 +561,362 @@ public class SeqPanel public void mouseDragged(MouseEvent evt) { if (!editingSeqs) - { - doMouseDraggedDefineMode(evt); - return; - } +{ + doMouseDraggedDefineMode(evt); + return; +} - // If we're dragging we're editing - int res = findRes(evt); - if (res < 0) - { + int res = findRes(evt); + + if (res < 0) + { res = 0; - } + } - if (lastres == -1 || lastres == res) - { + if ((lastres == -1) || (lastres == res)) + { return; - } + } - boolean dragRight = true; - if (res < av.getAlignment().getWidth() && res < lastres) - { - dragRight = false; - } + if ( (res < av.getAlignment().getWidth()) && (res < lastres)) + { + // dragLeft, delete gap + editSequence(false, res); + } + else + editSequence(true, res); - if (res != lastres) + mouseDragging = true; + if(scrollThread!=null) + scrollThread.setEvent(evt); + + } + + synchronized void editSequence(boolean insertGap, int startres) { - // Group editing - if (groupEditing) - { - SequenceGroup sg = av.getSelectionGroup(); - if (sg == null) - { - lastres = -1; - return; - } + int fixedLeft = -1; + int fixedRight = -1; + boolean fixedColumns = false; + SequenceGroup sg = av.getSelectionGroup(); - // drag to right - if (dragRight) - { - sg.setEndRes(sg.getEndRes() + (res - lastres)); - } + if(groupEditing && sg==null) + return; - // drag to left + SequenceI seq = av.alignment.getSequenceAt(startseq); + StringBuffer message = new StringBuffer(); + if (groupEditing) + message.append("Edit group:"); else + message.append("Edit sequence: "+seq.getName()); + + if(insertGap) + message.append(" insert "); + else + message.append(" delete "); + + message.append(Math.abs(startres-lastres)+" gaps."); + ap.alignFrame.statusBar.setText(message.toString()); + + + //Are we editing within a selection group? + if (groupEditing + || (sg != null && sg.sequences.contains(seq))) { - /// 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); - for (int j = res; j < lastres; j++) - { - if (seq.getSequence().length() <= j) - { - continue; - } + fixedColumns = true; - if (!jalview.util.Comparison.isGap(seq.getSequence().charAt(j))) - { - // Not a gap, block edit not valid - res = j + 1; - deleteAllowed = false; - continue; - } - deleteAllowed = true; - } - } + fixedLeft = sg.getStartRes(); + fixedRight = sg.getEndRes(); - if (!deleteAllowed) + if ( (startres < fixedLeft && lastres >= fixedLeft) + || (startres >= fixedLeft && lastres < fixedLeft) + || (startres > fixedRight && lastres <=fixedRight) + || (startres <= fixedRight && lastres > fixedRight)) { - lastres = -1; + endEditing(); return; } - sg.setEndRes(sg.getEndRes() - (lastres - res)); + if (fixedLeft > startres) + { + fixedRight = fixedLeft - 1; + fixedLeft = 0; + } + else if (fixedRight < startres) + { + fixedLeft = fixedRight; + fixedRight = -1; + } } - for (int i = 0; i < sg.getSize(); i++) - { - SequenceI s = sg.getSequenceAt(i); - int k = av.alignment.findIndex(s); + if (groupEditing) + { // drag to right - if (dragRight) + if (insertGap) { - for (int j = lastres; j < res; j++) + //If the user has selected the whole sequence, and is dragging to + // the right, we can still extend the alignment and selectionGroup + if(sg.getStartRes() == 0 && sg.getEndRes() + 1 == av.alignment.getWidth()) + { + sg.setEndRes(av.alignment.getWidth() + startres - lastres); + fixedRight = sg.getEndRes(); + } + + // Is it valid with fixed columns?? + // Find the next gap before the end + // of the visible region boundary + boolean blank = false; + for (fixedRight = fixedRight; + fixedRight > lastres; + fixedRight--) + { + blank = true; + for (int s = 0; s < sg.getSize(); s++) + { + seq = sg.getSequenceAt(s); + for (int j = 0; j < startres - lastres; j++) + { + if (!jalview.util.Comparison.isGap( + seq.getCharAt(fixedRight - j))) + { + blank = false; + break; + } + } + } + if (blank) + break; + } + + if (!blank) { - insertChar(j, k); + if(sg.getSize() == av.alignment.getHeight()) + { + //We can still insert gaps if the selectionGroup + //contains all the sequences + sg.setEndRes(sg.getEndRes()+1+startres-lastres); + fixedRight = av.alignment.getWidth()+startres-lastres; + } + else + { + endEditing(); + return; + } } } + // drag to left - else + else if(!insertGap) { - for (int j = res; j < lastres; j++) + /// Are we able to delete? + // ie are all columns blank? + + for (int s = 0; s < sg.getSize(); s++) { - if (s.getLength() > j) + seq = sg.getSequenceAt(s); + + for (int j = startres; j < lastres; j++) { - deleteChar(res, k); + if (seq.getSequence().length() <= j) + { + continue; + } + + if (!jalview.util.Comparison.isGap( + seq.getSequence().charAt(j))) + { + // Not a gap, block edit not valid + endEditing(); + return; + } } } } - } - } - else /////Editing a single sequence/////////// - { - if (res < av.getAlignment().getWidth() && res > lastres) - { - // dragging to the right - for (int j = lastres; j < res; j++) + + + for (int i = 0; i < sg.getSize(); i++) { - insertChar(j, startseq); + seq = sg.getSequenceAt(i); + + if (insertGap) + { + // dragging to the right + for (int j = lastres; j < startres; j++) + { + if (fixedColumns && fixedRight != -1) + { + insertChar(j, seq, fixedRight); + } + else + insertChar(j, seq); + } + } + else + { + // dragging to the left + for (int j = lastres; j > startres; j--) + { + if (fixedColumns && fixedRight != -1) + { + deleteChar(startres, seq, fixedRight); + } + else + { + deleteChar(startres, seq); + } + } + } } } - else if (res < av.getAlignment().getWidth() && res < lastres) + else /////Editing a single sequence/////////// { - // dragging to the left - for (int j = lastres; j > res; j--) + if (insertGap) { - if (jalview.util.Comparison.isGap( - av.alignment.getSequenceAt(startseq).getSequence().charAt(res))) + // dragging to the right + for (int j = lastres; j < startres; j++) { - - deleteChar(res, startseq); + if (fixedColumns && fixedRight != -1) + { + if (sg.getStartRes() == 0 + && sg.getEndRes() + 1 == av.alignment.getWidth() + && !jalview.util.Comparison.isGap(seq.getCharAt(fixedRight))) + { + //Single sequence edit, whole sequence selected, + //extend the selection group + sg.setEndRes(av.alignment.getWidth() -1 + startres - lastres); + fixedColumns = false; + insertChar(j, seq); + } + else + insertChar(j, seq, fixedRight); + } + else + insertChar(j, seq); } - else + } + else + { + // dragging to the left + for (int j = lastres; j > startres; j--) { - if(scrollThread!=null) + if (fixedColumns && fixedRight != -1) { - scrollThread.running = false; - scrollThread = null; + deleteChar(startres, seq, fixedRight); + } + else + { + deleteChar(startres, seq); } - break; } } } - } + lastres = startres; + seqCanvas.repaint(); } - mouseDragging = true; - if (res > av.endRes || res < av.startRes) + + /** + * DOCUMENT ME! + * + * @param j DOCUMENT ME! + * @param seq DOCUMENT ME! + */ + void insertChar(int j, SequenceI seq) { - mouseExited(evt); + seq.insertCharAt(j, av.getGapCharacter()); + seqEditOccurred = true; } - if (scrollThread != null) - scrollThread.setEvent(evt); + void insertChar(int j, SequenceI seq, int fixedColumn) + { + //Find the next gap before the end of the visible region boundary + //If lastCol > j, theres a boundary after the gap insertion + int blankColumn = fixedColumn; + for (blankColumn = fixedColumn; 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; + } - endEdit = res; - lastres = res; - seqCanvas.repaint(); - } + if (!jalview.util.Comparison.isGap(seq.getCharAt(blankColumn))) + { + //Just Checking + System.out.println("Tried removing residue (INSERT)"+seq.getCharAt(fixedColumn)); + return; + } - public void insertChar(int j, int seq) - { - av.alignment.getSequenceAt(seq).insertCharAt(j, av.getGapCharacter()); - seqEditOccurred = seq; - } + seq.deleteCharAt(blankColumn); + seq.insertCharAt(j, av.getGapCharacter()); + seqEditOccurred = true; + } - public void deleteChar(int j, int seq) - { + void deleteChar(int j, SequenceI seq, int fixedColumn) + { + if (!jalview.util.Comparison.isGap(seq.getCharAt(j))) + { + ap.alignFrame.statusBar.setText( + "End editing: Tried removing residue " + seq.getCharAt(j)); + return; + } - av.alignment.getSequenceAt(seq).deleteCharAt(j); - seqEditOccurred = seq; - av.alignment.getWidth(); - repaint(); - } + seq.deleteCharAt(j); + seq.insertCharAt(fixedColumn, av.getGapCharacter()); + seqEditOccurred = true; + } - void editOccurred(int i) - { - if (endEdit == startEdit) + /** + * DOCUMENT ME! + * + * @param j DOCUMENT ME! + * @param seq DOCUMENT ME! + */ + void deleteChar(int j, SequenceI seq) { + if (!jalview.util.Comparison.isGap(seq.getCharAt(j))) + { + ap.alignFrame.statusBar.setText( + "End editing: Tried removing residue " + seq.getCharAt(j)); + return; + } + + seq.deleteCharAt(j); + seqEditOccurred = true; + seqCanvas.repaint(); + } + + /** + * DOCUMENT ME! + * + * @param i DOCUMENT ME! + */ + void editOccurred() + { + if (!seqEditOccurred) + { ap.alignFrame.historyList.pop(); ap.alignFrame.updateEditMenuBar(); - } + } - av.firePropertyChange("alignment", null,av.getAlignment().getSequences()); - } + endEditing(); + + av.firePropertyChange("alignment", null,av.getAlignment().getSequences()); + + } ////////////////////////////////////////// /////Everything below this is for defining the boundary of the rubberband ////////////////////////////////////////// - int oldSeq = -1; public void doMousePressedDefineMode(MouseEvent evt) { if (scrollThread != null) @@ -597,12 +1025,6 @@ public class SeqPanel } - boolean changeEndSeq = false; - boolean changeStartSeq = false; - boolean changeEndRes = false; - boolean changeStartRes = false; - SequenceGroup stretchGroup = null; - public void doMouseReleasedDefineMode(MouseEvent evt) { if (stretchGroup == null) diff --git a/src/jalview/appletgui/SequenceRenderer.java b/src/jalview/appletgui/SequenceRenderer.java index 3f87b02..891dfab 100755 --- a/src/jalview/appletgui/SequenceRenderer.java +++ b/src/jalview/appletgui/SequenceRenderer.java @@ -264,4 +264,22 @@ public class SequenceRenderer } } + public void drawCursor(SequenceI seq, int res, int x1, int y1) + { + int pady = av.charHeight / 5; + int charOffset = 0; + graphics.setColor(Color.black); + graphics.fillRect(x1, y1, av.charWidth, av.charHeight); + graphics.setColor(Color.white); + + graphics.setColor(Color.white); + + char s = seq.getCharAt(res); + + charOffset = (av.charWidth - fm.charWidth(s)) / 2; + graphics.drawString(String.valueOf(s), + charOffset + x1, + (y1 + av.charHeight) - pady); + } + } -- 1.7.10.2