Mercurial > hg > ccmieditor
diff java/src/uk/ac/qmul/eecs/ccmi/simpletemplate/MultiLineString.java @ 0:9418ab7b7f3f
Initial import
author | Fiore Martin <fiore@eecs.qmul.ac.uk> |
---|---|
date | Fri, 16 Dec 2011 17:35:51 +0000 |
parents | |
children | d66dd5880081 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/src/uk/ac/qmul/eecs/ccmi/simpletemplate/MultiLineString.java Fri Dec 16 17:35:51 2011 +0000 @@ -0,0 +1,267 @@ +/* + CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool + + Copyright (C) 2002 Cay S. Horstmann (http://horstmann.com) + Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) + + This program 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. + + This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +package uk.ac.qmul.eecs.ccmi.simpletemplate; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import javax.swing.JLabel; + +import uk.ac.qmul.eecs.ccmi.diagrammodel.NodeProperties.Modifiers; + +/** + A string that can extend over multiple lines. +*/ +public class MultiLineString { + /** + Constructs an empty, centered, normal size multiline + string. + */ + public MultiLineString(){ + text = ""; + arrayText = null; + justification = CENTER; + size = NORMAL; + isSingleLine = true; + } + /** + Sets the value of the text property. + @param newValue the text of the multiline string + */ + public void setText(String newValue){ + setText(newValue,null); + } + + public void setText(String newValue, ModifierView[] modifierViews) { + isSingleLine = true; + text = newValue; + this.modifierViews = modifierViews; + format(); + } + + public void setText(String[] newValue, Modifiers modifiers){ + isSingleLine = false; + this.modifiers = modifiers; + arrayText = newValue; + format(); + } + + public void setBold(boolean bold){ + isBold = bold; + format(); + } + /** + Gets the value of the text property. + @return the text of the multiline string + */ + public String getText() { + if(isSingleLine) + return text; + else{ + StringBuilder builder = new StringBuilder(""); + for(int i=0; i<arrayText.length; i++){ + builder.append(arrayText[i]); + builder.append('\n'); + } + return builder.toString(); + } + } + /** + Sets the value of the justification property. + @param newValue the justification, one of LEFT, CENTER, + RIGHT + */ + public void setJustification(int newValue) { justification = newValue; format(); } + /** + Gets the value of the justification property. + @return the justification, one of LEFT, CENTER, + RIGHT + */ + public int getJustification() { return justification; } + /** + Sets the value of the size property. + @param newValue the size, one of SMALL, NORMAL, LARGE + */ + public void setSize(int newValue) { size = newValue; format(); } + /** + Gets the value of the size property. + @return the size, one of SMALL, NORMAL, LARGE + */ + public int getSize() { return size; } + + @Override + public String toString(){ + if(isSingleLine) + return text.replace('\n', '|'); + else + return getText().replace('\n', '|'); + } + + private void format(){ + StringBuffer prefix = new StringBuffer(); + StringBuffer suffix = new StringBuffer(); + StringBuffer htmlText = new StringBuffer(); + prefix.append(" "); + suffix.insert(0, " "); + if (size == LARGE){ + prefix.append("<font size=\"+1\">"); + suffix.insert(0, "</font>"); + } + if (size == SMALL){ + prefix.append("<font size=\"-1\">"); + suffix.insert(0, "</font>"); + } + + htmlText.append("<html>"); + if(isSingleLine){ + if(isBold) + prefix.append("<b>"); + htmlText.append(prefix); + + String formattedText = text; + if(modifierViews != null){ + for(ModifierView view : modifierViews){ + formattedText = formatFromView(formattedText,view); + } + } + htmlText.append(formattedText); + + if(isBold) + suffix.insert(0, "</b>"); + htmlText.append(suffix); + }else{ // multi line + boolean first = true; + for(int i=0; i<arrayText.length; i++){ + if (first) + first = false; + else + htmlText.append("<br>"); + htmlText.append(prefix); + String textLine = arrayText[i]; + Set<Integer> indexes = modifiers.getIndexes(i); + for(Integer I : indexes){ + ModifierView view = (ModifierView)modifiers.getView(modifiers.getTypes().get(I)); + textLine = formatFromView(textLine, view); + } + htmlText.append(textLine); + htmlText.append(suffix); + } + } + htmlText.append("</html>"); + + // replace any < that are not followed by {u, i, b, tt, font, br} with < + List<String> dontReplace = Arrays.asList(new String[] { "u", "i", "b", "tt", "font", "br" }); + + int ltpos = 0; + while (ltpos != -1){ + ltpos = htmlText.indexOf("<", ltpos + 1); + if (ltpos != -1 && !(ltpos + 1 < htmlText.length() && htmlText.charAt(ltpos + 1) == '/')){ + int end = ltpos + 1; + while (end < htmlText.length() && Character.isLetter(htmlText.charAt(end))) end++; + if (!dontReplace.contains(htmlText.substring(ltpos + 1, end))) + htmlText.replace(ltpos, ltpos+1, "<"); + } + } + + label.setText(htmlText.toString()); + if (justification == LEFT) label.setHorizontalAlignment(JLabel.LEFT); + else if (justification == CENTER) label.setHorizontalAlignment(JLabel.CENTER); + else if (justification == RIGHT) label.setHorizontalAlignment(JLabel.RIGHT); + } + + private String formatFromView(String text, ModifierView view){ + if(view == null) + return text; + + StringBuilder prefix = new StringBuilder(""); + StringBuilder suffix = new StringBuilder(""); + + prefix.append(view.getPrefix()); + suffix.append(view.getSuffix()); + + if(view.isBold()){ + prefix.insert(0,"<b>"); + suffix.append("</b>"); + } + + if(view.isItalic()){ + prefix.insert(0,"<i>"); + suffix.append("</i>"); + } + + if(view.isUnderline()){ + prefix.insert(0,"<u>"); + suffix.append("</u>"); + } + return prefix.append(text).append(suffix).toString(); + } + + /** + Gets the bounding rectangle for this multiline string. + @param g2 the graphics context + @return the bounding rectangle (with top left corner (0,0)) + */ + public Rectangle2D getBounds(){ + if(isSingleLine){ + if (text.length() == 0) + return new Rectangle2D.Double(); + }else { + if(arrayText.length == 0) + return new Rectangle2D.Double(); + } + Dimension dim = label.getPreferredSize(); + return new Rectangle2D.Double(0, 0, dim.getWidth(), dim.getHeight()); + } + + /** + Draws this multiline string inside a given rectangle + @param g2 the graphics context + @param r the rectangle into which to place this multiline string + */ + public void draw(Graphics2D g2, Rectangle2D r){ + label.setFont(g2.getFont()); + label.setBounds(0, 0, (int) r.getWidth(), (int) r.getHeight()); + g2.translate(r.getX(), r.getY()); + label.paint(g2); + g2.translate(-r.getX(), -r.getY()); + } + + public static final int LEFT = 0; + public static final int CENTER = 1; + public static final int RIGHT = 2; + public static final int LARGE = 3; + public static final int NORMAL = 4; + public static final int SMALL = 5; + + private String text; + private String[] arrayText; + private Modifiers modifiers; + private ModifierView[] modifierViews; + private int justification; + private int size; + private boolean isBold; + private transient JLabel label = new JLabel(); + private boolean isSingleLine; +}