diff --git a/pom.xml b/pom.xml index e7f6766..661da07 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 de.srsoftware web4rail - 1.2.38 + 1.2.39 Web4Rail jar Java Model Railway Control diff --git a/resources/translations/Application.de.translation b/resources/translations/Application.de.translation index ddb0f36..9f7187a 100644 --- a/resources/translations/Application.de.translation +++ b/resources/translations/Application.de.translation @@ -27,6 +27,7 @@ autopilot active for train : Autopilot für Zug aktiviert autopilot inactive for train : Autopilot nicht aktiv für Zug Availability : Verfügbarkeit Back : zurück +backward : rückwärts Basic properties : Grundlegende Eigenschaften BlockFree : Blockbelegung Block {} is free : Block {} ist frei @@ -39,16 +40,18 @@ BrakeStop : Zug anhalten Brake time¹, forward : Bremszeit¹, vorwärts Brake time¹, reverse : Bremszeit¹, rückwärts Brake time table : Bremszeit-Tabelle +CarInTrain : Wagen im Zug Car manager : Waggon-Verwaltung +CarOrientation : Wagen-Laufrichtung Cars\: : Waggons: -Click here to select train! : HIer klicken, um Zug auszuwählen! -[Click here to select block!] : [Hier klicken, um Block auszuwählen!] -Click to setup tag : Hier klicken, um Markierung anzugeben Click here to add conditions : Hier klicken, um Bedingungen hinzuzufügen -[Click here to select display!] : [Hier klicken, um Anzeige auszuwählen!] +Click here to select block! : Hier klicken, um Block auszuwählen! +Click here to select car! : Hier klicken, um Fahrzeug auszuwählen! +Click here to select display! : Hier klicken, um Anzeige auszuwählen! Click here to select train! : Hier klicken, um Zug auszuwählen! click here to setup contact : Hier klicken, um Kontakt auszuwählen click here to setup relay : Hier klicken, um Relais einzurichten +Click here to setup tag : Hier klicken, um Markierung anzugeben click here to setup turnout : Hier klicken, um Weiche einzurichten Click on a name to edit the entry. : Klicke auf einen Namen, um einen Eintrag zu bearbeiten. Command to send : Kommando, welches gesendet werden soll @@ -107,6 +110,7 @@ Help : Hilfe (id\: {}, length\: {}) : (Id: {}, Länge: {}) if ({})\: : falls ({}): inverted : invertiert +{} is oriented {} : {} ist {} gerichtet known cars : bekannte Waggons known locomotives : bekannte Lokomotiven known trains : bekannte Züge @@ -172,6 +176,7 @@ Route will only be available, if all conditions are fulfilled. : Route ist nur v Save : speichern SavePlan : Plan speichern Select block : Block auswählen +Select car : Fahrzeug auswählen Select contact\: : Kotakt auswählen: Select display : Anzeige auswählen Select from plan : Auf Plan auswählen @@ -230,6 +235,8 @@ toggle {} : {} umschalten Toggle power : Stom umschalten Train : Zug Train\: : Zug: +train contains {} : {} ist im Zug +train does not contain {} : {} ist nicht im Zug train does not have tag "{}" : Zug hat keine Markierung „{}“ train has tag "{}" : Zug hat Markierung „{}“ TrainHasTag : Zug mit Tag diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java index daad6b1..486baa7 100644 --- a/src/main/java/de/srsoftware/web4rail/Route.java +++ b/src/main/java/de/srsoftware/web4rail/Route.java @@ -284,7 +284,7 @@ public class Route extends BaseClass { Fieldset fieldset = new Fieldset(t("Brake time table")); Table table = new Table(); table.addHead(t("Train"),t("Brake time¹, forward"),t("Brake time¹, reverse")); - for (Train t : Train.list()) { + for (Train t : BaseClass.listElements(Train.class)) { Integer fTime = brakeTimes.get(t.brakeId()); Integer rTime = brakeTimes.get(t.brakeId(true)); table.addRow(t,isSet(fTime)? fTime+NBSP+"ms" : "–",isSet(rTime)? fTime+NBSP+"ms" : "–"); diff --git a/src/main/java/de/srsoftware/web4rail/actions/StopAllTrains.java b/src/main/java/de/srsoftware/web4rail/actions/StopAllTrains.java index 7855a05..333a16d 100644 --- a/src/main/java/de/srsoftware/web4rail/actions/StopAllTrains.java +++ b/src/main/java/de/srsoftware/web4rail/actions/StopAllTrains.java @@ -11,7 +11,7 @@ public class StopAllTrains extends Action { @Override public boolean fire(Context context) { - Train.list().forEach(train -> train.stopNow()); + BaseClass.listElements(Train.class).forEach(train -> train.stopNow()); return true; } } diff --git a/src/main/java/de/srsoftware/web4rail/conditions/CarInTrain.java b/src/main/java/de/srsoftware/web4rail/conditions/CarInTrain.java new file mode 100644 index 0000000..c226c96 --- /dev/null +++ b/src/main/java/de/srsoftware/web4rail/conditions/CarInTrain.java @@ -0,0 +1,59 @@ +package de.srsoftware.web4rail.conditions; + +import java.util.HashMap; +import java.util.List; + +import org.json.JSONObject; + +import de.srsoftware.web4rail.BaseClass; +import de.srsoftware.web4rail.Window; +import de.srsoftware.web4rail.moving.Car; +import de.srsoftware.web4rail.moving.Train; +import de.srsoftware.web4rail.tags.Fieldset; + +public class CarInTrain extends Condition { + + private static final String CAR = "car"; + private Car car; + + @Override + public boolean fulfilledBy(Context context) { + Train train = context.train(); + if (isNull(train) || isNull(car)) return false; + boolean contained = train.cars().contains(car); + return inverted ? !contained : contained; + } + + @Override + public JSONObject json() { + JSONObject json = super.json(); + if (isSet(car)) json.put(CAR, car.id().toString()); + return json; + } + + public Condition load(JSONObject json) { + super.load(json); + if (json.has(CAR)) car = BaseClass.get(new Id(json.getString(CAR))); + return this; + } + + @Override + protected Window properties(List
preForm, FormInput formInputs, List
postForm) { + formInputs.add(t("Select car"),Car.selector(car, null)); + + return super.properties(preForm, formInputs, postForm); + } + + @Override + public String toString() { + if (isNull(car)) return "["+t("Click here to select car!")+"]"; + return t(inverted ? "train does not contain {}" : "train cotains {}",car) ; + } + + @Override + protected Object update(HashMap params) { + String carId = params.get(Car.class.getSimpleName()); + if (isSet(carId)) car = BaseClass.get(new Id(carId)); + return super.update(params); + } +} diff --git a/src/main/java/de/srsoftware/web4rail/conditions/CarOrientation.java b/src/main/java/de/srsoftware/web4rail/conditions/CarOrientation.java new file mode 100644 index 0000000..99c4835 --- /dev/null +++ b/src/main/java/de/srsoftware/web4rail/conditions/CarOrientation.java @@ -0,0 +1,72 @@ +package de.srsoftware.web4rail.conditions; + +import java.util.HashMap; +import java.util.List; + +import org.json.JSONObject; + +import de.srsoftware.tools.Tag; +import de.srsoftware.web4rail.BaseClass; +import de.srsoftware.web4rail.Window; +import de.srsoftware.web4rail.moving.Car; +import de.srsoftware.web4rail.tags.Fieldset; +import de.srsoftware.web4rail.tags.Radio; + +public class CarOrientation extends Condition { + + private static final String ORIENTATION = "orientation"; + private static final String CAR = "car"; + private boolean orientation = Car.FORWARD; + private Car car; + + @Override + public boolean fulfilledBy(Context context) { + return inverted ? car.orientation() != orientation : car.orientation() == orientation; + } + + @Override + public JSONObject json() { + JSONObject json = super.json().put(ORIENTATION, orientation); + if (isSet(car)) json.put(CAR, car.id().toString()); + return json; + } + + public Condition load(JSONObject json) { + super.load(json); + if (json.has(CAR)) car = BaseClass.get(new Id(json.getString(CAR))); + if (json.has(ORIENTATION)) orientation = json.getBoolean(ORIENTATION); + return this; + } + + @Override + protected Window properties(List
preForm, FormInput formInputs, List
postForm) { + formInputs.add(t("Select car"),Car.selector(car, null)); + + Tag radioGroup = new Tag("span"); + new Radio(ORIENTATION, "f", t("forward"), orientation).addTo(radioGroup); + new Radio(ORIENTATION, "r", t("revers"), !orientation).addTo(radioGroup); + + return super.properties(preForm, formInputs, postForm); + } + + @Override + public String toString() { + return t("{} is oriented {}",car,inverted ? t("backward") : t("forward")); + } + + @Override + protected Object update(HashMap params) { + String or = params.get(ORIENTATION); + if (isSet(or)) switch (or){ + case "f": + orientation = Car.FORWARD; + break; + case "r": + orientation = Car.REVERSE; + break; + } + String carId = params.get(Car.class.getSimpleName()); + if (isSet(carId)) car = BaseClass.get(new Id(carId)); + return super.update(params); + } +} diff --git a/src/main/java/de/srsoftware/web4rail/conditions/Condition.java b/src/main/java/de/srsoftware/web4rail/conditions/Condition.java index 128b576..98c933b 100644 --- a/src/main/java/de/srsoftware/web4rail/conditions/Condition.java +++ b/src/main/java/de/srsoftware/web4rail/conditions/Condition.java @@ -116,6 +116,8 @@ public abstract class Condition extends BaseClass { return List.of( AutopilotActive.class, BlockFree.class, + CarInTrain.class, + CarOrientation.class, OrCondition.class, PushPullTrain.class, TrainHasTag.class, diff --git a/src/main/java/de/srsoftware/web4rail/conditions/TrainSelect.java b/src/main/java/de/srsoftware/web4rail/conditions/TrainSelect.java index 71fc485..b213e83 100644 --- a/src/main/java/de/srsoftware/web4rail/conditions/TrainSelect.java +++ b/src/main/java/de/srsoftware/web4rail/conditions/TrainSelect.java @@ -22,7 +22,9 @@ public class TrainSelect extends Condition { @Override public JSONObject json() { - return super.json().put(REALM_TRAIN, train.id()); + JSONObject json = super.json(); + if (isSet(train)) json.put(REALM_TRAIN, train.id()); + return json; } public Condition load(JSONObject json) { diff --git a/src/main/java/de/srsoftware/web4rail/moving/Car.java b/src/main/java/de/srsoftware/web4rail/moving/Car.java index e4f1733..d32db45 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Car.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Car.java @@ -5,11 +5,13 @@ import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.TreeSet; +import java.util.Vector; import java.util.stream.Collectors; import org.json.JSONObject; @@ -27,6 +29,7 @@ import de.srsoftware.web4rail.tags.Fieldset; import de.srsoftware.web4rail.tags.Form; import de.srsoftware.web4rail.tags.Input; import de.srsoftware.web4rail.tags.Label; +import de.srsoftware.web4rail.tags.Select; import de.srsoftware.web4rail.tags.Table; public class Car extends BaseClass implements Comparable{ @@ -70,6 +73,9 @@ public class Car extends BaseClass implements Comparable{ car.clone(); } else new Car(params.get(Car.NAME)).parent(plan); return Car.manager(); + case ACTION_DROP: + car.remove(); + return Car.manager(); case ACTION_MOVE: return car.moveUp(); case ACTION_PROPS: @@ -176,6 +182,9 @@ public class Car extends BaseClass implements Comparable{ String maxSpeed = (car.maxSpeedForward == 0 ? "–":""+car.maxSpeedForward)+NBSP; if (car.maxSpeedReverse != car.maxSpeedForward) maxSpeed += "("+car.maxSpeedReverse+")"+NBSP; + Tag actions = new Tag("span"); + car.cloneButton().addTo(actions); + car.button(t("delete"),Map.of(ACTION,ACTION_DROP)).addTo(actions); table.addRow( car.stockId, car.link(), @@ -183,7 +192,8 @@ public class Car extends BaseClass implements Comparable{ car.length+NBSP+lengthUnit, isSet(car.train) ? car.train.link("span", car.train) : "", String.join(", ", car.tags()), - car.cloneButton()); + actions + ); } table.addTo(win); @@ -210,6 +220,10 @@ public class Car extends BaseClass implements Comparable{ return name; } + public boolean orientation() { + return orientation; + } + @Override protected Window properties(List
preForm, FormInput formInputs, List
postForm) { formInputs.add(t("Name"),new Input(NAME,name)); @@ -285,4 +299,21 @@ public class Car extends BaseClass implements Comparable{ orientation = !orientation; return t("Reversed {}.",this); } + + public static Select selector(Car preselected,Collection exclude) { + if (isNull(exclude)) exclude = new Vector(); + Select select = new Select(Car.class.getSimpleName()); + new Tag("option").attr("value","0").content(t("unset")).addTo(select); + List cars = BaseClass.listElements(Car.class); + cars.sort((c1,c2) -> { + if (isSet(c1.stockId)) return c1.stockId.compareTo(c2.stockId); + return c1.name().compareTo(c2.name()); + }); + for (Car car : cars) { + if (exclude.contains(car)) continue; + Tag opt = select.addOption(car.id(), (car.stockId.isEmpty() ? "" : "["+car.stockId+"] ") + car); + if (car == preselected) opt.attr("selected", "selected"); + } + return select; + } } diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java index e2b703b..a1c56fe 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Train.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java @@ -5,7 +5,6 @@ import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -387,12 +386,6 @@ public class Train extends BaseClass implements Comparable { return link(type, tx); } - public static ArrayList list() { - ArrayList list = new ArrayList(trains.values()); - list.sort((t1,t2)->t1.name.compareTo(t2.name)); - return list; - } - public static void loadAll(String filename, Plan plan) throws IOException { BufferedReader file = new BufferedReader(new FileReader(filename, UTF8)); String line = file.readLine(); @@ -429,7 +422,7 @@ public class Train extends BaseClass implements Comparable { new Tag("p").content(t("Click on a name to edit the entry.")).addTo(win); Table table = new Table().addHead(t("Name"),t("Length"),t("Max. Speed"),t("Tags"),t("Route"),t("Current location"),t("Destination"),t("Auto pilot")); - list().forEach(train -> { + BaseClass.listElements(Train.class).forEach(train -> { int ms = train.maxSpeed(); table.addRow( train.link(), @@ -614,7 +607,7 @@ public class Train extends BaseClass implements Comparable { if (isNull(exclude)) exclude = new Vector(); Select select = new Select(Train.class.getSimpleName()); new Tag("option").attr("value","0").content(t("unset")).addTo(select); - for (Train train : Train.list()) { + for (Train train : BaseClass.listElements(Train.class)) { if (exclude.contains(train)) continue; Tag opt = select.addOption(train.id, train); if (train == preselected) opt.attr("selected", "selected"); @@ -743,10 +736,7 @@ public class Train extends BaseClass implements Comparable { } public static void startAll() { - for (Train train : list()) { - String response = train.automatic(); - LOG.info(response); - } + for (Train train : BaseClass.listElements(Train.class)) LOG.info(train.automatic()); } private void startSimulation() { diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Block.java b/src/main/java/de/srsoftware/web4rail/tiles/Block.java index cfcbea5..26c724e 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Block.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Block.java @@ -272,9 +272,11 @@ public abstract class Block extends StretchableTile{ if (params.containsKey(NAME)) name=params.get(NAME); if (params.containsKey(Train.class.getSimpleName())) { Id trainId = Id.from(params,Train.class.getSimpleName()); - if (trainId.equals(0)) { // TODO: this is rubbish - if (isSet(train)) train.dropTrace(); - train.set(null); + if (trainId.equals(0)) { + if (isSet(train)) { + train.dropTrace(); + train.set(null); + } train = null; } else { Train newTrain = Train.get(trainId);