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}