001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.tagging.presets.items; 003 004import javax.swing.JPanel; 005 006import org.openstreetmap.josm.data.tagging.ac.AutoCompletionPriority; 007import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingTextField; 008import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList; 009import org.openstreetmap.josm.gui.widgets.JosmComboBox; 010import org.openstreetmap.josm.spi.preferences.Config; 011import org.openstreetmap.josm.tools.GBC; 012 013/** 014 * Combobox type. 015 */ 016public class Combo extends ComboMultiSelect { 017 018 /** 019 * Whether the combo box is editable, which means that the user can add other values as text. 020 * Default is {@code true}. If {@code false} it is readonly, which means that the user can only select an item in the list. 021 */ 022 public boolean editable = true; // NOSONAR 023 /** The length of the combo box (number of characters allowed). */ 024 public String length; // NOSONAR 025 026 protected JosmComboBox<PresetListEntry> combobox; 027 028 /** 029 * Constructs a new {@code Combo}. 030 */ 031 public Combo() { 032 delimiter = ","; 033 } 034 035 @Override 036 protected void addToPanelAnchor(JPanel p, String def, boolean presetInitiallyMatches) { 037 if (!usage.unused()) { 038 for (String s : usage.values) { 039 if (!lhm.containsKey(s)) { 040 lhm.put(s, new PresetListEntry(s)); 041 } 042 } 043 } 044 if (def != null && !lhm.containsKey(def)) { 045 lhm.put(def, new PresetListEntry(def)); 046 } 047 if (!lhm.containsKey("")) { 048 lhm.put("", new PresetListEntry("")); 049 } 050 051 combobox = new JosmComboBox<>(lhm.values().toArray(new PresetListEntry[lhm.size()])); 052 component = combobox; 053 combobox.setRenderer(getListCellRenderer()); 054 combobox.setEditable(editable); 055 combobox.reinitialize(lhm.values()); 056 AutoCompletingTextField tf = new AutoCompletingTextField(); 057 initAutoCompletionField(tf, key); 058 if (Config.getPref().getBoolean("taggingpreset.display-keys-as-hint", true)) { 059 tf.setHint(key); 060 } 061 if (length != null && !length.isEmpty()) { 062 tf.setMaxChars(Integer.valueOf(length)); 063 } 064 AutoCompletionList acList = tf.getAutoCompletionList(); 065 if (acList != null) { 066 acList.add(getDisplayValues(), AutoCompletionPriority.IS_IN_STANDARD); 067 } 068 combobox.setEditor(tf); 069 070 if (usage.hasUniqueValue()) { 071 // all items have the same value (and there were no unset items) 072 originalValue = lhm.get(usage.getFirst()); 073 combobox.setSelectedItem(originalValue); 074 } else if (def != null && usage.unused()) { 075 // default is set and all items were unset 076 if (!usage.hadKeys() || PROP_FILL_DEFAULT.get() || "force".equals(use_last_as_default)) { 077 // selected osm primitives are untagged or filling default feature is enabled 078 combobox.setSelectedItem(lhm.get(def).getDisplayValue(true)); 079 } else { 080 // selected osm primitives are tagged and filling default feature is disabled 081 combobox.setSelectedItem(""); 082 } 083 originalValue = lhm.get(DIFFERENT); 084 } else if (usage.unused()) { 085 // all items were unset (and so is default) 086 originalValue = lhm.get(""); 087 if (!presetInitiallyMatches && "force".equals(use_last_as_default) && LAST_VALUES.containsKey(key)) { 088 combobox.setSelectedItem(lhm.get(LAST_VALUES.get(key))); 089 } else { 090 combobox.setSelectedItem(originalValue); 091 } 092 } else { 093 originalValue = lhm.get(DIFFERENT); 094 combobox.setSelectedItem(originalValue); 095 } 096 p.add(combobox, GBC.eol().fill(GBC.HORIZONTAL)); 097 } 098 099 @Override 100 protected Object getSelectedItem() { 101 return combobox.getSelectedItem(); 102 } 103 104 @Override 105 protected String getDisplayIfNull() { 106 if (combobox.isEditable()) 107 return combobox.getEditor().getItem().toString(); 108 else 109 return null; 110 } 111}