001package jmri.jmrit.display.configurexml;
002
003import java.util.List;
004
005import jmri.Block;
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.BlockContentsIcon objects.
018 *
019 * @author Bob Jacobsen Copyright: Copyright (c) 2004
020 */
021public class BlockContentsIconXml extends PositionableLabelXml {
022
023    public BlockContentsIconXml() {
024    }
025
026    /**
027     * Default implementation for storing the contents of a BlockContentsIcon
028     *
029     * @param o Object to store, of type BlockContentsIcon
030     * @return Element containing the complete info
031     */
032    @Override
033    public Element store(Object o) {
034
035        BlockContentsIcon p = (BlockContentsIcon) o;
036
037        Element element = new Element("BlockContentsIcon");
038
039        // include attributes
040        element.setAttribute("blockcontents", p.getNamedBlock().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
052        element.setAttribute("class", "jmri.jmrit.display.configurexml.BlockContentsIconXml");
053        if (p.getDefaultIcon() != null) {
054            element.setAttribute("defaulticon", p.getDefaultIcon().getURL());
055        }
056
057        // include contents
058        java.util.HashMap<String, NamedIcon> map = p.getMap();
059        if (map != null) {
060
061            for (java.util.Map.Entry<String, NamedIcon> mi : map.entrySet()) {
062                String key = mi.getKey();
063                String value = mi.getValue().getName();
064
065                Element e2 = new Element("blockstate");
066                e2.setAttribute("value", key);
067                e2.setAttribute("icon", value);
068                element.addContent(e2);
069            }
070        }
071
072        storeLogixNG_Data(p, element);
073
074        return element;
075    }
076
077    /**
078     * Load, starting with the BlockContentsIcon element, then all the
079     * value-icon pairs
080     *
081     * @param element Top level Element to unpack.
082     * @param o       an Editor as an Object
083     * @throws JmriConfigureXmlException when a error prevents creating the objects as as
084     *                   required by the input XML
085     */
086    @Override
087    public void load(Element element, Object o) throws JmriConfigureXmlException {
088
089        Editor ed = null;
090        BlockContentsIcon l;
091        if (o instanceof LayoutEditor) {
092            ed = (LayoutEditor) o;
093            l = new jmri.jmrit.display.layoutEditor.BlockContentsIcon("   ", (LayoutEditor) ed);
094        } else if (o instanceof jmri.jmrit.display.Editor) {
095            ed = (Editor) o;
096            l = new BlockContentsIcon("", ed);
097        } else {
098            log.error("Unrecognizable class - {}", o.getClass().getName());
099            return;
100        }
101
102        String name;
103        Attribute attr = element.getAttribute("blockcontents");
104        if (attr == null) {
105            log.error("incorrect information for a block contents; must use block name");
106            ed.loadFailed();
107            return;
108        } else {
109            name = attr.getValue();
110        }
111
112        loadTextInfo(l, element);
113
114        Block m = jmri.InstanceManager.getDefault(jmri.BlockManager.class).getBlock(name);
115        if (m != null) {
116            l.setBlock(name);
117        } else {
118            log.error("Block named '{}' not found.", attr.getValue());
119            ed.loadFailed();
120        }
121
122        Attribute a = element.getAttribute("selectable");
123        if (a != null && a.getValue().equals("yes")) {
124            l.setSelectable(true);
125        } else {
126            l.setSelectable(false);
127        }
128
129        // get the icon pairs
130        List<Element> items = element.getChildren("blockstate");
131        for (Element item : items) {
132            // get the class, hence the adapter object to do loading
133            String iconName = item.getAttribute("icon").getValue();
134            NamedIcon icon = NamedIcon.getIconByName(iconName);
135            if (icon == null) {
136                icon = ed.loadFailed("Memory " + name, iconName);
137                if (icon == null) {
138                    log.info("Memory \"{}\" icon removed for url= {}", name, iconName);
139                }
140            }
141            if (icon != null) {
142                String keyValue = item.getAttribute("value").getValue();
143                l.addKeyAndIcon(icon, keyValue);
144            }
145        }
146        try {
147            ed.putItem(l);
148        } catch (Positionable.DuplicateIdException e) {
149            throw new JmriConfigureXmlException("Positionable id is not unique", e);
150        }
151        // load individual item's option settings after editor has set its global settings
152        loadCommonAttributes(l, Editor.MEMORIES, element);
153        int x = 0;
154        int y = 0;
155        try {
156            x = element.getAttribute("x").getIntValue();
157            y = element.getAttribute("y").getIntValue();
158        } catch (org.jdom2.DataConversionException e) {
159            log.error("failed to convert positional attribute");
160        }
161        l.setOriginalLocation(x, y);
162        l.displayState();
163
164        loadLogixNG_Data(l, element);
165    }
166
167    private final static Logger log = LoggerFactory.getLogger(BlockContentsIconXml.class);
168}