001package jmri.jmrit.display.controlPanelEditor.shape.configurexml; 002 003import java.awt.Color; 004import jmri.NamedBeanHandle; 005import jmri.Sensor; 006import jmri.configurexml.AbstractXmlAdapter; 007import jmri.jmrit.display.ToolTip; 008import jmri.jmrit.display.controlPanelEditor.shape.PositionableShape; 009import org.jdom2.Attribute; 010import org.jdom2.DataConversionException; 011import org.jdom2.Element; 012import org.slf4j.Logger; 013import org.slf4j.LoggerFactory; 014 015/** 016 * Handle configuration for display.PositionableShape objects 017 * 018 * @author Pete Cressman Copyright (c) 2012 019 */ 020public abstract class PositionableShapeXml extends AbstractXmlAdapter { 021 022 public PositionableShapeXml() { 023 } 024 025 /** 026 * Default implementation for storing the contents of a PositionableShape 027 * 028 * @param o Object to store, of type PositionableShape 029 * @return Element containing the complete info 030 */ 031 @Override 032 public Element store(Object o) { 033 PositionableShape p = (PositionableShape) o; 034 035 if (!p.isActive()) { 036 return null; // if flagged as inactive, don't store 037 } 038 Element element = new Element("PositionableShape"); 039 storeCommonAttributes(p, element); 040 041 element.setAttribute("class", "jmri.jmrit.display.controlPanelEditor.shape.configurexml.PositionableShapeXml"); 042 return element; 043 } 044 045 /** 046 * Default implementation for storing the common contents. 047 * 048 * @param p the shape to store 049 * @param element Element in which contents are stored 050 */ 051 public void storeCommonAttributes(PositionableShape p, Element element) { 052 element.setAttribute("x", "" + p.getX()); 053 element.setAttribute("y", "" + p.getY()); 054 element.setAttribute("level", String.valueOf(p.getDisplayLevel())); 055 element.setAttribute("forcecontroloff", !p.isControlling() ? "true" : "false"); 056 element.setAttribute("hidden", p.isHidden() ? "yes" : "no"); 057 element.setAttribute("positionable", p.isPositionable() ? "true" : "false"); 058 element.setAttribute("showtooltip", p.showToolTip() ? "true" : "false"); 059 element.setAttribute("editable", p.isEditable() ? "true" : "false"); 060 ToolTip tip = p.getToolTip(); 061 String txt = tip.getText(); 062 if (txt != null) { 063 Element elem = new Element("toolTip").addContent(txt); 064 element.addContent(elem); 065 } 066 if (p.getDegrees() != 0) { 067 element.setAttribute("degrees", "" + p.getDegrees()); 068 } 069 070 Element elem = storeColor("lineColor", p.getLineColor()); 071 if (elem != null) { 072 element.addContent(elem); 073 } 074 elem = storeColor("fillColor", p.getFillColor()); 075 if (elem != null) { 076 element.addContent(elem); 077 } 078 element.setAttribute("lineWidth", "" + p.getLineWidth()); 079 080 NamedBeanHandle<Sensor> handle = p.getControlSensorHandle(); 081 if (handle != null) { 082 element.setAttribute("controlSensor", handle.getName()); 083 } 084 element.setAttribute("hideOnSensor", p.isHideOnSensor() ? "true" : "false"); 085 element.setAttribute("changeLevelOnSensor", String.valueOf(p.getChangeLevel())); 086 } 087 088 public Element storeColor(String name, Color c) { 089 if (c == null) { 090 return null; 091 } 092 Element elem = new Element(name); 093 elem.setAttribute("red", "" + c.getRed()); 094 elem.setAttribute("green", "" + c.getGreen()); 095 elem.setAttribute("blue", "" + c.getBlue()); 096 elem.setAttribute("alpha", "" + c.getAlpha()); 097 return elem; 098 } 099 100 @Override 101 public boolean load(Element shared, Element perNode) { 102 log.error("Invalid method called"); 103 return false; 104 } 105 106 public void loadCommonAttributes(PositionableShape ps, int defaultLevel, Element element) { 107 int x = getInt(element, "x"); 108 int y = getInt(element, "y"); 109 ps.setLocation(x, y); 110 111 ps.setDisplayLevel(getInt(element, "level")); 112 113 try { 114 boolean value = element.getAttribute("hidden").getBooleanValue(); 115 ps.setHidden(value); 116 ps.setVisible(!value); 117 } catch (DataConversionException e1) { 118 log.warn("unable to convert positionable shape hidden attribute"); 119 } 120 121 try { 122 ps.setPositionable(element.getAttribute("positionable").getBooleanValue()); 123 } catch (DataConversionException e1) { 124 log.warn("unable to convert positionable shape positionable attribute"); 125 } 126 127 try { 128 ps.setShowToolTip(element.getAttribute("showtooltip").getBooleanValue()); 129 } catch (DataConversionException e1) { 130 log.warn("unable to convert positionable shape showtooltip attribute"); 131 } 132 133 try { 134 ps.setEditable(element.getAttribute("editable").getBooleanValue()); 135 } catch (DataConversionException e1) { 136 log.warn("unable to convert positionable shape editable attribute"); 137 } 138 139 Element elem = element.getChild("toolTip"); 140 if (elem != null) { 141 ToolTip tip = ps.getToolTip(); 142 if (tip != null) { 143 tip.setText(elem.getText()); 144 } 145 } 146 ps.setLineWidth(getInt(element, "lineWidth")); 147 148 int alpha = -1; 149 Attribute a = element.getAttribute("alpha"); 150 try { 151 if (a != null) { 152 alpha = a.getIntValue(); 153 } 154 } catch (DataConversionException ex) { 155 log.warn("invalid 'alpha' value (non integer)"); 156 } 157 ps.setLineColor(getColor(element, "lineColor", alpha)); 158 ps.setFillColor(getColor(element, "fillColor", alpha)); 159 160 ps.rotate(getInt(element, "degrees")); 161 162 boolean hide = false; 163 try { 164 hide = element.getAttribute("hideOnSensor").getBooleanValue(); 165 } catch (DataConversionException e1) { 166 log.warn("unable to convert positionable shape hideOnSensor attribute"); 167 } 168 ps.setHide(hide); 169 170 int changeLevel = 2; 171 try { 172 changeLevel = getInt(element, "changeLevelOnSensor"); 173 } catch (Exception e) { 174 log.error("failed to get changeLevel attribute ex= {}", e.getMessage()); 175 } 176 ps.setChangeLevel(changeLevel); 177 178 try { 179 a = element.getAttribute("controlSensor"); 180 if (a != null) { 181 ps.setControlSensor(a.getValue()); 182 ps.setListener(); 183 } 184 } catch (NullPointerException e) { 185 log.error("incorrect information for controlSensor of PositionableShape"); 186 } 187 ps.updateSize(); 188 } 189 190 /* pre version 3.9.4 alpha was only used for fill color. 191 * alpha == -1 indicates 3.9.4 or later 192 */ 193 public Color getColor(Element element, String name, int alpha) { 194 Element elem = element.getChild(name); 195 if (elem == null) { 196 return null; 197 } 198 try { 199 int red = elem.getAttribute("red").getIntValue(); 200 int blue = elem.getAttribute("blue").getIntValue(); 201 int green = elem.getAttribute("green").getIntValue(); 202 if (alpha == -1) { 203 alpha = elem.getAttribute("alpha").getIntValue(); 204 return new Color(red, green, blue, alpha); 205 } else if (name.equals("lineColor")) { 206 return new Color(red, green, blue); 207 } else { 208 return new Color(red, green, blue, alpha); 209 } 210 } catch (DataConversionException e) { 211 log.warn("failed to convert color attribute for {}", name, e); 212 } 213 return null; 214 } 215 216 public int getInt(Element element, String name) { 217 try { 218 Attribute attr = element.getAttribute(name); 219 if (attr != null) { 220 return attr.getIntValue(); 221 } 222 } catch (DataConversionException e) { 223 log.error("failed to convert integer attribute for {}", name, e); 224 } 225 return 0; 226 } 227 228 public float getFloat(Element element, String name) { 229 try { 230 Attribute attr = element.getAttribute(name); 231 if (attr != null) { 232 return attr.getFloatValue(); 233 } 234 } catch (DataConversionException e) { 235 log.error("failed to convert integer attribute for {}", name, e); 236 } 237 return 0; 238 } 239 240 private final static Logger log = LoggerFactory.getLogger(PositionableShapeXml.class); 241}