Ticket #7552: 7552_delta.patch
File 7552_delta.patch, 23.3 KB (added by , 12 years ago) |
---|
-
data/defaultpresets.xml
diff --git a/data/defaultpresets.xml b/data/defaultpresets.xml index d8a5172..ff22e70 100755
a b combo: combo box, with multiple choices and possible to enter free form text 38 38 values: comma separated list of values 39 39 display_values: comma separated list of values to be displayed instead of the 40 40 database values, order and number must be equal to values 41 short_description: comma separated list of texts to be displayed below each 42 display_value. (Only if it is not possible to describe 43 the entry in 2-3 words.) Instead of comma separeted list, you can 44 also write it in the following form: 45 <short_description>first description</short_description> 46 ... 47 <short_description>last description</short_description> 41 short_descriptions: comma separated list of texts to be displayed below each 42 display_value. (Only if it is not possible to describe 43 the entry in 2-3 words.) Instead of comma separeted list 44 instead using values, display_values and short_descriptions, the following form is also supported: 45 <list_item value="" display_value="' short_description="" icon=""/> 48 46 default: default string to display 49 47 delete_if_empty: true/false 50 48 use_last_as_default: true/false/force … … multiselect: list of values from which zero or more can be selected 54 52 text: fixed label to display 55 53 delimiter: character that separates values (default: semicolon) - this 56 54 will also be used to separate selected values in the tag. 57 values: delimiter-separated list of values (delimiter can be escaped with backslash)58 55 rows: specify the number of rows to display (default -1) 56 values: delimiter-separated list of values (delimiter can be escaped with backslash) 59 57 display_values: delimiter-separated list of values to be displayed instead of the 60 58 database values, order and number must be equal to values 61 short_description: delimiter-separated list of texts to be displayed below each 62 display_value. (Only if it is not possible to describe 63 the entry in 2-3 words.) Instead of a separated list, you can 64 also write it in the following form: 65 <short_description>first description</short_description> 66 ... 67 <short_description>last description</short_description> 59 short_descriptions: delimiter-separated list of texts to be displayed below each 60 display_value. (Only if it is not possible to describe 61 the entry in 2-3 words.) Instead of a separated list 62 instead using values, display_values and short_descriptions, the following form is also supported: 63 <list_item value="" display_value="' short_description="" icon=""/> 68 64 default: default string to display 69 65 delete_if_empty: true/false 70 66 use_last_as_default: true/false/force … … are supplied, then "values" will be treated as "display_values" and translated i 690 686 <key key="highway" value="path" /> 691 687 <optional> 692 688 <text key="name" text="Name" default="" delete_if_empty="true" /> 693 <combo key="sac_scale" text="SAC Scale" values="hiking,mountain_hiking,demanding_mountain_hiking,alpine_hiking,demanding_alpine_hiking,difficult_alpine_hiking" default="" delete_if_empty="true" display_values="T1 - hiking trail,T2 - mountain hiking trail,T3 - difficult\, exposed hiking trail,T4 - difficult\, exposed\, steep alpine trail,T5 - difficult alpine trail with climbing,T6 - hazardous alpine trail with climbing">694 < short_description>Trail well cleared. Area flat or slightly sloped, no fall hazard</short_description>695 < short_description>Trail with continuous line and balanced ascent. Terrain partially steep, fall hazard possible</short_description>696 < short_description>exposed sites may be secured with ropes or chains, possible need to use hands for balance. Partly exposed sites with fall hazard, scree, pathless jagged rocks</short_description>697 < short_description>sometimes need for hand use to get ahead. Terrain quite exposed, precarious grassy acclivities, jagged rocks, facile snow-free glaciers.</short_description>698 < short_description>single plainly climbing up to second grade. Exposed, demanding terrain, jagged rocks, few dangerous glacier and snow</short_description>699 < short_description>climbing up to second grade. Often very exposed, precarious jagged rocks, glacier with danger to slip and fall</short_description>689 <combo key="sac_scale" text="SAC Scale"> 690 <list_entry value="hiking" display_value="T1 - hiking trail" short_description="Trail well cleared. Area flat or slightly sloped, no fall hazard" /> 691 <list_entry value="mountain_hiking" display_value="T2 - mountain hiking trail" short_description="Trail with continuous line and balanced ascent. Terrain partially steep, fall hazard possible" /> 692 <list_entry value="demanding_mountain_hiking" display_value="T3 - difficult, exposed hiking trail" short_description="exposed sites may be secured with ropes or chains, possible need to use hands for balance. Partly exposed sites with fall hazard, scree, pathless jagged rocks" /> 693 <list_entry value="alpine_hiking" display_value="T4 - difficult, exposed, steep alpine trail" short_description="sometimes need for hand use to get ahead. Terrain quite exposed, precarious grassy acclivities, jagged rocks, facile snow-free glaciers" /> 694 <list_entry value="demanding_alpine_hiking" display_value="T5 - difficult alpine trail with climbing" short_description="single plainly climbing up to second grade. Exposed, demanding terrain, jagged rocks, few dangerous glacier and snow" /> 695 <list_entry value="difficult_alpine_hiking" display_value="T6 - hazardous alpine trail with climbing" short_description="climbing up to second grade. Often very exposed, precarious jagged rocks, glacier with danger to slip and fall" /> 700 696 </combo> 701 697 <combo key="mtb:scale" text="MTB Scale" values="0,1,2,3,4,5" default="" delete_if_empty="true" /> 702 698 <combo key="surface" text="Surface" values="paved,unpaved,asphalt,concrete,metal,wood,paving_stones,cobblestone,gravel,pebblestone,compacted,grass_paver,grass,sand,ground" default="" delete_if_empty="true" /> -
data/tagging-preset.xsd
diff --git a/data/tagging-preset.xsd b/data/tagging-preset.xsd index 64a0d4e..f4d17b8 100644
a b 125 125 <anyAttribute processContents="skip" /> 126 126 </complexType> 127 127 128 <complexType name="list_entry"> 129 <attribute name="value" type="string" use="required" /> 130 <attribute name="display_value" type="string" /> 131 <attribute name="short_description" type="string" /> 132 <attribute name="icon" type="string" /> 133 </complexType> 134 128 135 <complexType name="combo"> 129 136 <sequence> 130 <element name="short_description" type="string" minOccurs="0" 131 maxOccurs="unbounded" /> 137 <element name="list_entry" type="tns:list_entry" /> 132 138 </sequence> 133 139 <attribute name="key" type="string" use="required" /> 134 140 <attribute name="text" type="string" /> -
src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
diff --git a/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java b/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java index 86749ee..fa09340 100644
a b import static org.openstreetmap.josm.tools.I18n.trn; 7 7 8 8 import java.awt.Component; 9 9 import java.awt.Dimension; 10 import java.awt.Font; 10 11 import java.awt.GridBagLayout; 11 12 import java.awt.Image; 12 13 import java.awt.Insets; … … import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingTextField; 71 72 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionItemPritority; 72 73 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList; 73 74 import org.openstreetmap.josm.gui.util.GuiHelper; 74 import org.openstreetmap.josm.gui.widgets.HtmlPanel;75 75 import org.openstreetmap.josm.io.MirroredInputStream; 76 76 import org.openstreetmap.josm.tools.GBC; 77 77 import org.openstreetmap.josm.tools.ImageProvider; 78 78 import org.openstreetmap.josm.tools.UrlLabel; 79 import org.openstreetmap.josm.tools.Utils; 79 80 import org.openstreetmap.josm.tools.XmlObjectParser; 80 81 import org.openstreetmap.josm.tools.template_engine.ParseError; 81 82 import org.openstreetmap.josm.tools.template_engine.TemplateEntry; … … public class TaggingPreset extends AbstractAction implements MapView.LayerChange 193 194 return returnValue; 194 195 } 195 196 196 protected static class PresetListEntry { 197 String value; 198 String display_value; 199 String short_description; 197 public static class PresetListEntry { 198 public String value; 199 public String display_value; 200 public String short_description; 201 public String icon; 202 public String locale_display_value; 203 public String locale_short_description; 200 204 201 205 public String getListDisplay() { 202 206 if (value.equals(DIFFERENT)) … … public class TaggingPreset extends AbstractAction implements MapView.LayerChange 205 209 if (value.equals("")) 206 210 return " "; 207 211 208 StringBuilder res = new StringBuilder("<b>"); 209 if (display_value != null) { 210 res.append(display_value); 211 } else { 212 res.append(value); 213 } 212 final StringBuilder res = new StringBuilder("<b>"); 213 final String displ = Utils.firstNonNull(locale_display_value, tr(display_value), value); 214 res.append(displ); 214 215 res.append("</b>"); 215 if (short_description != null) { 216 final String descr = Utils.firstNonNull(locale_short_description, tr(short_description)); 217 if (descr != null) { 216 218 // wrap in table to restrict the text width 217 res.append("< br><table><td width='232'>(").append(short_description).append(")</td></table>");219 res.append("<div style=\"width:300px; padding:0 0 5px 5px\">").append(descr).append("</div>"); 218 220 } 219 221 return res.toString(); 220 222 } 221 223 222 public PresetListEntry(String value) { 223 this.value = value; 224 this.display_value = value; 224 public ImageIcon getIcon() { 225 return icon == null ? null : ImageProvider.getIfAvailable(icon); 226 } 227 228 public PresetListEntry() { 225 229 } 226 230 227 public PresetListEntry(String value , String display_value) {231 public PresetListEntry(String value) { 228 232 this.value = value; 229 this.display_value = display_value;230 233 } 231 234 232 235 // toString is mainly used to initialize the Editor … … public class TaggingPreset extends AbstractAction implements MapView.LayerChange 234 237 public String toString() { 235 238 if (value.equals(DIFFERENT)) 236 239 return DIFFERENT; 237 return display_value .replaceAll("<.*>", ""); // remove additional markup, e.g. <br>240 return display_value == null ? value : display_value.replaceAll("<.*>", ""); // remove additional markup, e.g. <br> 238 241 } 239 242 } 240 243 … … public class TaggingPreset extends AbstractAction implements MapView.LayerChange 430 433 public String use_last_as_default = "false"; 431 434 public boolean required = false; 432 435 433 protected List<String> short_description_list;434 436 protected JComponent component; 435 protected Map<String, PresetListEntry> lhm ;437 protected Map<String, PresetListEntry> lhm = new LinkedHashMap<String, PresetListEntry>(); 436 438 protected Usage usage; 437 439 protected Object originalValue; 438 440 … … public class TaggingPreset extends AbstractAction implements MapView.LayerChange 444 446 445 447 // find out if our key is already used in the selection. 446 448 usage = determineTextUsage(sel, key); 447 String def = default_;448 449 char delChar = ';';450 if (!delimiter.isEmpty()) {451 delChar = delimiter.charAt(0);452 }453 454 String[] value_array = splitEscaped(delChar, values);455 449 String[] display_array; 456 String[] short_descriptions_array = null;457 450 458 if (locale_display_values != null) { 459 display_array = splitEscaped(delChar, locale_display_values); 460 } else if (display_values != null) { 461 display_array = splitEscaped(delChar, display_values); 451 if (lhm.isEmpty()) { 452 display_array = initListEntriesFromAttributes(); 462 453 } else { 463 display_array = value_array; 454 if (values != null) { 455 System.err.println(tr("Warning in tagging preset \"{0}-{1}\": " 456 + "Ignoring ''{2}'' attribute as ''{3}'' elements are given.", 457 key, text, "values", "list_entry")); 458 } 459 if (display_values != null || locale_display_values != null) { 460 System.err.println(tr("Warning in tagging preset \"{0}-{1}\": " 461 + "Ignoring ''{2}'' attribute as ''{3}'' elements are given.", 462 key, text, "display_values", "list_entry")); 463 } 464 if (short_descriptions != null || locale_short_descriptions != null) { 465 System.err.println(tr("Warning in tagging preset \"{0}-{1}\": " 466 + "Ignoring ''{2}'' attribute as ''{3}'' elements are given.", 467 key, text, "short_descriptions", "list_entry")); 468 } 469 display_array = new String[lhm.values().size()]; 470 int i = 0; 471 for (PresetListEntry e : lhm.values()) { 472 display_array[i++] = e.display_value; 473 } 464 474 } 465 475 466 if (locale_ short_descriptions != null) {467 short_descriptions_array = splitEscaped(delChar, locale_short_descriptions);468 } else if (short_descriptions != null) {469 short_descriptions_array = splitEscaped(delChar, short_descriptions);470 } else if (short_description_list != null) {471 short_descriptions_array = short_description_list.toArray(new String[0]);476 if (locale_text == null) { 477 if (text_context != null) { 478 locale_text = trc(text_context, fixPresetString(text)); 479 } else { 480 locale_text = tr(fixPresetString(text)); 481 } 472 482 } 483 p.add(new JLabel(locale_text + ":"), GBC.std().insets(0, 0, 10, 0)); 484 485 addToPanelAnchor(p, default_, display_array); 473 486 474 if (!"false".equals(use_last_as_default) && def == null && lastValue.containsKey(key)) { 475 def = lastValue.get(key); 487 return true; 488 489 } 490 491 private String[] initListEntriesFromAttributes() { 492 char delChar = ';'; 493 if (!delimiter.isEmpty()) { 494 delChar = delimiter.charAt(0); 476 495 } 477 496 497 String[] value_array = splitEscaped(delChar, values); 498 499 final String displ = Utils.firstNonNull(locale_display_values, display_values); 500 String[] display_array = displ == null ? value_array : splitEscaped(delChar, displ); 501 502 final String descr = Utils.firstNonNull(locale_short_descriptions, short_descriptions); 503 String[] short_descriptions_array = descr == null ? null : splitEscaped(delChar, descr); 504 478 505 if (display_array.length != value_array.length) { 479 506 System.err.println(tr("Broken tagging preset \"{0}-{1}\" - number of items in ''display_values'' must be the same as in ''values''", key, text)); 480 507 display_array = value_array; … … public class TaggingPreset extends AbstractAction implements MapView.LayerChange 485 512 short_descriptions_array = null; 486 513 } 487 514 488 lhm = new LinkedHashMap<String, PresetListEntry>();489 515 if (!usage.hasUniqueValue() && !usage.unused()) { 490 516 lhm.put(DIFFERENT, new PresetListEntry(DIFFERENT)); 491 517 } 492 518 for (int i = 0; i < value_array.length; i++) { 493 PresetListEntry e = new PresetListEntry(value_array[i]); 494 e.display_value = (locale_display_values == null) 495 ? (values_context == null ? tr(fixPresetString(display_array[i])) 496 : trc(values_context, fixPresetString(display_array[i]))) : display_array[i]; 497 if (short_descriptions_array != null) { 498 e.short_description = locale_short_descriptions == null ? tr(fixPresetString(short_descriptions_array[i])) 499 : fixPresetString(short_descriptions_array[i]); 500 } 501 lhm.put(value_array[i], e); 502 } 503 504 if (locale_text == null) { 505 if (text_context != null) { 506 locale_text = trc(text_context, fixPresetString(text)); 507 } else { 508 locale_text = tr(fixPresetString(text)); 519 final PresetListEntry e = new PresetListEntry(value_array[i]); 520 e.locale_display_value = locale_display_values != null 521 ? display_array[i] 522 : trc(values_context, fixPresetString(display_array[i])); 523 if (short_descriptions_array != null) { 524 e.locale_short_description = locale_short_descriptions != null 525 ? short_descriptions_array[i] 526 : tr(fixPresetString(short_descriptions_array[i])); 509 527 } 528 lhm.put(value_array[i], e); 510 529 } 511 p.add(new JLabel(locale_text + ":"), GBC.std().insets(0, 0, 10, 0));512 513 addToPanelAnchor(p, def, display_array);514 515 return true;516 530 531 return display_array; 517 532 } 518 533 519 534 protected String getDisplayIfNull(String display) { … … public class TaggingPreset extends AbstractAction implements MapView.LayerChange 560 575 changedTags.add(new Tag(key, value)); 561 576 } 562 577 563 public void setShort_description(String s) { 564 if (short_description_list == null) { 565 short_description_list = new ArrayList<String>(); 578 public void addListEntry(PresetListEntry e) { 579 lhm.put(e.value, e); 580 } 581 582 public void addListEntries(Collection<PresetListEntry> e) { 583 for (PresetListEntry i : e) { 584 addListEntry(i); 566 585 } 567 short_description_list.add(tr(s));568 586 } 569 587 570 588 @Override … … public class TaggingPreset extends AbstractAction implements MapView.LayerChange 575 593 protected ListCellRenderer getListCellRenderer() { 576 594 return new ListCellRenderer() { 577 595 578 HtmlPanel lbl = new HtmlPanel();596 JLabel lbl = new JLabel(); 579 597 JComponent dummy = new JComponent() { 580 598 }; 581 599 … … public class TaggingPreset extends AbstractAction implements MapView.LayerChange 594 612 } 595 613 596 614 PresetListEntry item = (PresetListEntry) value; 597 String s = item.getListDisplay(); 598 lbl.setText(s); 615 lbl.setOpaque(true); 616 lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN)); 617 lbl.setText("<html>" + item.getListDisplay() + "</html>"); 618 lbl.setIcon(item.getIcon()); 599 619 lbl.setEnabled(list.isEnabled()); 600 620 // We do not want the editor to have the maximum height of all 601 621 // entries. Return a dummy with bogus height. … … public class TaggingPreset extends AbstractAction implements MapView.LayerChange 1140 1160 parser.map("label", Label.class); 1141 1161 parser.map("space", Space.class); 1142 1162 parser.map("key", Key.class); 1163 parser.map("list_entry", PresetListEntry.class); 1143 1164 LinkedList<TaggingPreset> all = new LinkedList<TaggingPreset>(); 1144 1165 TaggingPresetMenu lastmenu = null; 1145 1166 Roles lastrole = null; 1167 List<PresetListEntry> listEntries = new LinkedList<PresetListEntry>(); 1146 1168 1147 1169 if (validate) { 1148 1170 parser.startWithValidation(in, "http://josm.openstreetmap.de/tagging-preset-1.0", "resource://data/tagging-preset.xsd"); … … public class TaggingPreset extends AbstractAction implements MapView.LayerChange 1176 1198 all.add(tp); 1177 1199 lastrole = null; 1178 1200 } else { 1179 if (all.size() != 0) {1180 if (o instanceof Roles) {1181 all.getLast().data.add((Item) o);1201 if (all.size() != 0) { 1202 if (o instanceof Roles) { 1203 all.getLast().data.add((Item) o); 1182 1204 lastrole = (Roles) o; 1183 } 1184 else if(o instanceof Role) { 1185 if(lastrole == null) 1205 } else if (o instanceof Role) { 1206 if (lastrole == null) { 1186 1207 throw new SAXException(tr("Preset role element without parent")); 1208 } 1187 1209 lastrole.roles.add((Role) o); 1188 } 1189 else { 1190 all.getLast().data.add((Item)o); 1210 } else if (o instanceof PresetListEntry) { 1211 listEntries.add((PresetListEntry) o); 1212 } else { 1213 all.getLast().data.add((Item) o); 1214 if (o instanceof ComboMultiSelect) { 1215 ((ComboMultiSelect) o).addListEntries(listEntries); 1216 } 1217 listEntries = new LinkedList<PresetListEntry>(); 1191 1218 lastrole = null; 1192 1219 } 1193 1220 } else -
src/org/openstreetmap/josm/tools/Utils.java
diff --git a/src/org/openstreetmap/josm/tools/Utils.java b/src/org/openstreetmap/josm/tools/Utils.java index 8c26f43..2ea3c7d 100644
a b public class Utils { 62 62 return null; 63 63 } 64 64 65 public static <T> Collection<T> filter(Collection<? extends T> collection, Predicate<? super T> predicate) { 66 return new FilteredCollection<T>(collection, predicate); 67 } 65 public static <T> Collection<T> filter(Collection<? extends T> collection, Predicate<? super T> predicate) { 66 return new FilteredCollection<T>(collection, predicate); 67 } 68 69 public static <T> T firstNonNull(T... items) { 70 for (T i : items) { 71 if (i != null) { 72 return i; 73 } 74 } 75 return null; 76 } 68 77 69 78 /** 70 79 * Filter a collection by (sub)class.