X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=srcjar%2Ffr%2Forsay%2Flri%2Fvarna%2Fmodels%2Fannotations%2FTextAnnotation.java;fp=srcjar%2Ffr%2Forsay%2Flri%2Fvarna%2Fmodels%2Fannotations%2FTextAnnotation.java;h=0db63a5e973e923e9c3e7f2bfbb47cface28ff8c;hb=e95c5f895775891d55d9f23d5da64f8ce6bd07bb;hp=0000000000000000000000000000000000000000;hpb=74f21ca6ca8fa17d53708e457d191e15904f8310;p=jalview.git diff --git a/srcjar/fr/orsay/lri/varna/models/annotations/TextAnnotation.java b/srcjar/fr/orsay/lri/varna/models/annotations/TextAnnotation.java new file mode 100644 index 0000000..0db63a5 --- /dev/null +++ b/srcjar/fr/orsay/lri/varna/models/annotations/TextAnnotation.java @@ -0,0 +1,537 @@ +/* + VARNA is a tool for the automated drawing, visualization and annotation of the secondary structure of RNA, designed as a companion software for web servers and databases. + Copyright (C) 2008 Kevin Darty, Alain Denise and Yann Ponty. + electronic mail : Yann.Ponty@lri.fr + paper mail : LRI, bat 490 Universit� Paris-Sud 91405 Orsay Cedex France + + This file is part of VARNA version 3.1. + VARNA version 3.1 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. + + VARNA version 3.1 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 VARNA version 3.1. + If not, see http://www.gnu.org/licenses. + */ +package fr.orsay.lri.varna.models.annotations; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Point2D; +import java.io.Serializable; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Collections; + +import javax.xml.transform.sax.TransformerHandler; + +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import fr.orsay.lri.varna.models.rna.ModeleBase; +import fr.orsay.lri.varna.VARNAPanel; +import fr.orsay.lri.varna.models.VARNAConfigLoader; +import fr.orsay.lri.varna.models.rna.ModelBaseStyle; +import fr.orsay.lri.varna.models.rna.VARNAPoint; +import fr.orsay.lri.varna.utils.XMLUtils; + + + +/** + * The annotated text model + * + * @author Darty@lri.fr + * + */ +public class TextAnnotation implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 465236085501860747L; + + public enum AnchorType{ + POSITION, + BASE, + HELIX, + LOOP + }; + + + public static final String HEADER_TEXT = "TextAnnotation"; + + /** + * default text color + */ + public static final Color DEFAULTCOLOR = Color.black; + /** + * default text font + */ + public static final Font DEFAULTFONT = new Font("Arial", Font.PLAIN, 12); + + private String _text; + private AnchorType _typeAnchor; + private Color _color; + private double _angle; + private Object _anchor; + private Font _font; + + public static String XML_ELEMENT_NAME = "textAnnotation"; + public static String XML_VAR_TYPE_NAME = "type"; + public static String XML_VAR_COLOR_NAME = "color"; + public static String XML_VAR_ANGLE_NAME = "angle"; + public static String XML_VAR_TEXT_NAME = "text"; + + public void toXML(TransformerHandler hd) throws SAXException + { + AttributesImpl atts = new AttributesImpl(); + atts.addAttribute("","",XML_VAR_TYPE_NAME,"CDATA",""+_typeAnchor); + atts.addAttribute("","",XML_VAR_COLOR_NAME,"CDATA",""+XMLUtils.toHTMLNotation(_color)); + atts.addAttribute("","",XML_VAR_ANGLE_NAME,"CDATA",""+_angle); + hd.startElement("","",XML_ELEMENT_NAME,atts); + atts.clear(); + hd.startElement("","",XML_VAR_TEXT_NAME,atts); + XMLUtils.exportCDATAString(hd, _text); + hd.endElement("","",XML_VAR_TEXT_NAME); + switch (_typeAnchor) + { + case POSITION: + ((VARNAPoint)_anchor).toXML(hd,"pos"); + break; + case BASE: + XMLUtils.toXML(hd, (ModeleBase)_anchor); + break; + case HELIX: + XMLUtils.toXML(hd, (ArrayList)_anchor); + break; + case LOOP: + XMLUtils.toXML(hd, (ArrayList)_anchor); + break; + } + XMLUtils.toXML(hd, _font); + hd.endElement("","",XML_ELEMENT_NAME); + } + + /** + * creates an annoted text on a VARNAPanel with the specified text + * + * @param texte Textual content of the annotation + */ + public TextAnnotation(String texte) { + _text = texte; + _color = DEFAULTCOLOR; + _font = DEFAULTFONT; + _angle = 0; + } + + /** + * /** creates an annoted text on a VARNAPanel with the specified text and + * is static position + * + * @param texte + * @param x + * @param y + */ + public TextAnnotation(String texte, double x, double y) { + this(texte); + _anchor = new VARNAPoint(x, y); + _typeAnchor = AnchorType.POSITION; + } + + /** + * creates an annoted text on a VARNAPanel with the specified text fixed to + * a base + * + * @param texte + * @param mb + */ + public TextAnnotation(String texte, ModeleBase mb) { + this(texte); + _anchor = mb; + _typeAnchor = AnchorType.BASE; + } + + /** + * creates an annoted text on a VARNAPanel with the specified text fixed to + * a helix (if type is HELIX) or to a loop (if type is LOOP) + * + * @param texte + * @param listeBase + * @param type + * @throws Exception + */ + public TextAnnotation(String texte, ArrayList listeBase, + AnchorType type) throws Exception { + this(texte); + _anchor = listeBase; + + if (type == AnchorType.HELIX) + _typeAnchor = AnchorType.HELIX; + else if (type == AnchorType.LOOP) + _typeAnchor = AnchorType.LOOP; + else + throw new Exception("Bad argument"); + } + + /** + * creates an annoted text from another one + * + * @param textAnnotation + */ + public TextAnnotation(TextAnnotation textAnnotation) { + _anchor = textAnnotation.getAncrage(); + _font = textAnnotation.getFont(); + _text = textAnnotation.getTexte(); + _typeAnchor = textAnnotation.getType(); + } + + /** + * + * @return the text + */ + public String getTexte() { + return _text; + } + + public void setText(String _texte) { + this._text = _texte; + } + + /** + * + * @return the font + */ + public Font getFont() { + return _font; + } + + public void setFont(Font _font) { + this._font = _font; + } + + public Object getAncrage() { + return _anchor; + } + + public void setAncrage(ModeleBase mb) { + _anchor = mb; + _typeAnchor = AnchorType.BASE; + } + + public void setAncrage(double x, double y) { + _anchor = new VARNAPoint(x, y); + _typeAnchor = AnchorType.POSITION; + } + + public void setAncrage(ArrayList list, AnchorType type) + throws Exception { + _anchor = list; + if (type == AnchorType.HELIX) + _typeAnchor = AnchorType.HELIX; + else if (type == AnchorType.LOOP) + _typeAnchor = AnchorType.LOOP; + else + throw new Exception("Bad argument"); + } + + public AnchorType getType() { + return _typeAnchor; + } + + public void setType(AnchorType t) { + _typeAnchor = t; + } + + + public Color getColor() { + return _color; + } + + public void setColor(Color color) { + this._color = color; + } + + + public String getHelixDescription() + { + ArrayList listeBase = ((ArrayList)_anchor); + int minA = Integer.MAX_VALUE,maxA = Integer.MIN_VALUE; + int minB = Integer.MAX_VALUE,maxB = Integer.MIN_VALUE; + for(ModeleBase mb : listeBase) + { + int i = mb.getBaseNumber(); + if (mb.getElementStructure()>i) + { + minA = Math.min(minA, i); + maxA = Math.max(maxA, i); + } + else + { + minB = Math.min(minB, i); + maxB = Math.max(maxB, i); + } + } + return "["+minA+","+maxA+"] ["+minB+","+maxB+"]"; + } + + public String getLoopDescription() + { + ArrayList listeBase = ((ArrayList)_anchor); + int min = Integer.MAX_VALUE,max = Integer.MIN_VALUE; + for(ModeleBase mb : listeBase) + { + int i = mb.getBaseNumber(); + min = Math.min(min, i); + max = Math.max(max, i); + } + return "["+min+","+max+"]"; + } + + public String toString() { + String tmp = "["+_text+"] "; + switch (_typeAnchor) { + case POSITION: + NumberFormat formatter = new DecimalFormat(".00"); + return tmp+" at ("+formatter.format(getCenterPosition().x)+","+formatter.format(getCenterPosition().y)+")"; + case BASE: + return tmp+" on base "+((ModeleBase) _anchor).getBaseNumber(); + case HELIX: + return tmp+" on helix "+getHelixDescription(); + case LOOP: + return tmp+" on loop "+getLoopDescription(); + default: + return tmp; + } + } + + /** + * + * @return the text position center + */ + public Point2D.Double getCenterPosition() { + switch (_typeAnchor) { + case POSITION: + return ((VARNAPoint) _anchor).toPoint2D(); + case BASE: + return ((ModeleBase) _anchor).getCoords(); + case HELIX: + return calculLoopHelix(); + case LOOP: + return calculLoop(); + default: + return new Point2D.Double(0., 0.); + } + } + + private Point2D.Double calculLoop() { + ArrayList liste = extractedArrayListModeleBaseFromAncrage(); + double totalX = 0., totalY = 0.; + for (ModeleBase base : liste) { + totalX += base.getCoords().x; + totalY += base.getCoords().y; + } + return new Point2D.Double(totalX / liste.size(), totalY / liste.size()); + } + + private Point2D.Double calculLoopHelix() { + ArrayList liste = extractedArrayListModeleBaseFromAncrage(); + Collections.sort(liste); + double totalX = 0., totalY = 0.; + double num=0.0; + for (int i=0;i0 && (i extractedArrayListModeleBaseFromAncrage() { + return (ArrayList) _anchor; + } + + /** + * clone a TextAnnotation + */ + public TextAnnotation clone() { + TextAnnotation textAnnot = null; + try { + switch (_typeAnchor) { + case BASE: + textAnnot = new TextAnnotation(_text, (ModeleBase) _anchor); + break; + case POSITION: + textAnnot = new TextAnnotation(_text, + ((VARNAPoint) _anchor).x, + ((VARNAPoint) _anchor).y); + break; + case LOOP: + textAnnot = new TextAnnotation(_text, + extractedArrayListModeleBaseFromAncrage(), AnchorType.LOOP); + break; + case HELIX: + textAnnot = new TextAnnotation(_text, + extractedArrayListModeleBaseFromAncrage(), AnchorType.HELIX); + break; + default: + break; + } + } catch (Exception e) { + e.printStackTrace(); + } + textAnnot.setFont(_font); + textAnnot.setColor(_color); + return textAnnot; + + } + + /** + * copy a textAnnotation + * + * @param textAnnotation + */ + public void copy(TextAnnotation textAnnotation) { + _anchor = textAnnotation.getAncrage(); + _font = textAnnotation.getFont(); + _text = textAnnotation.getTexte(); + _typeAnchor = textAnnotation.getType(); + _color = textAnnotation.getColor(); + _angle = textAnnotation.getAngleInDegres(); + } + + + /** + * + * @return the angle in degrees + */ + public double getAngleInDegres() { + // if (_typeAncrage == TextAnnotation.HELIX) + // _angle = calculAngleDegres(); + return _angle; + } + + /** + * + * @return the angle in radians + */ + public double getAngleInRadians() { + return (getAngleInDegres() * Math.PI) / 180.; + } + + public void setAngleInDegres(double _angle) { + this._angle = _angle; + } + + public void setAngleInRadians(double _angle) { + this._angle = _angle * 180 / Math.PI; + } + + + public static TextAnnotation parse(String thisAnn, VARNAPanel vp) + { + String[] data = thisAnn.split(":"); + + String text = ""; + int anchor = -1; + int x = -1; + int y = -1; + TextAnnotation.AnchorType type = TextAnnotation.AnchorType.LOOP; + Font font = TextAnnotation.DEFAULTFONT; + Color color = TextAnnotation.DEFAULTCOLOR; + TextAnnotation ann = null; + try { + if (data.length == 2) { + text = data[0]; + String[] data2 = data[1].split(","); + for (int j = 0; j < data2.length; j++) { + String opt = data2[j]; + String[] data3 = opt.split("="); + if (data3.length == 2) { + String name = data3[0].toLowerCase(); + String value = data3[1]; + if (name.equals("type")) { + if (value.toUpperCase().equals("H")) { + type = TextAnnotation.AnchorType.HELIX; + } else if (value.toUpperCase().equals("L")) { + type = TextAnnotation.AnchorType.LOOP; + } else if (value.toUpperCase().equals("P")) { + type = TextAnnotation.AnchorType.POSITION; + } else if (value.toUpperCase().equals("B")) { + type = TextAnnotation.AnchorType.BASE; + } + } else if (name.equals("x")) { + x = Integer.parseInt(value); + } else if (name.equals("y")) { + y = Integer.parseInt(value); + } else if (name.equals("anchor")) { + anchor = Integer.parseInt(value); + } else if (name.equals("size")) { + font = font.deriveFont((float) Integer + .parseInt(value)); + } else if (name.equals("color")) { + color = VARNAConfigLoader.getSafeColor(value, color); + } + } + } + switch (type) { + case POSITION: + if ((x != -1) && (y != -1)) { + Point2D.Double p = vp + .panelToLogicPoint(new Point2D.Double(x, y)); + ann = new TextAnnotation(text, p.x, p.y); + } + break; + case BASE: + if (anchor != -1) { + int index = vp.getRNA().getIndexFromBaseNumber( + anchor); + ModeleBase mb = vp.getRNA().get_listeBases() + .get(index); + ann = new TextAnnotation(text, mb); + } + break; + case HELIX: + if (anchor != -1) { + ArrayList mbl = new ArrayList(); + int index = vp.getRNA().getIndexFromBaseNumber( + anchor); + ArrayList il = vp.getRNA() + .findHelix(index); + for (int k : il) { + mbl.add(vp.getRNA().get_listeBases().get(k)); + } + ann = new TextAnnotation(text, mbl, type); + } + break; + case LOOP: + if (anchor != -1) { + ArrayList mbl = new ArrayList(); + int index = vp.getRNA().getIndexFromBaseNumber( + anchor); + ArrayList il = vp.getRNA().findLoop(index); + for (int k : il) { + mbl.add(vp.getRNA().get_listeBases().get(k)); + } + ann = new TextAnnotation(text, mbl, type); + } + break; + } + if (ann != null) { + ann.setColor(color); + ann.setFont(font); + } + } + } catch (Exception e) { + System.err.println("Apply Annotations: " + e.toString()); + } + return ann; + } +}