/* ****************************************************************************** * * Copyright 2008-2010 Hans Dijkema * * JRichTextEditor is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * JRichTextEditor 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with JRichTextEditor. If not, see <http://www.gnu.org/licenses/>. * * ******************************************************************************/ package nl.dykema.jxmlnote.styles; import java.awt.Color; import java.awt.Font; import java.util.Vector; import javax.swing.text.MutableAttributeSet; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; import javax.swing.text.TabSet; import javax.swing.text.TabStop; import nl.dykema.jxmlnote.utils.DPIAdjuster; public class XMLNoteParStyle { static private Integer styleNumber=0; private static StyleContext _context=null; private XMLNoteStyles _styleContainer=null; private Style _style=null; private String _name="Paragraph"; private String _id="par"; private String _font="arial"; private int _point_size=12; private int _skip_bottom_point_size=10; private int _skip_top_point_size=0; private boolean _italics=false; private boolean _bold=false; private boolean _underline=false; private Color _color=Color.black; private Color _bg=Color.white; private String _extraCss=""; private double _zoomFactor=1.0; private String _align=ALIGN_LEFT; private boolean _default=false; private TabSet _tabs; private boolean _blockStyleChangeInform=false; private boolean _inTransaction=false; private boolean _keepWithNext=false; private int _leftIndent=0; public static final String ALIGN_LEFT="left"; public static final String ALIGN_RIGHT="right"; public static final String ALIGN_CENTER="center"; public static final String ALIGN_JUSTIFY="justify"; public static final String ALIGN_JUSTIFIED=ALIGN_JUSTIFY; public void begin() { _inTransaction=true; } public void commit() { _inTransaction=false; this.informStyleChange(); } public static StyleContext getStyleContext() { return _context; } private static synchronized String getTmpStyleName() { styleNumber+=1; return String.format("Style%04d", styleNumber); } private boolean blockStyleChangeInform(boolean n) { boolean b=_blockStyleChangeInform; _blockStyleChangeInform=n; return b; } private void informStyleChange() { if (!_blockStyleChangeInform) { if (_styleContainer!=null) { if (!_inTransaction) { _styleContainer.styleChanged(this); } } } } public void setContainer(XMLNoteStyles s) { _styleContainer=s; } public XMLNoteStyles getContainer() { return _styleContainer; } private String contextStyleName(String device) { return _styleContainer.stylesContextName()+":"+device+":"+id(); } private void fixFontSizeAndTabStops(String device) { String stname=contextStyleName(device); Style dev=_context.getStyle(stname); if (dev==null) { _context.addStyle(stname, _style); dev=_context.getStyle(stname); } TabSet stops=StyleConstants.getTabSet(_style); Integer sz=StyleConstants.getFontSize(_style); //FIXME: DPIAdjuster gebruiken voor Screens. Voor printing niet. if (sz!=null) { double pts=(double) sz; if (device.equals(DPIAdjuster.DEVICE_SCREEN)) { pts=DPIAdjuster.adjustPointSize(pts); StyleConstants.setFontSize(dev,(int) Math.round(pts)); Vector<TabStop> newStops=new Vector<TabStop>(); for(int i=0,n=stops.getTabCount();i<n;i++) { TabStop tb=stops.getTab(i); double tab=DPIAdjuster.adjustPointSize(tb.getPosition()); int align=tb.getAlignment(); int leader=tb.getLeader(); newStops.add(new TabStop((int) Math.round(tab),align,leader)); } TabStop[] sts=new TabStop[newStops.size()]; newStops.toArray(sts); TabSet tabset=new TabSet(sts); StyleConstants.setTabSet(dev, tabset); } } } public MutableAttributeSet getStyle(String device) { SimpleAttributeSet set=new SimpleAttributeSet(); set.addAttributes(getRealStyle(device)); XMLNoteStyleConstants.setId(set, id()); return set; } public Style getRealStyle(String device) { String stname=contextStyleName(device); Style dev=_context.getStyle(stname); if (dev==null) { fixFontSizeAndTabStops(device); return getRealStyle(device); } else { return dev; } } public String name() { return _name; } public void name(String n) { _name=n; ((StyleContext.NamedStyle)_style).setName(n); } public String description() { return _name; } public void description(String d) { //_description=d; } public String id() { return _id; } public void id(String i) { _id=i; _style.addAttribute(XMLNoteStyleConstants.IdAttribute, _id); } public String font() { return _font; } public void font(String f) { _font=f; StyleConstants.setFontFamily(_style, f); informStyleChange(); } public boolean keepWithNext() { return _keepWithNext; } public void keepWithNext(boolean b) { _keepWithNext=b; } public Font getFont() { int style=Font.PLAIN; if (bold()) { style=Font.BOLD; } if (italics()) { if (style==Font.BOLD) { style+=Font.ITALIC; } else { style=Font.ITALIC; } } Font f=new Font(font(),style,pointSize()); return DPIAdjuster.adjustFont(f); } public int pointSize() { return (int) (_point_size*_zoomFactor); } public int leftIndent() { return _leftIndent; } public void leftIndent(int l) { _leftIndent=l; StyleConstants.setLeftIndent(_style, l); informStyleChange(); } public void pointSize(int pt) { _point_size=pt; StyleConstants.setFontSize(_style, pt); fixFontSizeAndTabStops(DPIAdjuster.DEVICE_SCREEN); fixFontSizeAndTabStops(DPIAdjuster.DEVICE_PRINT); informStyleChange(); } public int bottomSkip() { return (int) (_skip_bottom_point_size*_zoomFactor); } public void bottomSkip(int pt) { _skip_bottom_point_size=pt; StyleConstants.setSpaceBelow(_style, pt); informStyleChange(); } public int topSkip() { return (int) (_skip_top_point_size*_zoomFactor); } public void topSkip(int pt) { _skip_top_point_size=pt; StyleConstants.setSpaceAbove(_style,pt); informStyleChange(); } public boolean bold() { return _bold; } public void bold(boolean b) { _bold=b; StyleConstants.setBold(_style, b); informStyleChange(); } public boolean italics() { return _italics; } public void italics(boolean it) { _italics=it; StyleConstants.setItalic(_style, it); informStyleChange(); } public boolean underline() { return _underline; } public void tabs(TabSet tabs) { _tabs=tabs; StyleConstants.setTabSet(_style, tabs); informStyleChange(); } public TabSet tabs() { return _tabs; } public void underline(boolean u) { _underline=u; StyleConstants.setUnderline(_style, u); informStyleChange(); } public boolean isDefault() { return _default; } public void isDefault(boolean b) { _default=b; } public String color2String(Color c) { return String.format("#%02x%02x%02x",c.getRed()%256,c.getGreen()%256,c.getBlue()%256); } public Color string2Color(String c) { Integer col=Integer.parseInt(c.substring(1),16); return new Color(col); } public Color color() { return _color; } public void color(Color color) { _color=color; StyleConstants.setForeground(_style, color); informStyleChange(); } public Color bgColor() { return _bg; } public void bgColor(Color color) { _bg=color; StyleConstants.setBackground(_style, color); informStyleChange(); } public String getExtraCSS() { return _extraCss; } public void setExtraCSS(String extracss) { _extraCss=extracss; } public void zoom(double factor) { _zoomFactor=factor; informStyleChange(); } public void align(String a) { a=a.toLowerCase(); _align=a; if (a.equals(ALIGN_LEFT)) { StyleConstants.setAlignment(_style, StyleConstants.ALIGN_LEFT); } else if (a.equals(ALIGN_RIGHT)) { StyleConstants.setAlignment(_style, StyleConstants.ALIGN_RIGHT); } else if (a.equals(ALIGN_CENTER)) { StyleConstants.setAlignment(_style, StyleConstants.ALIGN_CENTER); } else if (a.equals(ALIGN_JUSTIFY)) { StyleConstants.setAlignment(_style, StyleConstants.ALIGN_JUSTIFIED); } else { align("left"); return; } informStyleChange(); } public String align() { return _align; } /*public String toLabelHtml(String label) { String s=String.format("<html><font size=\"%d\" face=\"%s\" color=\"%s\" background=\"%s\">", _point_size,_font, color2String(_color), color2String(_bg) ); s=s+((_bold) ? "<b>" : ""); s=s+((_underline) ? "<u>" : ""); s=s+((_italics) ? "<i>" : ""); s=s+label; s=s+((_italics) ? "</i>" : ""); s=s+((_underline) ? "</u>" : ""); s=s+((_bold) ? "</b>" : ""); s+="</font></html>"; return s; }*/ public String toString() { int i,n; String dotcomma=""; StringBuffer stops=new StringBuffer(); for(i=0,n=_tabs.getTabCount();i<n;i++) { TabStop s=_tabs.getTab(i); String tab=String.format("%d,%d,%d", (int) s.getPosition(),s.getAlignment(),s.getLeader()); stops.append(dotcomma); stops.append(tab); dotcomma=";"; } return String.format("id=%s!nm=%s!font=%s!pt=%d!bottom=%d!top=%d!bold=%d!underl=%d!it=%d!color=%s!bgcolor=%s!align=%s!default=%d!tabs=%s!keepwithnext=%d!lindent=%d!extracss=%s", _id,_name, _font,_point_size,_skip_bottom_point_size,_skip_top_point_size, (_bold) ? 1 : 0,(_underline) ? 1 : 0,(_italics) ? 1 : 0, color2String(_color),color2String(_bg), _align, (_default) ? 1 : 0, stops.toString(), (_keepWithNext) ? 1 : 0,leftIndent(), _extraCss ); } public String getIdForString(String f) { String [] d=f.split("[!]"); int i; String name=getTmpStyleName(); for(i=0;i<d.length;i++) { String[] q=d[i].split("[=]",2); if (q[0].equals("name")) { name=q[1].trim(); } else if (q[0].equals("id")) { name=q[1].trim(); return name; } } return name; } public void fromString(String f) { boolean blocked=blockStyleChangeInform(true); String[] d=f.split("[!]"); int i; for(i=0;i<d.length;i++) { String[] q=d[i].split("[=]",2); if (q[0].equals("font")) { font(q[1].trim()); } else if (q[0].equals("pt")) { pointSize(Integer.parseInt(q[1].trim())); } else if (q[0].equals("bottom")) { bottomSkip(Integer.parseInt(q[1].trim())); } else if (q[0].equals("top")) { topSkip(Integer.parseInt(q[1].trim())); } else if (q[0].equals("id")) { id(q[1].trim()); } else if (q[0].equals("nm")) { name(q[1].trim()); } else if (q[0].equals("name")) { id(q[1].trim()); } else if (q[0].equals("descr")) { name(q[1].trim()); } else if (q[0].equals("color")) { color(string2Color(q[1].trim())); } else if (q[0].equals("bgcolor")) { bgColor(string2Color(q[1].trim())); } else if (q[0].equals("bold")) { int b=Integer.parseInt(q[1].trim());bold((b==1) ? true : false); } else if (q[0].equals("underl")) { int u=Integer.parseInt(q[1].trim());underline((u==1)? true : false); } else if (q[0].equals("it")) { int it=Integer.parseInt(q[1].trim());italics((it==1) ? true : false); } else if (q[0].equals("align")) { align(q[1].trim()); } else if (q[0].equals("default")) { int dd=Integer.parseInt(q[1].trim());_default=((dd==1) ? true : false); } else if (q[0].equals("tabs")) { String stops=q[1].trim(); Vector<TabStop> v=new Vector<TabStop>(); String[] tabs=stops.split("[;]"); int k; for(k=0;k<tabs.length;k++) { String[] stop=tabs[k].trim().split("[,]"); TabStop st=new TabStop((float) Integer.parseInt(stop[0]), Integer.parseInt(stop[1]), Integer.parseInt(stop[2])); v.add(st); } TabStop[] sts=new TabStop[v.size()]; v.toArray(sts); TabSet tabset=new TabSet(sts); tabs(tabset); } else if (q[0].equals("keepwithnext")) { int bb=Integer.parseInt(q[1].trim());_keepWithNext=((bb==1) ? true : false); } else if (q[0].equals("lindent")) { _leftIndent=Integer.parseInt(q[1].trim()); } else if (q[0].equals("extracss")) { setExtraCSS(q[1].trim()); } } blockStyleChangeInform(blocked); informStyleChange(); } public String asCssStyle() { return String.format("font-family: \"%s\"; font-size: %dpt; margin-bottom: %dpt; margin-top: %dpt; "+ "font-weigth: %s; font-style: %s; text-decoration: %s; text-align: %s;" + "color: %s; background-color: %s; %s", font(),pointSize(),bottomSkip(),topSkip(), (bold()) ? "bold" : "normal", (italics()) ? "italic" : "normal", (underline()) ? "underline" : "none", _align, color2String(color()), color2String(bgColor()), _extraCss ); } public String asCSS(XMLNoteStyleIdConverter cvt) { return String.format("%s { %s }", cvt.convert(id()),asCssStyle()); } /** * Returns a copy of the current paragraph style, without associating it with a XMLNoteStyles container. * @return */ public XMLNoteParStyle copy() { return new XMLNoteParStyle(null,toString()); } private void init(String description,String name,String fnt,int pt,int bottomPt,int topPt, boolean bld,boolean italic,boolean underl, String algn,boolean isDef,TabSet ts,boolean keepwn,int lindent, Color fg,Color bg) { boolean blocked=blockStyleChangeInform(true); description(description); name(name); font(fnt); pointSize(pt); bottomSkip(bottomPt); topSkip(topPt); bold(bld); italics(italic); underline(underl); align(algn); isDefault(isDef); tabs(ts); keepWithNext(keepwn); color(fg); bgColor(bg); leftIndent(lindent); blockStyleChangeInform(blocked); } private void defInit(XMLNoteStyles container,String name) { if (_context==null) { _context=new StyleContext(); } _styleContainer=container; String stname=contextStyleName(""); _style=_context.addStyle(stname,_context.getStyle(StyleContext.DEFAULT_STYLE)); Vector<TabStop> v=new Vector<TabStop>(); int i; for(i=0;i<7;i++) { float tab=((float) (i+1))*72.0f; v.add(new TabStop(tab,TabStop.ALIGN_LEFT,TabStop.LEAD_NONE)); } TabStop[] sts=new TabStop[i]; v.toArray(sts); tabs(new TabSet(sts)); } public XMLNoteParStyle( XMLNoteStyles container, String description,String name,String fnt,int pt,int bottomPt,int topPt, boolean bold,boolean italic,boolean underline, Color foreground,Color background, TabSet tabs,boolean keepWithNext,int leftIndent, boolean isDefaultStyle ) { defInit(container,name); init(description, name,fnt,pt, bottomPt,topPt, bold,italic,underline, "left", isDefaultStyle, tabs,keepWithNext,leftIndent, foreground,background ); } public XMLNoteParStyle( XMLNoteStyles container, String description,String name,String fnt,int pt,int bottomPt,int topPt, boolean bold,boolean italic,boolean underline, String align, Color foreground,Color background, TabSet tabs,boolean keepWithNext,int leftIndent, boolean isDefaultStyle ) { defInit(container,name); init(description, name,fnt,pt, bottomPt,topPt, bold,italic,underline, align, isDefaultStyle, tabs,keepWithNext,leftIndent, foreground,background ); } public XMLNoteParStyle( XMLNoteStyles container, String _fromString) { defInit(container,getIdForString(_fromString)); _styleContainer=container; boolean blocked=blockStyleChangeInform(true); fromString(_fromString); blockStyleChangeInform(blocked); } }