+ public void updateColours(SequenceI seq, int index)\r
+ {\r
+ System.out.println("update the seqPanel colours");\r
+ //repaint();\r
+ }\r
+\r
+ /**\r
+ * DOCUMENT ME!\r
+ *\r
+ * @param evt DOCUMENT ME!\r
+ */\r
+ public void mouseMoved(MouseEvent evt)\r
+ {\r
+ if (editingSeqs)\r
+ {\r
+ // This is because MacOSX creates a mouseMoved\r
+ // If control is down, other platforms will not.\r
+ mouseDragged(evt);\r
+ }\r
+\r
+ int res = findRes(evt);\r
+ int seq = findSeq(evt);\r
+\r
+ if (res < 0 || seq < 0 || seq >= av.getAlignment().getHeight())\r
+ {\r
+ return;\r
+ }\r
+\r
+ SequenceI sequence = av.getAlignment().getSequenceAt(seq);\r
+\r
+ if (res > sequence.getLength())\r
+ {\r
+ return;\r
+ }\r
+\r
+ if (ssm != null)\r
+ mouseOverSequence(sequence, sequence.findPosition(res));\r
+\r
+ setStatusMessage(sequence, res, seq);\r
+\r
+ tooltipText.setLength(6); // Cuts the buffer back to <html>\r
+\r
+ SequenceGroup[] groups = av.alignment.findAllGroups(sequence);\r
+ if (groups != null)\r
+ {\r
+ for (int g = 0; g < groups.length; g++)\r
+ {\r
+ if (groups[g].getStartRes() <= res && groups[g].getEndRes() >= res)\r
+ {\r
+ if (tooltipText.length() > 6)\r
+ {\r
+ tooltipText.append("<br>");\r
+ }\r
+\r
+ if (!groups[g].getName().startsWith("JTreeGroup") &&\r
+ !groups[g].getName().startsWith("JGroup"))\r
+ {\r
+ tooltipText.append(groups[g].getName());\r
+ }\r
+\r
+ if (groups[g].getDescription() != null)\r
+ {\r
+ tooltipText.append(": " + groups[g].getDescription());\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ // use aa to see if the mouse pointer is on a\r
+ if (av.showSequenceFeatures)\r
+ {\r
+ SequenceFeature[] features = findFeaturesAtRes(\r
+ sequence.getDatasetSequence(), sequence.findPosition(res));\r
+\r
+ if (features != null)\r
+ {\r
+ for (int i = 0; i < features.length; i++)\r
+ {\r
+ if (features[i].getType().equals("disulfide bond"))\r
+ {\r
+ if (features[i].getBegin() == sequence.findPosition(res)\r
+ || features[i].getEnd() == sequence.findPosition(res))\r
+ {\r
+ if (tooltipText.length() > 6)\r
+ {\r
+ tooltipText.append("<br>");\r
+ }\r
+ tooltipText.append("disulfide bond " + features[i].getBegin() +\r
+ ":" +\r
+ features[i].getEnd());\r
+ if (features[i].links != null)\r
+ {\r
+ tooltipText.append(" <img src=\"" + linkImageURL + "\">");\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (tooltipText.length() > 6)\r
+ {\r
+ tooltipText.append("<br>");\r
+ }\r
+\r
+ tooltipText.append(features[i].getType() + " " +\r
+ features[i].begin);\r
+ if (features[i].begin != features[i].end)\r
+ {\r
+ tooltipText.append(" " + features[i].end);\r
+ }\r
+\r
+ if (features[i].getDescription() != null\r
+ && !features[i].description.equals(features[i].getType()))\r
+ {\r
+ tmpString = features[i].getDescription();\r
+ int startTag = tmpString.toUpperCase().indexOf("<HTML>");\r
+ if (startTag > -1)\r
+ {\r
+ tmpString = tmpString.substring(startTag + 6);\r
+ }\r
+ int endTag = tmpString.toUpperCase().indexOf("</BODY>");\r
+ if (endTag > -1)\r
+ {\r
+ tmpString = tmpString.substring(0, endTag);\r
+ }\r
+ endTag = tmpString.toUpperCase().indexOf("</HTML>");\r
+ if (endTag > -1)\r
+ {\r
+ tmpString = tmpString.substring(0, endTag);\r
+ }\r
+\r
+ if (startTag > -1)\r
+ {\r
+ tooltipText.append("; " + tmpString);\r
+ }\r
+ else\r
+ {\r
+ if (tmpString.indexOf("<") > -1 || tmpString.indexOf(">") > -1)\r
+ {\r
+ //The description does not specify html is to\r
+ //be used, so we must remove < > symbols\r
+ tmpString = tmpString.replaceAll("<", "<");\r
+ tmpString = tmpString.replaceAll(">", ">");\r
+\r
+ tooltipText.append("; ");\r
+ tooltipText.append(tmpString);\r
+\r
+ }\r
+ else\r
+ {\r
+ tooltipText.append("; " + tmpString);\r
+ }\r
+ }\r
+ }\r
+ if (features[i].getValue("status") != null)\r
+ {\r
+ String status = features[i].getValue("status").toString();\r
+ if (status.length() > 0)\r
+ {\r
+ tooltipText.append("; (" + features[i].getValue("status") + ")");\r
+ }\r
+ }\r
+\r
+ if (features[i].links != null)\r
+ {\r
+ tooltipText.append(" <img src=\"" + linkImageURL + "\">");\r
+ }\r
+\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (tooltipText.length() == 6) // <html></html>\r
+ {\r
+ setToolTipText(null);\r
+ }\r
+ else\r
+ {\r
+ tooltipText.append("</html>");\r
+ setToolTipText(tooltipText.toString());\r
+ }\r
+ // else\r
+ // setToolTipText(null);\r
+ }\r
+\r
+ void setStatusMessage(SequenceI sequence, int res, int seq)\r
+ {\r
+ StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: " +\r
+ sequence.getName());\r
+\r
+ Object obj = null;\r
+ if (av.alignment.isNucleotide())\r
+ {\r
+ obj = ResidueProperties.nucleotideName.get(sequence.getCharAt(res) +\r
+ "");\r
+ if (obj != null)\r
+ {\r
+ text.append(" Nucleotide: ");\r
+ }\r
+ }\r
+ else\r
+ {\r
+ obj = ResidueProperties.aa2Triplet.get(sequence.getCharAt(res) + "");\r
+ if (obj != null)\r
+ {\r
+ text.append(" Residue: ");\r
+ }\r
+ }\r
+\r
+ if (obj != null)\r
+ {\r
+\r
+ if (obj != "")\r
+ {\r
+ text.append(obj + " (" + sequence.findPosition(res) +\r
+ ")");\r
+ }\r
+ }\r
+ ap.alignFrame.statusBar.setText(text.toString());\r
+\r
+ }\r
+\r
+ /**\r
+ * DOCUMENT ME!\r
+ *\r
+ * @param evt DOCUMENT ME!\r
+ */\r
+ public void mouseDragged(MouseEvent evt)\r
+ {\r
+ if (mouseWheelPressed)\r
+ {\r
+ int oldWidth = av.charWidth;\r
+\r
+ //Which is bigger, left-right or up-down?\r
+ if (Math.abs(evt.getY() - lastMousePress.getY())\r
+ > Math.abs(evt.getX() - lastMousePress.getX()))\r
+ {\r
+ int fontSize = av.font.getSize();\r
+\r
+ if (evt.getY() < lastMousePress.getY())\r
+ {\r
+ fontSize--;\r
+ }\r
+ else if (evt.getY() > lastMousePress.getY())\r
+ {\r
+ fontSize++;\r
+ }\r
+\r
+ if (fontSize < 1)\r
+ {\r
+ fontSize = 1;\r
+ }\r
+\r
+ av.setFont(new Font(av.font.getName(), av.font.getStyle(), fontSize));\r
+ av.charWidth = oldWidth;\r
+ ap.fontChanged();\r
+ }\r
+ else\r
+ {\r
+ if (evt.getX() < lastMousePress.getX() && av.charWidth > 1)\r
+ {\r
+ av.charWidth--;\r
+ }\r
+ else if (evt.getX() > lastMousePress.getX())\r
+ {\r
+ av.charWidth++;\r
+ }\r
+\r
+ ap.paintAlignment(false);\r
+ }\r
+\r
+ FontMetrics fm = getFontMetrics(av.getFont());\r
+ av.validCharWidth = fm.charWidth('M') <= av.charWidth;\r
+\r
+ lastMousePress = evt.getPoint();\r
+\r
+ return;\r
+ }\r
+\r
+ if (!editingSeqs)\r
+ {\r
+ doMouseDraggedDefineMode(evt);\r
+ return;\r
+ }\r
+\r
+ int res = findRes(evt);\r
+\r
+ if (res < 0)\r
+ {\r
+ res = 0;\r
+ }\r
+\r
+ if ( (lastres == -1) || (lastres == res))\r
+ {\r
+ return;\r
+ }\r
+\r
+ if ( (res < av.getAlignment().getWidth()) && (res < lastres))\r
+ {\r
+ // dragLeft, delete gap\r
+ editSequence(false, res);\r
+ }\r
+ else\r
+ {\r
+ editSequence(true, res);\r
+ }\r
+\r
+ mouseDragging = true;\r
+ if (scrollThread != null)\r
+ {\r
+ scrollThread.setEvent(evt);\r
+ }\r
+ }\r
+\r
+\r
+\r
+ synchronized void editSequence(boolean insertGap, int startres)\r
+ {\r
+ int fixedLeft = -1;\r
+ int fixedRight = -1;\r
+ boolean fixedColumns = false;\r
+ SequenceGroup sg = av.getSelectionGroup();\r
+\r
+ SequenceI seq = av.alignment.getSequenceAt(startseq);\r
+\r
+ //No group, but the sequence may represent a group\r
+ if (!groupEditing && av.hasHiddenRows)\r
+ {\r
+ if (av.hiddenRepSequences != null\r
+ && av.hiddenRepSequences.containsKey(seq))\r
+ {\r
+ sg = (SequenceGroup) av.hiddenRepSequences.get(seq);\r
+ groupEditing = true;\r
+ }\r
+ }\r
+\r
+ StringBuffer message = new StringBuffer();\r
+ if (groupEditing)\r
+ {\r
+ message.append("Edit group:");\r
+ if (editCommand == null)\r
+ {\r
+ editCommand = new EditCommand("Edit Group");\r
+ }\r
+ }\r
+ else\r
+ {\r
+ message.append("Edit sequence: " + seq.getName());\r
+ String label = seq.getName();\r
+ if (label.length() > 10)\r
+ {\r
+ label = label.substring(0, 10);\r
+ }\r
+ if (editCommand == null)\r
+ {\r
+ editCommand = new EditCommand("Edit " + label);\r
+ }\r
+ }\r
+\r
+ if (insertGap)\r
+ {\r
+ message.append(" insert ");\r
+ }\r
+ else\r
+ {\r
+ message.append(" delete ");\r
+ }\r
+\r
+ message.append(Math.abs(startres - lastres) + " gaps.");\r
+ ap.alignFrame.statusBar.setText(message.toString());\r
+\r
+ //Are we editing within a selection group?\r
+ if (groupEditing\r
+ || (sg != null && sg.getSequences(av.hiddenRepSequences).contains(seq)))\r
+ {\r
+ fixedColumns = true;\r
+\r
+ //sg might be null as the user may only see 1 sequence,\r
+ //but the sequence represents a group\r
+ if (sg == null)\r
+ {\r
+ if (av.hiddenRepSequences == null\r
+ || !av.hiddenRepSequences.containsKey(seq))\r
+ {\r
+ endEditing();\r
+ return;\r
+ }\r
+ sg = (SequenceGroup) av.hiddenRepSequences.get(seq);\r
+ }\r
+\r
+ fixedLeft = sg.getStartRes();\r
+ fixedRight = sg.getEndRes();\r
+\r
+ if ( (startres < fixedLeft && lastres >= fixedLeft)\r
+ || (startres >= fixedLeft && lastres < fixedLeft)\r
+ || (startres > fixedRight && lastres <= fixedRight)\r
+ || (startres <= fixedRight && lastres > fixedRight))\r
+ {\r
+ endEditing();\r
+ return;\r
+ }\r
+\r
+ if (fixedLeft > startres)\r
+ {\r
+ fixedRight = fixedLeft - 1;\r
+ fixedLeft = 0;\r
+ }\r
+ else if (fixedRight < startres)\r
+ {\r
+ fixedLeft = fixedRight;\r
+ fixedRight = -1;\r
+ }\r
+ }\r
+\r
+ if (av.hasHiddenColumns)\r
+ {\r
+ fixedColumns = true;\r
+ int y1 = av.getColumnSelection().getHiddenBoundaryLeft(startres);\r
+ int y2 = av.getColumnSelection().getHiddenBoundaryRight(startres);\r
+\r
+ if ( (insertGap && startres > y1 && lastres < y1)\r
+ || (!insertGap && startres < y2 && lastres > y2))\r
+ {\r
+ endEditing();\r
+ return;\r
+ }\r
+\r
+ //System.out.print(y1+" "+y2+" "+fixedLeft+" "+fixedRight+"~~");\r
+ //Selection spans a hidden region\r
+ if (fixedLeft < y1 && (fixedRight > y2 || fixedRight == -1))\r
+ {\r
+ if (startres >= y2)\r
+ {\r
+ fixedLeft = y2;\r
+ }\r
+ else\r
+ {\r
+ fixedRight = y2 - 1;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (groupEditing)\r
+ {\r
+ Vector vseqs = sg.getSequences(av.hiddenRepSequences);\r
+ int g, groupSize = vseqs.size();\r
+ SequenceI[] groupSeqs = new SequenceI[groupSize];\r
+ for (g = 0; g < groupSeqs.length; g++)\r
+ {\r
+ groupSeqs[g] = (SequenceI) vseqs.elementAt(g);\r
+ }\r
+\r
+ // drag to right\r
+ if (insertGap)\r
+ {\r
+ //If the user has selected the whole sequence, and is dragging to\r
+ // the right, we can still extend the alignment and selectionGroup\r
+ if (sg.getStartRes() == 0\r
+ && sg.getEndRes() == fixedRight\r
+ && sg.getEndRes() == av.alignment.getWidth() - 1\r
+ )\r
+ {\r
+ sg.setEndRes(av.alignment.getWidth() + startres - lastres);\r
+ fixedRight = sg.getEndRes();\r
+ }\r
+\r
+ // Is it valid with fixed columns??\r
+ // Find the next gap before the end\r
+ // of the visible region boundary\r
+ boolean blank = false;\r
+ for (fixedRight = fixedRight;\r
+ fixedRight > lastres;\r
+ fixedRight--)\r
+ {\r
+ blank = true;\r
+\r
+ for (g = 0; g < groupSize; g++)\r
+ {\r
+ for (int j = 0; j < startres - lastres; j++)\r
+ {\r
+ if (!jalview.util.Comparison.isGap(\r
+ groupSeqs[g].getCharAt(fixedRight - j)))\r
+ {\r
+ blank = false;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if (blank)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (!blank)\r
+ {\r
+ if (sg.getSize() == av.alignment.getHeight())\r
+ {\r
+ if ( (av.hasHiddenColumns\r
+ &&\r
+ startres < av.getColumnSelection().getHiddenBoundaryRight(startres)))\r
+ {\r
+ endEditing();\r
+ return;\r
+ }\r
+\r
+ int alWidth = av.alignment.getWidth();\r
+ if (av.hasHiddenRows)\r
+ {\r
+ int hwidth = av.alignment.getHiddenSequences().getWidth();\r
+ if (hwidth > alWidth)\r
+ {\r
+ alWidth = hwidth;\r
+ }\r
+ }\r
+ //We can still insert gaps if the selectionGroup\r
+ //contains all the sequences\r
+ sg.setEndRes(sg.getEndRes() + startres - lastres);\r
+ fixedRight = alWidth + startres - lastres;\r
+ }\r
+ else\r
+ {\r
+ endEditing();\r
+ return;\r
+ }\r
+ }\r
+ }\r
+\r
+ // drag to left\r
+ else if (!insertGap)\r
+ {\r
+ /// Are we able to delete?\r
+ // ie are all columns blank?\r
+\r
+ for (g = 0; g < groupSize; g++)\r
+ {\r
+ for (int j = startres; j < lastres; j++)\r
+ {\r
+ if (groupSeqs[g].getLength() <= j)\r
+ {\r
+ continue;\r
+ }\r
+\r
+ if (!jalview.util.Comparison.isGap(\r
+ groupSeqs[g].getCharAt(j)))\r
+ {\r
+ // Not a gap, block edit not valid\r
+ endEditing();\r
+ return;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (insertGap)\r
+ {\r
+ // dragging to the right\r
+ if (fixedColumns && fixedRight != -1)\r
+ {\r
+ for (int j = lastres; j < startres; j++)\r
+ {\r
+ insertChar(j, groupSeqs, fixedRight);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ editCommand.appendEdit(EditCommand.INSERT_GAP,\r
+ groupSeqs,\r
+ startres, startres - lastres,\r
+ av.alignment,\r
+ true);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // dragging to the left\r
+ if (fixedColumns && fixedRight != -1)\r
+ {\r
+ for (int j = lastres; j > startres; j--)\r
+ {\r
+ deleteChar(startres, groupSeqs, fixedRight);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ editCommand.appendEdit(EditCommand.DELETE_GAP,\r
+ groupSeqs,\r
+ startres, lastres - startres,\r
+ av.alignment,\r
+ true);\r
+ }\r
+\r
+ }\r
+ }\r
+ else /////Editing a single sequence///////////\r
+ {\r
+ if (insertGap)\r
+ {\r
+ // dragging to the right\r
+ if (fixedColumns && fixedRight != -1)\r
+ {\r
+ for (int j = lastres; j < startres; j++)\r
+ {\r
+ insertChar(j, new SequenceI[]\r
+ {seq}, fixedRight);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ editCommand.appendEdit(EditCommand.INSERT_GAP,\r
+ new SequenceI[]\r
+ {seq},\r
+ lastres, startres - lastres,\r
+ av.alignment,\r
+ true);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // dragging to the left\r
+ if (fixedColumns && fixedRight != -1)\r
+ {\r
+ for (int j = lastres; j > startres; j--)\r
+ {\r
+ if (!jalview.util.Comparison.isGap(seq.getCharAt(startres)))\r
+ {\r
+ endEditing();\r
+ break;\r
+ }\r
+ deleteChar(startres, new SequenceI[]\r
+ {seq}, fixedRight);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ //could be a keyboard edit trying to delete none gaps\r
+ int max = 0;\r
+ for (int m = startres; m < lastres; m++)\r
+ {\r
+ if (!jalview.util.Comparison.isGap(seq.getCharAt(m)))\r
+ {\r
+ break;\r
+ }\r
+ max++;\r
+ }\r
+\r
+ if (max > 0)\r
+ {\r
+ editCommand.appendEdit(EditCommand.DELETE_GAP,\r
+ new SequenceI[]\r
+ {seq},\r
+ startres, max,\r
+ av.alignment,\r
+ true);\r
+ }\r
+ }\r
+ }\r
+ }\r