001package jmri.jmrit.display.configurexml; 002 003import java.util.HashMap; 004import java.util.List; 005 006import jmri.SignalHead; 007import jmri.configurexml.JmriConfigureXmlException; 008import jmri.jmrit.catalog.NamedIcon; 009import jmri.jmrit.display.*; 010 011import org.jdom2.Attribute; 012import org.jdom2.Element; 013import org.slf4j.Logger; 014import org.slf4j.LoggerFactory; 015 016/** 017 * Handle configuration for display.SignalHeadIcon objects. 018 * 019 * @author Bob Jacobsen Copyright: Copyright (c) 2002 020 */ 021public class SignalHeadIconXml extends PositionableLabelXml { 022 023 static final HashMap<String, String> _nameMap = new HashMap<>(); 024 025 public SignalHeadIconXml() { 026 // map previous store names to property key names 027 _nameMap.put("red", "SignalHeadStateRed"); 028 _nameMap.put("yellow", "SignalHeadStateYellow"); 029 _nameMap.put("green", "SignalHeadStateGreen"); 030 _nameMap.put("lunar", "SignalHeadStateLunar"); 031 _nameMap.put("held", "SignalHeadStateHeld"); 032 _nameMap.put("dark", "SignalHeadStateDark"); 033 _nameMap.put("flashred", "SignalHeadStateFlashingRed"); 034 _nameMap.put("flashyellow", "SignalHeadStateFlashingYellow"); 035 _nameMap.put("flashgreen", "SignalHeadStateFlashingGreen"); 036 _nameMap.put("flashlunar", "SignalHeadStateFlashingLunar"); 037 } 038 039 /** 040 * Default implementation for storing the contents of a SignalHeadIcon 041 * 042 * @param o Object to store, of type SignalHeadIcon 043 * @return Element containing the complete info 044 */ 045 @Override 046 public Element store(Object o) { 047 048 SignalHeadIcon p = (SignalHeadIcon) o; 049 if (!p.isActive()) { 050 return null; // if flagged as inactive, don't store 051 } 052 Element element = new Element("signalheadicon"); 053 054 element.setAttribute("signalhead", "" + p.getNamedSignalHead().getName()); 055 storeCommonAttributes(p, element); 056 element.setAttribute("clickmode", "" + p.getClickMode()); 057 element.setAttribute("litmode", "" + p.getLitMode()); 058 059 Element elem = new Element("icons"); 060 NamedIcon icon = p.getIcon("SignalHeadStateHeld"); 061 if (icon != null) { 062 elem.addContent(storeIcon("held", icon)); 063 } 064 icon = p.getIcon("SignalHeadStateDark"); 065 if (icon != null) { 066 elem.addContent(storeIcon("dark", icon)); 067 } 068 icon = p.getIcon("SignalHeadStateRed"); 069 if (icon != null) { 070 elem.addContent(storeIcon("red", icon)); 071 } 072 icon = p.getIcon("SignalHeadStateYellow"); 073 if (icon != null) { 074 elem.addContent(storeIcon("yellow", icon)); 075 } 076 icon = p.getIcon("SignalHeadStateGreen"); 077 if (icon != null) { 078 elem.addContent(storeIcon("green", icon)); 079 } 080 icon = p.getIcon("SignalHeadStateLunar"); 081 if (icon != null) { 082 elem.addContent(storeIcon("lunar", icon)); 083 } 084 icon = p.getIcon("SignalHeadStateFlashingRed"); 085 if (icon != null) { 086 elem.addContent(storeIcon("flashred", icon)); 087 } 088 icon = p.getIcon("SignalHeadStateFlashingYellow"); 089 if (icon != null) { 090 elem.addContent(storeIcon("flashyellow", icon)); 091 } 092 icon = p.getIcon("SignalHeadStateFlashingGreen"); 093 if (icon != null) { 094 elem.addContent(storeIcon("flashgreen", icon)); 095 } 096 icon = p.getIcon("SignalHeadStateFlashingLunar"); 097 if (icon != null) { 098 elem.addContent(storeIcon("flashlunar", icon)); 099 } 100 element.addContent(elem); 101 elem = new Element("iconmaps"); 102 String family = p.getFamily(); 103 if (family != null) { 104 elem.setAttribute("family", family); 105 } 106 element.addContent(elem); 107 108 storeLogixNG_Data(p, element); 109 110 element.setAttribute("class", "jmri.jmrit.display.configurexml.SignalHeadIconXml"); 111 return element; 112 } 113 114 /** 115 * Create a PositionableLabel, then add to a target JLayeredPane 116 * 117 * @param element Top level Element to unpack. 118 * @param o an Editor as an Object 119 * @throws JmriConfigureXmlException when a error prevents creating the objects as as 120 * required by the input XML 121 */ 122 @Override 123 public void load(Element element, Object o) throws JmriConfigureXmlException { 124 // create the objects 125 Editor ed = (Editor) o; 126 SignalHeadIcon l = new SignalHeadIcon(ed); 127 String name; 128 129 Attribute attr = element.getAttribute("signalhead"); 130 if (attr == null) { 131 log.error("incorrect information for signal head; must use signalhead name"); 132 ed.loadFailed(); 133 return; 134 } else { 135 name = attr.getValue(); 136 } 137 138 SignalHead sh = jmri.InstanceManager.getDefault(jmri.SignalHeadManager.class).getSignalHead(name); 139 140 if (sh != null) { 141 l.setSignalHead(name); 142 } else { 143 log.error("SignalHead named '{}' not found.", attr.getValue()); 144 // ed.loadFailed(); 145 return; 146 } 147 int rotation = 0; 148 try { 149 attr = element.getAttribute("rotate"); 150 rotation = attr.getIntValue(); 151 } catch (org.jdom2.DataConversionException e) { 152 } catch (NullPointerException e) { // considered normal if the attributes are not present 153 } 154 155 List<Element> aspects = element.getChildren(); 156 if (aspects.size() > 0) { 157 Element icons = element.getChild("icons"); 158 Element elem = element; 159 if (icons != null) { 160 aspects = icons.getChildren(); 161 elem = icons; 162 } 163 for (Element value : aspects) { 164 String aspect = value.getName(); 165 NamedIcon icon = loadIcon(l, aspect, elem, "SignalHead \"" + name + "\": icon \"" + aspect + "\" ", ed); 166 if (icon != null) { 167 l.setIcon(_nameMap.get(aspect), icon); 168 } else { 169 log.info("SignalHead \"{}\": icon \"{}\" removed", name, aspect); 170 } 171 } 172 log.debug("{} icons loaded for {}", aspects.size(), l.getNameString()); 173 } else { 174 // old style as attributes - somewhere around pre 2.5.4 175 NamedIcon icon = loadSignalIcon("red", rotation, l, element, name, ed); 176 if (icon != null) { 177 l.setIcon("SignalHeadStateRed", icon); 178 } 179 icon = loadSignalIcon("yellow", rotation, l, element, name, ed); 180 if (icon != null) { 181 l.setIcon("SignalHeadStateYellow", icon); 182 } 183 icon = loadSignalIcon("green", rotation, l, element, name, ed); 184 if (icon != null) { 185 l.setIcon("SignalHeadStateGreen", icon); 186 } 187 icon = loadSignalIcon("lunar", rotation, l, element, name, ed); 188 if (icon != null) { 189 l.setIcon("SignalHeadStateLunar", icon); 190 } 191 icon = loadSignalIcon("held", rotation, l, element, name, ed); 192 if (icon != null) { 193 l.setIcon("SignalHeadStateHeld", icon); 194 } 195 icon = loadSignalIcon("dark", rotation, l, element, name, ed); 196 if (icon != null) { 197 l.setIcon("SignalHeadStateDark", icon); 198 } 199 icon = loadSignalIcon("flashred", rotation, l, element, name, ed); 200 if (icon != null) { 201 l.setIcon("SignalHeadStateFlashingRed", icon); 202 } 203 icon = loadSignalIcon("flashyellow", rotation, l, element, name, ed); 204 if (icon != null) { 205 l.setIcon("SignalHeadStateFlashingYellow", icon); 206 } 207 icon = loadSignalIcon("flashgreen", rotation, l, element, name, ed); 208 if (icon != null) { 209 l.setIcon("SignalHeadStateFlashingGreen", icon); 210 } 211 icon = loadSignalIcon("flashlunar", rotation, l, element, name, ed); 212 if (icon != null) { 213 l.setIcon("SignalHeadStateFlashingLunar", icon); 214 } 215 } 216 Element elem = element.getChild("iconmaps"); 217 if (elem != null) { 218 attr = elem.getAttribute("family"); 219 if (attr != null) { 220 l.setFamily(attr.getValue()); 221 } 222 } 223 try { 224 attr = element.getAttribute("clickmode"); 225 if (attr != null) { 226 l.setClickMode(attr.getIntValue()); 227 } 228 } catch (org.jdom2.DataConversionException e) { 229 log.error("Failed on clickmode attribute: ", e); 230 } 231 232 try { 233 attr = element.getAttribute("litmode"); 234 if (attr != null) { 235 l.setLitMode(attr.getBooleanValue()); 236 } 237 } catch (org.jdom2.DataConversionException e) { 238 log.error("Failed on litmode attribute: ", e); 239 } 240 241 try { 242 ed.putItem(l); 243 } catch (Positionable.DuplicateIdException e) { 244 throw new JmriConfigureXmlException("Positionable id is not unique", e); 245 } 246 247 loadLogixNG_Data(l, element); 248 249 // load individual item's option settings after editor has set its global settings 250 loadCommonAttributes(l, Editor.SIGNALS, element); 251 } 252 253 private NamedIcon loadSignalIcon(String aspect, int rotation, SignalHeadIcon l, 254 Element element, String name, Editor ed) { 255 String msg = "SignalHead \"" + name + "\": icon \"" + aspect + "\" "; 256 NamedIcon icon = loadIcon(l, aspect, element, msg, ed); 257 if (icon == null) { 258 if (element.getAttribute(aspect) != null) { 259 String iconName = element.getAttribute(aspect).getValue(); 260 icon = NamedIcon.getIconByName(iconName); 261 if (icon == null) { 262 icon = ed.loadFailed(msg, iconName); 263 if (icon == null) { 264 log.info("{} removed for url= {}", msg, iconName); 265 } 266 } 267 if (icon != null) { 268 icon.setRotation(rotation, l); 269 } 270 } else { 271 log.info("did not load file aspect {} for SignalHead {}", aspect, name); 272 } 273 } 274 if (icon == null) { 275 log.info("SignalHead Icon \"{}\": icon \"{}\" removed", name, aspect); 276 } 277 return icon; 278 } 279 280 private final static Logger log = LoggerFactory.getLogger(SignalHeadIconXml.class); 281 282}