/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.0b1)
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
* Copyright (C) 2014 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 <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
package jalview.gui;
-import java.util.*;
-import java.util.regex.Pattern;
-
-import java.awt.*;
-import java.awt.datatransfer.*;
-import java.awt.event.*;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.FormatAdapter;
+import jalview.util.MessageManager;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.MediaTracker;
+import java.awt.RenderingHints;
+import java.awt.Toolkit;
+import java.awt.datatransfer.StringSelection;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
-import java.awt.image.*;
-import javax.swing.*;
+import java.awt.image.BufferedImage;
+import java.util.Arrays;
+import java.util.Vector;
+import java.util.regex.Pattern;
-import jalview.datamodel.*;
-import jalview.io.*;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.SwingUtilities;
+import javax.swing.ToolTipManager;
/**
* DOCUMENT ME!
public class AnnotationLabels extends JPanel implements MouseListener,
MouseMotionListener, ActionListener
{
- static String TOGGLE_LABELSCALE = "Scale Label to Column";
+ String TOGGLE_LABELSCALE = MessageManager.getString("label.scale_label_to_column");
- static String ADDNEW = "Add New Row";
+ String ADDNEW = MessageManager.getString("label.add_new_row");
- static String EDITNAME = "Edit Label/Description";
+ String EDITNAME = MessageManager.getString("label.edit_label_description");
- static String HIDE = "Hide This Row";
+ String HIDE = MessageManager.getString("label.hide_row");
- static String DELETE = "Delete This Row";
+ String DELETE = MessageManager.getString("label.delete_row");
- static String SHOWALL = "Show All Hidden Rows";
+ String SHOWALL = MessageManager.getString("label.show_all_hidden_rows");
- static String OUTPUT_TEXT = "Export Annotation";
+ String OUTPUT_TEXT = MessageManager.getString("label.export_annotation");
- static String COPYCONS_SEQ = "Copy Consensus Sequence";
+ String COPYCONS_SEQ = MessageManager.getString("label.copy_consensus_sequence");
boolean resizePanel = false;
int selectedRow;
- int scrollOffset = 0;
+ private int scrollOffset = 0;
Font font = new Font("Arial", Font.PLAIN, 11);
Graphics2D g = (Graphics2D) bi.getGraphics();
g.rotate(Math.toRadians(90));
g.drawImage(temp, 0, -bi.getWidth(this), this);
- image = (Image) bi;
+ image = bi;
addMouseListener(this);
addMouseMotionListener(this);
- addMouseWheelListener(ap.annotationPanel);
+ addMouseWheelListener(ap.getAnnotationPanel());
}
public AnnotationLabels(AlignViewport av)
aa[selectedRow].scaleColLabel = !aa[selectedRow].scaleColLabel;
}
+ refresh();
+
+ }
+
+ /**
+ * Redraw sensibly.
+ */
+ protected void refresh()
+ {
ap.validateAnnotationDimensions(false);
ap.addNotify();
ap.repaint();
- // validate();
- // ap.paintAlignment(true);
}
/**
*/
public void mousePressed(MouseEvent evt)
{
- getSelectedRow(evt.getY() - scrollOffset);
+ getSelectedRow(evt.getY() - getScrollOffset());
oldY = evt.getY();
}
public void mouseReleased(MouseEvent evt)
{
int start = selectedRow;
- getSelectedRow(evt.getY() - scrollOffset);
+ getSelectedRow(evt.getY() - getScrollOffset());
int end = selectedRow;
if (start != end)
resizePanel = false;
dragEvent = null;
repaint();
- ap.annotationPanel.repaint();
+ ap.getAnnotationPanel().repaint();
}
/**
{
resizePanel = evt.getY() < 10;
- getSelectedRow(evt.getY() - scrollOffset);
+ getSelectedRow(evt.getY() - getScrollOffset());
if (selectedRow > -1
&& ap.av.getAlignment().getAlignmentAnnotation().length > selectedRow)
{
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 (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);
+ }
}
-
}
/**
*/
public void mouseClicked(MouseEvent evt)
{
- AlignmentAnnotation[] aa = ap.av.getAlignment()
+ final AlignmentAnnotation[] aa = ap.av.getAlignment()
.getAlignmentAnnotation();
if (SwingUtilities.isLeftMouseButton(evt))
{
{
// todo: make the ap scroll to the selection - not necessary, first
// click highlights/scrolls, second selects
- ap.seqPanel.ap.idPanel.highlightSearchResults(null);
+ ap.getSeqPanel().ap.getIdPanel().highlightSearchResults(null);
ap.av.setSelectionGroup(// new SequenceGroup(
aa[selectedRow].groupRef); // );
ap.paintAlignment(false);
}
else
{
- ap.seqPanel.ap.idPanel
+ ap.getSeqPanel().ap.getIdPanel()
.highlightSearchResults(aa[selectedRow].groupRef
.getSequences(null));
}
}
else if (aa[selectedRow].sequenceRef != null)
{
- Vector sr = new Vector();
- sr.addElement(aa[selectedRow].sequenceRef);
if (evt.getClickCount() == 1)
{
- ap.seqPanel.ap.idPanel.highlightSearchResults(sr);
+ ap.getSeqPanel().ap.getIdPanel().highlightSearchResults(Arrays
+ .asList(new SequenceI[]
+ { aa[selectedRow].sequenceRef }));
}
else if (evt.getClickCount() >= 2)
{
- ap.seqPanel.ap.idPanel.highlightSearchResults(null);
- SequenceGroup sg = new SequenceGroup();
- sg.addSequence(aa[selectedRow].sequenceRef, false);
+ 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 (!(evt.isControlDown() || evt.isShiftDown()))
+ {
+ sg = new SequenceGroup(sg);
+ sg.clear();
+ sg.addSequence(aa[selectedRow].sequenceRef, false);
+ } else {
+ if (evt.isControlDown())
+ {
+ 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.av.sendSelection();
ap.paintAlignment(false);
return;
}
- JPopupMenu pop = new JPopupMenu("Annotations");
+ JPopupMenu pop = new JPopupMenu(
+ MessageManager.getString("label.annotations"));
JMenuItem item = new JMenuItem(ADDNEW);
item.addActionListener(this);
pop.add(item);
item = new JMenuItem(HIDE);
item.addActionListener(this);
pop.add(item);
+ // JAL-1264 hide all sequence-specific annotations of this type
+ final String label = aa[selectedRow].label;
+ if (selectedRow < aa.length)
+ {
+ if (aa[selectedRow].sequenceRef != null)
+ {
+ JMenuItem hideType = new JMenuItem();
+ String text = MessageManager.getString("label.hide_all") + " " + label;
+ hideType.setText(text);
+ hideType.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ for (AlignmentAnnotation ann : ap.av.getAlignment()
+ .getAlignmentAnnotation())
+ {
+ if (ann.sequenceRef != null && ann.label != null
+ && ann.label.equals(label))
+ {
+ ann.visible = false;
+ }
+ }
+ refresh();
+ }
+ });
+ pop.add(hideType);
+ }
+ }
item = new JMenuItem(DELETE);
item.addActionListener(this);
pop.add(item);
pop.add(item);
}
}
- else if (aa[selectedRow].label.indexOf("Consensus") > -1)
+ else if (label.indexOf("Consensus") > -1)
{
pop.addSeparator();
// av and sequencegroup need to implement same interface for
final JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem(
- "Ignore Gaps In Consensus",
+ MessageManager.getString("label.ignore_gaps_consensus"),
(aa[selectedRow].groupRef != null) ? aa[selectedRow].groupRef
.getIgnoreGapsConsensus() : ap.av
.getIgnoreGapsConsensus());
{
// TODO: pass on reference to ap so the view can be updated.
aaa.groupRef.setIgnoreGapsConsensus(cbmi.getState());
- ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
+ ap.getAnnotationPanel().paint(ap.getAnnotationPanel().getGraphics());
}
else
{
if (aaa.groupRef != null)
{
final JCheckBoxMenuItem chist = new JCheckBoxMenuItem(
- "Show Group Histogram",
+ MessageManager.getString("label.show_group_histogram"),
aa[selectedRow].groupRef.isShowConsensusHistogram());
chist.addActionListener(new ActionListener()
{
});
pop.add(chist);
final JCheckBoxMenuItem cprofl = new JCheckBoxMenuItem(
- "Show Group Logo",
+ MessageManager.getString("label.show_group_logo"),
aa[selectedRow].groupRef.isShowSequenceLogo());
cprofl.addActionListener(new ActionListener()
{
});
pop.add(cprofl);
final JCheckBoxMenuItem cproflnorm = new JCheckBoxMenuItem(
- "Normalise Group Logo",
+ MessageManager.getString("label.normalise_group_logo"),
aa[selectedRow].groupRef.isNormaliseSequenceLogo());
cproflnorm.addActionListener(new ActionListener()
{
else
{
final JCheckBoxMenuItem chist = new JCheckBoxMenuItem(
- "Show Histogram", av.isShowConsensusHistogram());
+ MessageManager.getString("label.show_histogram"), av.isShowConsensusHistogram());
chist.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
});
pop.add(chist);
final JCheckBoxMenuItem cprof = new JCheckBoxMenuItem(
- "Show Logo", av.isShowSequenceLogo());
+ MessageManager.getString("label.show_logo"), av.isShowSequenceLogo());
cprof.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
});
pop.add(cprof);
final JCheckBoxMenuItem cprofnorm = new JCheckBoxMenuItem(
- "Normalise Logo", av.isNormaliseSequenceLogo());
+ MessageManager.getString("label.normalise_logo"), av.isNormaliseSequenceLogo());
cprofnorm.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
}
/**
- * Draw the full set of annotation Labels for the alignment at the given cursor
+ * Draw the full set of annotation Labels for the alignment at the given
+ * cursor
+ *
+ * @param g
+ * Graphics2D instance (needed for font scaling)
+ * @param width
+ * Width for scaling labels
*
- * @param g Graphics2D instance (needed for font scaling)
- * @param width Width for scaling labels
- *
*/
public void drawComponent(Graphics g, int width)
{
}
private final boolean debugRedraw = false;
+
/**
- * Draw the full set of annotation Labels for the alignment at the given cursor
+ * Draw the full set of annotation Labels for the alignment at the given
+ * cursor
*
- * @param g Graphics2D instance (needed for font scaling)
- * @param clip - true indicates that only current visible area needs to be rendered
- * @param width Width for scaling labels
+ * @param g
+ * Graphics2D instance (needed for font scaling)
+ * @param clip
+ * - true indicates that only current visible area needs to be
+ * rendered
+ * @param width
+ * Width for scaling labels
*/
public void drawComponent(Graphics g, boolean clip, int width)
{
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
- g.translate(0, scrollOffset);
+ g.translate(0, getScrollOffset());
g.setColor(Color.black);
-
+
AlignmentAnnotation[] aa = av.getAlignment().getAlignmentAnnotation();
int fontHeight = g.getFont().getSize();
int y = 0;
Font baseFont = g.getFont();
FontMetrics baseMetrics = fm;
int ofontH = fontHeight;
- int sOffset=0;
+ int sOffset = 0;
int visHeight = 0;
- int[] visr = (ap!=null && ap.annotationPanel!=null) ? ap.annotationPanel.getVisibleVRange() : null;
- if (clip && visr!=null){
- sOffset = visr[0];
+ int[] visr = (ap != null && ap.getAnnotationPanel() != null) ? ap.getAnnotationPanel()
+ .getVisibleVRange() : null;
+ if (clip && visr != null)
+ {
+ sOffset = visr[0];
visHeight = visr[1];
}
- boolean visible = true,before=false,after=false;
+ boolean visible = true, before = false, after = false;
if (aa != null)
{
hasHiddenRows = false;
- int olY=0;
+ int olY = 0;
for (int i = 0; i < aa.length; i++)
{
visible = true;
hasHiddenRows = true;
continue;
}
- olY=y;
+ olY = y;
y += aa[i].height;
- if (clip) {if (y<sOffset)
+ if (clip)
{
- if (!before)
+ if (y < sOffset)
{
- if (debugRedraw) {
- System.out.println("before vis: "+i);
+ if (!before)
+ {
+ if (debugRedraw)
+ {
+ System.out.println("before vis: " + i);
+ }
+ before = true;
}
- before=true;
+ // don't draw what isn't visible
+ continue;
}
- // don't draw what isn't visible
- continue;
- }
- if (olY>visHeight)
- {
-
- if (!after)
+ if (olY > visHeight)
{
- if (debugRedraw) {
- System.out.println("Scroll offset: "+sOffset+" after vis: "+i);
+
+ if (!after)
+ {
+ if (debugRedraw)
+ {
+ System.out.println("Scroll offset: " + sOffset
+ + " after vis: " + i);
+ }
+ after = true;
}
- after=true;
+ // don't draw what isn't visible
+ continue;
}
- // don't draw what isn't visible
- continue;
- }}
+ }
g.setColor(Color.black);
offset = -aa[i].height / 2;
offset -= fm.getDescent();
}
else
+ {
offset += fm.getDescent();
+ }
x = width - fm.stringWidth(aa[i].label) - 3;
if (aa[i].graphGroup > -1)
{
int groupSize = 0;
- // TODO: JAL-1291 revise rendering model so the graphGroup map is computed efficiently for all visible labels
+ // TODO: JAL-1291 revise rendering model so the graphGroup map is
+ // computed efficiently for all visible labels
for (int gg = 0; gg < aa.length; gg++)
{
if (aa[gg].graphGroup == aa[i].graphGroup)
if (resizePanel)
{
- g.drawImage(image, 2, 0 - scrollOffset, this);
+ g.drawImage(image, 2, 0 - getScrollOffset(), this);
}
else if (dragEvent != null && aa != null)
{
g.setColor(Color.lightGray);
g.drawString(aa[selectedRow].label, dragEvent.getX(),
- dragEvent.getY() - scrollOffset);
+ dragEvent.getY() - getScrollOffset());
}
if (!av.wrapAlignment && ((aa == null) || (aa.length < 1)))
{
- g.drawString("Right click", 2, 8);
- g.drawString("to add annotation", 2, 18);
+ g.drawString(MessageManager.getString("label.right_click"), 2, 8);
+ g.drawString(MessageManager.getString("label.to_add_annotation"), 2,
+ 18);
}
}
+
+ public int getScrollOffset()
+ {
+ return scrollOffset;
+ }
}