+ * DOCUMENT ME!
+ *
+ * @param evt
+ * DOCUMENT ME!
+ */
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ if (evt.isPopupTrigger())
+ {
+ showPopupMenu(evt);
+ return;
+ }
+
+ int start = selectedRow;
+ getSelectedRow(evt.getY() - getScrollOffset());
+ int end = selectedRow;
+
+ if (start != end)
+ {
+ // Swap these annotations
+ AlignmentAnnotation startAA = ap.av.getAlignment()
+ .getAlignmentAnnotation()[start];
+ if (end == -1)
+ {
+ end = ap.av.getAlignment().getAlignmentAnnotation().length - 1;
+ }
+ AlignmentAnnotation endAA = ap.av.getAlignment()
+ .getAlignmentAnnotation()[end];
+
+ ap.av.getAlignment().getAlignmentAnnotation()[end] = startAA;
+ ap.av.getAlignment().getAlignmentAnnotation()[start] = endAA;
+ }
+
+ resizePanel = false;
+ dragEvent = null;
+ repaint();
+ ap.getAnnotationPanel().repaint();
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param evt
+ * DOCUMENT ME!
+ */
+ @Override
+ public void mouseEntered(MouseEvent evt)
+ {
+ if (evt.getY() < 10)
+ {
+ resizePanel = true;
+ repaint();
+ }
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param evt
+ * DOCUMENT ME!
+ */
+ @Override
+ public void mouseExited(MouseEvent evt)
+ {
+ if (dragEvent == null)
+ {
+ resizePanel = false;
+ repaint();
+ }
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param evt
+ * DOCUMENT ME!
+ */
+ @Override
+ public void mouseDragged(MouseEvent evt)
+ {
+ dragEvent = evt;
+
+ if (resizePanel)
+ {
+ Dimension d = ap.annotationScroller.getPreferredSize();
+ int dif = evt.getY() - oldY;
+
+ dif /= ap.av.getCharHeight();
+ dif *= ap.av.getCharHeight();
+
+ if ((d.height - dif) > 20)
+ {
+ ap.annotationScroller.setPreferredSize(new Dimension(d.width,
+ d.height - dif));
+ d = ap.annotationSpaceFillerHolder.getPreferredSize();
+ ap.annotationSpaceFillerHolder.setPreferredSize(new Dimension(
+ d.width, d.height - dif));
+ ap.paintAlignment(true);
+ }
+
+ ap.addNotify();
+ }
+ else
+ {
+ repaint();
+ }
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param evt
+ * DOCUMENT ME!
+ */
+ @Override
+ public void mouseMoved(MouseEvent evt)
+ {
+ resizePanel = evt.getY() < 10;
+
+ getSelectedRow(evt.getY() - getScrollOffset());
+
+ if (selectedRow > -1
+ && ap.av.getAlignment().getAlignmentAnnotation().length > selectedRow)
+ {
+ AlignmentAnnotation aa = ap.av.getAlignment()
+ .getAlignmentAnnotation()[selectedRow];
+
+ StringBuffer desc = new StringBuffer();
+ if (aa.description != null
+ && !aa.description.equals("New description"))
+ {
+ // TODO: we could refactor and merge this code with the code in
+ // jalview.gui.SeqPanel.mouseMoved(..) that formats sequence feature
+ // tooltips
+ desc.append(aa.getDescription(true).trim());
+ // check to see if the description is an html fragment.
+ if (desc.length() < 6
+ || (desc.substring(0, 6).toLowerCase().indexOf("<html>") < 0))
+ {
+ // clean the description ready for embedding in html
+ desc = new StringBuffer(LEFT_ANGLE_BRACKET_PATTERN.matcher(desc)
+ .replaceAll("<"));
+ desc.insert(0, "<html>");
+ }
+ else
+ {
+ // remove terminating html if any
+ int i = desc.substring(desc.length() - 7).toLowerCase()
+ .lastIndexOf("</html>");
+ if (i > -1)
+ {
+ desc.setLength(desc.length() - 7 + i);
+ }
+ }
+ if (aa.hasScore())
+ {
+ desc.append("<br/>");
+ }
+ // if (aa.hasProperties())
+ // {
+ // desc.append("<table>");
+ // for (String prop : aa.getProperties())
+ // {
+ // desc.append("<tr><td>" + prop + "</td><td>"
+ // + aa.getProperty(prop) + "</td><tr>");
+ // }
+ // desc.append("</table>");
+ // }
+ }
+ else
+ {
+ // begin the tooltip's html fragment
+ desc.append("<html>");
+ if (aa.hasScore())
+ {
+ // TODO: limit precision of score to avoid noise from imprecise
+ // doubles
+ // (64.7 becomes 64.7+/some tiny value).
+ desc.append(" Score: " + aa.score);
+ }
+ }
+ if (desc.length() > 6)
+ {
+ desc.append("</html>");
+ this.setToolTipText(desc.toString());
+ }
+ else
+ {
+ this.setToolTipText(null);
+ }
+ }
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent evt)
+ {
+ final AlignmentAnnotation[] aa = ap.av.getAlignment()
+ .getAlignmentAnnotation();
+ if (!evt.isPopupTrigger() && SwingUtilities.isLeftMouseButton(evt))
+ {
+ if (selectedRow > -1 && selectedRow < aa.length)
+ {
+ if (aa[selectedRow].groupRef != null)
+ {
+ if (evt.getClickCount() >= 2)
+ {
+ // todo: make the ap scroll to the selection - not necessary, first
+ // click highlights/scrolls, second selects
+ ap.getSeqPanel().ap.getIdPanel().highlightSearchResults(null);
+ // process modifiers
+ SequenceGroup sg = ap.av.getSelectionGroup();
+ if (sg == null
+ || sg == aa[selectedRow].groupRef
+ || !(jalview.util.Platform.isControlDown(evt) || evt
+ .isShiftDown()))
+ {
+ if (jalview.util.Platform.isControlDown(evt)
+ || evt.isShiftDown())
+ {
+ // clone a new selection group from the associated group
+ ap.av.setSelectionGroup(new SequenceGroup(
+ aa[selectedRow].groupRef));
+ }
+ else
+ {
+ // set selection to the associated group so it can be edited
+ ap.av.setSelectionGroup(aa[selectedRow].groupRef);
+ }
+ }
+ else
+ {
+ // modify current selection with associated group
+ int remainToAdd = aa[selectedRow].groupRef.getSize();
+ for (SequenceI sgs : aa[selectedRow].groupRef.getSequences())
+ {
+ if (jalview.util.Platform.isControlDown(evt))
+ {
+ sg.addOrRemove(sgs, --remainToAdd == 0);
+ }
+ else
+ {
+ // notionally, we should also add intermediate sequences from
+ // last added sequence ?
+ sg.addSequence(sgs, --remainToAdd == 0);
+ }
+ }
+ }
+
+ ap.paintAlignment(false);
+ PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
+ ap.av.sendSelection();
+ }
+ else
+ {
+ ap.getSeqPanel().ap.getIdPanel().highlightSearchResults(
+ aa[selectedRow].groupRef.getSequences(null));
+ }
+ return;
+ }
+ else if (aa[selectedRow].sequenceRef != null)
+ {
+ if (evt.getClickCount() == 1)
+ {
+ ap.getSeqPanel().ap
+ .getIdPanel()
+ .highlightSearchResults(
+ Arrays.asList(new SequenceI[] { aa[selectedRow].sequenceRef }));
+ }
+ else if (evt.getClickCount() >= 2)
+ {
+ ap.getSeqPanel().ap.getIdPanel().highlightSearchResults(null);
+ SequenceGroup sg = ap.av.getSelectionGroup();
+ if (sg != null)
+ {
+ // we make a copy rather than edit the current selection if no
+ // modifiers pressed
+ // see Enhancement JAL-1557
+ if (!(jalview.util.Platform.isControlDown(evt) || evt
+ .isShiftDown()))
+ {
+ sg = new SequenceGroup(sg);
+ sg.clear();
+ sg.addSequence(aa[selectedRow].sequenceRef, false);
+ }
+ else
+ {
+ if (jalview.util.Platform.isControlDown(evt))
+ {
+ sg.addOrRemove(aa[selectedRow].sequenceRef, true);
+ }
+ else
+ {
+ // notionally, we should also add intermediate sequences from
+ // last added sequence ?
+ sg.addSequence(aa[selectedRow].sequenceRef, true);
+ }
+ }
+ }
+ else
+ {
+ sg = new SequenceGroup();
+ sg.setStartRes(0);
+ sg.setEndRes(ap.av.getAlignment().getWidth() - 1);
+ sg.addSequence(aa[selectedRow].sequenceRef, false);
+ }
+ ap.av.setSelectionGroup(sg);
+ ap.paintAlignment(false);
+ PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
+ ap.av.sendSelection();
+ }
+
+ }
+ }
+ return;
+ }
+ }
+
+ /**