001package jmri.jmrit.display.configurexml;
002
003import java.util.List;
004
005import jmri.Memory;
006import jmri.configurexml.JmriConfigureXmlException;
007import jmri.jmrit.catalog.NamedIcon;
008import jmri.jmrit.display.*;
009import jmri.jmrit.display.layoutEditor.LayoutEditor;
010
011import org.jdom2.Attribute;
012import org.jdom2.Element;
013import org.slf4j.Logger;
014import org.slf4j.LoggerFactory;
015
016/**
017 * Handle configuration for display.MemoryIcon objects.
018 *
019 * @author Bob Jacobsen Copyright: Copyright (c) 2004
020 */
021public class MemoryIconXml extends PositionableLabelXml {
022
023    public MemoryIconXml() {
024    }
025
026    /**
027     * Default implementation for storing the contents of a MemoryIcon
028     *
029     * @param o Object to store, of type MemoryIcon
030     * @return Element containing the complete info
031     */
032    @Override
033    public Element store(Object o) {
034
035        MemoryIcon p = (MemoryIcon) o;
036
037        Element element = new Element("memoryicon");
038
039        // include attributes
040        element.setAttribute("memory", p.getNamedMemory().getName());
041        storeCommonAttributes(p, element);
042        storeTextInfo(p, element);
043
044        //If the fixed width option is not set and the justification is not left
045        //Then we need to replace the x, y values with the original ones.
046        if (p.getPopupUtility().getFixedWidth() == 0 && p.getPopupUtility().getJustification() != 0) {
047            element.setAttribute("x", "" + p.getOriginalX());
048            element.setAttribute("y", "" + p.getOriginalY());
049        }
050        element.setAttribute("selectable", (p.isSelectable() ? "yes" : "no"));
051        if (p.updateBlockValueOnChange()) {
052            element.setAttribute("updateBlockValue", (p.updateBlockValueOnChange() ? "yes" : "no"));
053        }
054
055        element.setAttribute("class", "jmri.jmrit.display.configurexml.MemoryIconXml");
056        if (p.getDefaultIcon() != null) {
057            element.setAttribute("defaulticon", p.getDefaultIcon().getURL());
058        }
059
060        // include contents
061        java.util.HashMap<String, NamedIcon> map = p.getMap();
062        if (map != null) {
063
064            for (java.util.Map.Entry<String, NamedIcon> mi : map.entrySet()) {
065                String key = mi.getKey();
066                String value = mi.getValue().getName();
067
068                Element e2 = new Element("memorystate");
069                e2.setAttribute("value", key);
070                e2.setAttribute("icon", value);
071                element.addContent(e2);
072            }
073        }
074
075        storeLogixNG_Data(p, element);
076
077        return element;
078    }
079
080    /**
081     * Load, starting with the memoryicon element, then all the value-icon pairs
082     *
083     * @param element Top level Element to unpack.
084     * @param o       an Editor as an Object
085     * @throws JmriConfigureXmlException when a error prevents creating the objects as as
086     *                   required by the input XML
087     */
088    @Override
089    public void load(Element element, Object o) throws JmriConfigureXmlException {
090
091        Editor ed = null;
092        MemoryIcon l;
093        if (o instanceof LayoutEditor) {
094            ed = (LayoutEditor) o;
095            l = new jmri.jmrit.display.layoutEditor.MemoryIcon("   ", (LayoutEditor) ed);
096        } else if (o instanceof jmri.jmrit.display.Editor) {
097            ed = (Editor) o;
098            l = new MemoryIcon("", ed);
099        } else {
100            log.error("Unrecognizable class - {}", o.getClass().getName());
101            return;
102        }
103
104        String name;
105        Attribute attr = element.getAttribute("memory");
106        if (attr == null) {
107            log.error("incorrect information for a memory location; must use memory name");
108            ed.loadFailed();
109            return;
110        } else {
111            name = attr.getValue();
112        }
113
114        loadTextInfo(l, element);
115
116        Memory m = jmri.InstanceManager.memoryManagerInstance().getMemory(name);
117        if (m != null) {
118            l.setMemory(name);
119        } else {
120            log.error("Memory named '{}' not found.", attr.getValue());
121            ed.loadFailed();
122        }
123
124        Attribute a = element.getAttribute("selectable");
125        if (a != null && a.getValue().equals("yes")) {
126            l.setSelectable(true);
127        } else {
128            l.setSelectable(false);
129        }
130
131        a = element.getAttribute("defaulticon");
132        if (a != null) {
133            l.setDefaultIcon(NamedIcon.getIconByName(a.getValue()));
134        }
135        
136        a = element.getAttribute("updateBlockValue");
137        if (a != null && a.getValue().equals("yes")) {
138            l.updateBlockValueOnChange(true);
139        }
140
141        // get the icon pairs
142        List<Element> items = element.getChildren("memorystate");
143        for (Element item : items) {
144            // get the class, hence the adapter object to do loading
145            String iconName = item.getAttribute("icon").getValue();
146            NamedIcon icon = NamedIcon.getIconByName(iconName);
147            if (icon == null) {
148                icon = ed.loadFailed("Memory " + name, iconName);
149                if (icon == null) {
150                    log.info("Memory \"{}\" icon removed for url= {}", name, iconName);
151                }
152            }
153            if (icon != null) {
154                String keyValue = item.getAttribute("value").getValue();
155                l.addKeyAndIcon(icon, keyValue);
156            }
157        }
158        try {
159            ed.putItem(l);
160        } catch (Positionable.DuplicateIdException e) {
161            throw new JmriConfigureXmlException("Positionable id is not unique", e);
162        }
163
164        loadLogixNG_Data(l, element);
165
166        // load individual item's option settings after editor has set its global settings
167        loadCommonAttributes(l, Editor.MEMORIES, element);
168        int x = 0;
169        int y = 0;
170        try {
171            x = element.getAttribute("x").getIntValue();
172            y = element.getAttribute("y").getIntValue();
173        } catch (org.jdom2.DataConversionException e) {
174            log.error("failed to convert positional attribute");
175        }
176        l.setOriginalLocation(x, y);
177        l.displayState();
178    }
179
180    private final static Logger log = LoggerFactory.getLogger(MemoryIconXml.class);
181}