001package jmri.jmrit.display.layoutEditor.configurexml; 002 003import java.awt.geom.Point2D; 004import java.util.List; 005import jmri.Turnout; 006import jmri.jmrit.display.layoutEditor.LayoutEditor; 007import jmri.jmrit.display.layoutEditor.LayoutTurntable; 008import jmri.jmrit.display.layoutEditor.LayoutTurntableView; 009import jmri.jmrit.display.layoutEditor.TrackSegment; 010import org.jdom2.Attribute; 011import org.jdom2.DataConversionException; 012import org.jdom2.Element; 013 014/** 015 * This module handles configuration for display.LayoutTurntable objects for a 016 * LayoutEditor. 017 * 018 * @author David Duchamp Copyright (c) 2007 019 * @author George Warner Copyright (c) 2017-2018 020 * @author Bob Jacobsen Copyright (c) 2020 021 */ 022public class LayoutTurntableViewXml extends LayoutTrackViewXml { 023 024 public LayoutTurntableViewXml() { 025 } 026 027 /** 028 * Default implementation for storing the contents of a LayoutTurntable 029 * 030 * @param o Object to store, of type LayoutTurntable 031 * @return Element containing the complete info 032 */ 033 @Override 034 public Element store(Object o) { 035 036 LayoutTurntableView pv = (LayoutTurntableView) o; 037 LayoutTurntable p = pv.getTurntable(); 038 039 Element element = new Element("layoutturntable"); 040 boolean turnoutControl = p.isTurnoutControlled(); 041 // include attributes 042 element.setAttribute("ident", p.getId()); 043 if (!p.getBlockName().isEmpty()) { 044 element.setAttribute("blockname", p.getBlockName()); 045 } 046 element.setAttribute("radius", "" + p.getRadius()); 047 Point2D coords = pv.getCoordsCenter(); 048 element.setAttribute("xcen", "" + coords.getX()); 049 element.setAttribute("ycen", "" + coords.getY()); 050 element.setAttribute("turnoutControlled", "" + (turnoutControl ? "yes" : "no")); 051 boolean dispatcherManaged = p.isDispatcherManaged(); 052 if (dispatcherManaged) { 053 String exitMastName = p.getExitSignalMastName(); 054 if (exitMastName != null && !exitMastName.isEmpty()) { 055 element.setAttribute("exitmast", exitMastName); 056 } 057 String bufferMastName = p.getBufferSignalMastName(); 058 if (bufferMastName != null && !bufferMastName.isEmpty()) { 059 element.setAttribute("buffermast", bufferMastName); 060 } 061 element.setAttribute("signalIconPlacement", "" + p.getSignalIconPlacement()); 062 element.setAttribute("dispatcherManaged", "yes"); 063 } 064 element.setAttribute("class", "jmri.jmrit.display.layoutEditor.configurexml.LayoutTurntableXml"); // temporary until storage split 065 // add ray tracks 066 for (int i = 0; i < p.getNumberRays(); i++) { 067 Element rElem = new Element("raytrack"); 068 rElem.setAttribute("angle", "" + p.getRayAngle(i)); 069 TrackSegment t = p.getRayConnectOrdered(i); 070 if (t != null) { 071 rElem.setAttribute("connectname", t.getId()); 072 } 073 if (dispatcherManaged) { 074 String mastName = p.getRayTrackList().get(i).getApproachMastName(); 075 if (mastName != null && !mastName.isEmpty()) { 076 rElem.setAttribute("approachmast", mastName); 077 } 078 } 079 rElem.setAttribute("index", "" + p.getRayIndex(i)); 080 if (turnoutControl && p.getRayTurnoutName(i) != null) { 081 rElem.setAttribute("turnout", p.getRayTurnoutName(i)); 082 if (p.getRayTurnoutState(i) == Turnout.THROWN) { 083 rElem.setAttribute("turnoutstate", "thrown"); 084 } else { 085 rElem.setAttribute("turnoutstate", "closed"); 086 } 087 if (p.isRayDisabled(i)) { 088 rElem.setAttribute("disabled", "yes"); 089 } 090 if (p.isRayDisabledWhenOccupied(i)) { 091 rElem.setAttribute("disableWhenOccupied", "yes"); 092 } 093 } 094 element.addContent(rElem); 095 } 096 storeLogixNG_Data(pv, element); 097 return element; 098 } 099 100 @Override 101 public boolean load(Element shared, Element perNode) { 102 log.error("Invalid method called"); 103 return false; 104 } 105 106 /** 107 * Load, starting with the layout turntable element, then all the other data 108 * 109 * @param element Top level Element to unpack. 110 * @param o LayoutEditor as an Object 111 */ 112 @Override 113 public void load(Element element, Object o) { 114 // create the objects 115 LayoutEditor p = (LayoutEditor) o; 116 117 // get center point 118 String name = element.getAttribute("ident").getValue(); 119 double x = 0.0; 120 double y = 0.0; 121 double radius = 25.0; 122 try { 123 x = element.getAttribute("xcen").getFloatValue(); 124 y = element.getAttribute("ycen").getFloatValue(); 125 radius = element.getAttribute("radius").getFloatValue(); 126 } catch (org.jdom2.DataConversionException e) { 127 log.error("failed to convert layoutturntable center or radius attributes"); 128 } 129 // create the new LayoutTurntable 130 LayoutTurntable lt = new LayoutTurntable(name, p); 131 LayoutTurntableView lv = new LayoutTurntableView(lt, new Point2D.Double(x, y), p); 132 133 p.addLayoutTrack(lt, lv); 134 135 lv.setCoordsCenter(new Point2D.Double(x, y)); 136 log.trace("LayoutTurntable at {}, {}", x, y); 137 138 lt.setRadius(radius); 139 140 // get remaining attribute 141 Attribute a = element.getAttribute("blockname"); 142 if (a != null) { 143 lt.tLayoutBlockName = a.getValue(); 144 } 145 146 a = element.getAttribute("turnoutControlled"); 147 if (a != null) { 148 lt.setTurnoutControlled("yes".equalsIgnoreCase(a.getValue())); 149 } 150 151 a = element.getAttribute("dispatcherManaged"); 152 if (a != null) { 153 lt.setDispatcherManaged("yes".equalsIgnoreCase(a.getValue())); 154 if (lt.isDispatcherManaged()) { 155 a = element.getAttribute("exitmast"); 156 if (a != null) { 157 lt.tExitSignalMastName = a.getValue(); 158 } 159 a = element.getAttribute("buffermast"); 160 if (a != null) { 161 lt.tBufferSignalMastName = a.getValue(); 162 } 163 a = element.getAttribute("signalIconPlacement"); 164 if (a != null) { 165 try { 166 lt.setSignalIconPlacement(a.getIntValue()); 167 } catch (DataConversionException e) { 168 log.error("failed to convert signalIconPlacement attribute"); 169 } 170 } 171 } 172 } 173 174 // load ray tracks 175 List<Element> rayTrackList = element.getChildren("raytrack"); 176 if (rayTrackList.size() > 0) { 177 for (Element value : rayTrackList) { 178 double angle = 0.0; 179 int index = 0; 180 try { 181 angle = (value.getAttribute("angle")).getFloatValue(); 182 index = (value.getAttribute("index")).getIntValue(); 183 } catch (DataConversionException e) { 184 log.error("failed to convert ray track angle or index attributes"); 185 } 186 String connectName = ""; 187 a = value.getAttribute("connectname"); 188 if (a != null) { 189 connectName = a.getValue(); 190 } 191 LayoutTurntable.RayTrack ray = lt.addRay(angle); 192 ray.connectName = connectName; 193 if (lt.isDispatcherManaged()) { 194 a = value.getAttribute("approachmast"); 195 if (a != null) { 196 ray.approachMastName = a.getValue(); 197 } 198 } 199 if (lt.isTurnoutControlled() && value.getAttribute("turnout") != null) { 200 if (value.getAttribute("turnoutstate").getValue().equals("thrown")) { 201 lt.setRayTurnout(index, value.getAttribute("turnout").getValue(), Turnout.THROWN); 202 } else { 203 lt.setRayTurnout(index, value.getAttribute("turnout").getValue(), Turnout.CLOSED); 204 } 205 a = value.getAttribute("disabled"); 206 if (a != null) { 207 lt.setRayDisabled(index, "yes".equalsIgnoreCase(a.getValue())); 208 } 209 a = value.getAttribute("disableWhenOccupied"); 210 if (a != null) { 211 lt.setRayDisabledWhenOccupied(index, "yes".equalsIgnoreCase(a.getValue())); 212 } 213 } 214 } 215 } 216 217 loadLogixNG_Data(lv, element); 218 } 219 220 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LayoutTurntableViewXml.class); 221}