diff --git a/pom.xml b/pom.xml index 42fb9f2..ec76b3f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 de.srsoftware web4rail - 0.9.7 + 0.9.8 Web4Rail jar Java Model Railway Control diff --git a/resources/translations/Application.de.translation b/resources/translations/Application.de.translation index 7136bfb..350e92a 100644 --- a/resources/translations/Application.de.translation +++ b/resources/translations/Application.de.translation @@ -37,10 +37,14 @@ SetSpeed : Geschwindigkeit ändern Setup actions : Aktivierungs-Aktionen Signals : Signale StopAuto : Automatikmodus abschalten +Tags : Markierungen Train\: : Zug: +train does not have tag "{}" : Zug hat keine Markierung „{}“ +train has tag "{}" : Zug hat Markierung „{}“ train is longer than {} : Zug ist länger als {} train is shorter than {} : Zug ist kürzer als {} Trains\: : Züge: +TrainHasTag : Zug mit Tag TrainLength : Zuglänge TrainSelect : Zug-Auswahl Turn allowed : Wenden erlaubt diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java index b15ee15..0186af9 100644 --- a/src/main/java/de/srsoftware/web4rail/Route.java +++ b/src/main/java/de/srsoftware/web4rail/Route.java @@ -191,7 +191,7 @@ public class Route implements Constants{ Tag li = new Tag("li"); condition.link("span",REALM_ROUTE+":"+id).addTo(li); Map params = Map.of(REALM,REALM_ROUTE,ID,id(),ACTION,DROP_CONDITION,REALM_CONDITION,condition.id()); - new Button(t("delete"), params).addTo(li).addTo(list); + new Button(t("delete"), params).addTo(li.content(NBSP)).addTo(list); } list.addTo(win); } diff --git a/src/main/java/de/srsoftware/web4rail/conditions/Condition.java b/src/main/java/de/srsoftware/web4rail/conditions/Condition.java index b10711f..54fd46b 100644 --- a/src/main/java/de/srsoftware/web4rail/conditions/Condition.java +++ b/src/main/java/de/srsoftware/web4rail/conditions/Condition.java @@ -70,6 +70,10 @@ public abstract class Condition implements Constants { return null; } + public int id() { + return id; + } + public JSONObject json() { JSONObject json = new JSONObject().put(TYPE, getClass().getSimpleName()); if (inverted) json.put(INVERTED, true); @@ -88,6 +92,10 @@ public abstract class Condition implements Constants { return new Tag(tagClass).clazz("link").attr("onclick","request("+json+")").content(toString()); } + private static List> list() { + return List.of(TrainHasTag.class,TrainSelect.class,TrainLength.class); + } + public Tag propForm(HashMap params) { Form form = new Form("condition-props-"+id); new Input(REALM,REALM_CONDITION).hideIn(form); @@ -118,10 +126,6 @@ public abstract class Condition implements Constants { return select.addTo(new Label(t("Action type:")+NBSP)); } - private static List> list() { - return List.of(TrainSelect.class,TrainLength.class); - } - public static String t(String text, Object...fills) { return Translation.get(Application.class, text, fills); } @@ -135,8 +139,4 @@ public abstract class Condition implements Constants { inverted = "on".equals(params.get(INVERTED)); return t("updated {}.",this); } - - public int id() { - return id; - } } diff --git a/src/main/java/de/srsoftware/web4rail/conditions/TrainHasTag.java b/src/main/java/de/srsoftware/web4rail/conditions/TrainHasTag.java new file mode 100644 index 0000000..695ddc3 --- /dev/null +++ b/src/main/java/de/srsoftware/web4rail/conditions/TrainHasTag.java @@ -0,0 +1,50 @@ +package de.srsoftware.web4rail.conditions; + +import java.util.HashMap; + +import org.json.JSONObject; + +import de.srsoftware.tools.Tag; +import de.srsoftware.web4rail.actions.Action.Context; +import de.srsoftware.web4rail.tags.Input; +import de.srsoftware.web4rail.tags.Label; + +public class TrainHasTag extends Condition { + + private static final String TAG = "tag"; + private String tag = null; + + @Override + public boolean fulfilledBy(Context context) { + if (tag == null) return true; + return context.train.tags().contains(tag); + } + + @Override + public JSONObject json() { + return super.json().put(TAG, tag); + } + + public static TrainHasTag load(JSONObject json) { + TrainHasTag tl = new TrainHasTag(); + if (json.has(TAG)) tl.tag = json.getString(TAG); + return tl; + } + + @Override + public Tag propForm(HashMap params) { + return new Input(TAG, tag == null ? "" : tag).addTo(new Label(t("Tag:")+NBSP)).addTo(super.propForm(params)); + } + + @Override + public String toString() { + if (tag == null) return t("[Click to setup tag]"); + return t(inverted ? "train does not have tag \"{}\"" : "train has tag \"{}\"",tag) ; + } + + @Override + protected Object update(HashMap params) { + tag = params.get(TAG); + return super.update(params); + } +} diff --git a/src/main/java/de/srsoftware/web4rail/moving/Car.java b/src/main/java/de/srsoftware/web4rail/moving/Car.java index 73c8f00..06e1843 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Car.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Car.java @@ -7,7 +7,9 @@ import java.io.FileWriter; import java.io.IOException; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.Map.Entry; +import java.util.TreeSet; import org.json.JSONObject; import org.slf4j.Logger; @@ -32,6 +34,8 @@ public class Car implements Constants { public static final String NAME = "name"; private static final String LENGTH = "length"; private static final String STOCK_ID = "stock-id"; + private static final String TAGS = "tags"; + protected HashSet tags = new HashSet(); private String id; private String name; @@ -94,6 +98,7 @@ public class Car implements Constants { json.put(NAME, name); json.put(LENGTH, length); json.put(STOCK_ID, stockId); + if (!tags.isEmpty()) json.put(TAGS, tags); return json; } @@ -121,6 +126,7 @@ public class Car implements Constants { if (json.has(ID)) id = json.getString(ID); if (json.has(LENGTH)) length = json.getInt(LENGTH); if (json.has(STOCK_ID)) stockId = json.getString(STOCK_ID); + if (json.has(TAGS)) json.getJSONArray(TAGS).forEach(elem -> { tags.add(elem.toString()); }); return this; } @@ -139,9 +145,10 @@ public class Car implements Constants { new Input(REALM,REALM_CAR).hideIn(form); new Input(ID,id()).hideIn(form); Fieldset fieldset = new Fieldset("Basic properties"); - new Input(NAME,name).addTo(new Label(t("Name"))).addTo(fieldset); - new Input(STOCK_ID,stockId).addTo(new Label(t("Stock ID"))).addTo(fieldset); - new Input(LENGTH,length).attr("type", "number").addTo(new Label(t("Length"))).addTo(fieldset); + new Input(NAME,name).addTo(new Label(t("Name")+NBSP)).addTo(fieldset); + new Input(STOCK_ID,stockId).addTo(new Label(t("Stock ID")+NBSP)).addTo(fieldset); + new Input(LENGTH,length).attr("type", "number").addTo(new Label(t("Length")+NBSP)).addTo(fieldset); + new Input(TAGS,String.join(", ", tags)).addTo(new Label(t("Tags")+NBSP)).addTo(fieldset); fieldset.addTo(form); return form; } @@ -181,6 +188,10 @@ public class Car implements Constants { return Translation.get(Application.class, txt, fills); } + public TreeSet tags() { + return new TreeSet(tags); + } + @Override public String toString() { return getClass().getSimpleName()+"("+name()+")"; @@ -194,6 +205,14 @@ public class Car implements Constants { if (params.containsKey(NAME)) name = params.get(NAME); if (params.containsKey(STOCK_ID)) stockId = params.get(STOCK_ID); if (params.containsKey(LENGTH)) length = Integer.parseInt(params.get(LENGTH)); + if (params.containsKey(TAGS)) { + String[] parts = params.get(TAGS).replace(",", " ").split(" "); + tags.clear(); + for (String tag : parts) { + tag = tag.trim(); + if (!tag.isEmpty()) tags.add(tag); + } + } return this; } } diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java index 90c9e2c..4b28e73 100644 --- a/src/main/java/de/srsoftware/web4rail/moving/Train.java +++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java @@ -11,6 +11,8 @@ import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Random; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.Vector; import org.json.JSONObject; @@ -62,6 +64,10 @@ public class Train implements Constants { private static final String LOCOS = "locomotives"; private Vector locos = new Vector(); + + private static final String TAGS = "tags"; + private HashSet tags = new HashSet(); + private Block block = null; @@ -208,6 +214,7 @@ public class Train implements Constants { Vector carIds = new Vector(); for (Car car : cars) carIds.add(car.id()); json.put(CARS,carIds); + if (!tags.isEmpty()) json.put(TAGS, tags); return json; } @@ -247,6 +254,7 @@ public class Train implements Constants { if (json.has(NAME)) name = json.getString(NAME); for (Object id : json.getJSONArray(CARS)) add(Car.get((String)id)); for (Object id : json.getJSONArray(LOCOS)) add((Locomotive) Car.get((String)id)); + if (json.has(TAGS)) json.getJSONArray(TAGS).forEach(elem -> { tags.add(elem.toString()); }); return this; } @@ -336,6 +344,7 @@ public class Train implements Constants { new Input(ID,id).hideIn(form); new Input(NAME,name).addTo(form); new Checkbox(PUSH_PULL, t("Push-pull train"), pushPull).addTo(form); + new Input(TAGS,String.join(", ", tags)).addTo(new Label(t("Tags")+NBSP)).addTo(form); new Button(t("Apply")).addTo(form).addTo(fieldset); new Button(t("Turn"), "train("+id+",'"+ACTION_TURN+"')").addTo(fieldset).addTo(window); @@ -363,11 +372,21 @@ public class Train implements Constants { } if (direction != null) new Tag("li").content(t("Direction: heading {}",direction)).addTo(propList); + Tag tagList = new Tag("ul"); + for (String tag : tags()) new Tag("li").content(tag).addTo(tagList); + tagList.addTo(new Tag("li").content(t("Tags"))).addTo(propList); propList.addTo(fieldset).addTo(window); return window; } + public SortedSet tags() { + TreeSet list = new TreeSet(tags); + for (Locomotive loco : locos) list.addAll(loco.tags()); + for (Car car:cars) list.addAll(car.tags()); + return list; + } + public Object quitAutopilot() { if (autopilot != null) { autopilot.stop = true; @@ -484,6 +503,15 @@ public class Train implements Constants { LOG.debug("update({})",params); pushPull = params.containsKey(PUSH_PULL) && params.get(PUSH_PULL).equals("on"); if (params.containsKey(NAME)) name = params.get(NAME); + if (params.containsKey(TAGS)) { + String[] parts = params.get(TAGS).replace(",", " ").split(" "); + tags.clear(); + for (String tag : parts) { + tag = tag.trim(); + if (!tag.isEmpty()) tags.add(tag); + } + } + return this; } } diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Block.java b/src/main/java/de/srsoftware/web4rail/tiles/Block.java index 8bfddcd..2836343 100644 --- a/src/main/java/de/srsoftware/web4rail/tiles/Block.java +++ b/src/main/java/de/srsoftware/web4rail/tiles/Block.java @@ -67,7 +67,7 @@ public abstract class Block extends StretchableTile{ new Checkbox(ALLOW_TURN,t("Turn allowed"),turnAllowed).addTo(new Tag("p")).addTo(form); Select select = Train.selector(train, null); - select.addTo(new Label(t("Trains:")+NBSP)).addTo(new Tag("p")).addTo(form); + select.addTo(new Label(t("Train:")+NBSP)).addTo(new Tag("p")).addTo(form); return form; }