001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.tagging.presets.items; 003 004import java.util.ArrayList; 005import java.util.Arrays; 006import java.util.Collection; 007import java.util.List; 008 009import javax.swing.JPanel; 010 011import org.openstreetmap.josm.data.osm.OsmPrimitive; 012import org.openstreetmap.josm.data.osm.OsmUtils; 013import org.openstreetmap.josm.data.osm.Tag; 014import org.openstreetmap.josm.gui.widgets.QuadStateCheckBox; 015import org.openstreetmap.josm.tools.GBC; 016 017/** 018 * Checkbox type. 019 */ 020public class Check extends KeyedItem { 021 022 /** The localized version of {@link #text}. */ 023 public String locale_text; // NOSONAR 024 /** the value to set when checked (default is "yes") */ 025 public String value_on = OsmUtils.TRUE_VALUE; // NOSONAR 026 /** the value to set when unchecked (default is "no") */ 027 public String value_off = OsmUtils.FALSE_VALUE; // NOSONAR 028 /** whether the off value is disabled in the dialog, i.e., only unset or yes are provided */ 029 public boolean disable_off; // NOSONAR 030 /** "on" or "off" or unset (default is unset) */ 031 public String default_; // only used for tagless objects // NOSONAR 032 033 private QuadStateCheckBox check; 034 private QuadStateCheckBox.State initialState; 035 private Boolean def; 036 037 @Override 038 public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel, boolean presetInitiallyMatches) { 039 040 // find out if our key is already used in the selection. 041 final Usage usage = determineBooleanUsage(sel, key); 042 final String oneValue = usage.values.isEmpty() ? null : usage.values.last(); 043 def = "on".equals(default_) ? Boolean.TRUE : "off".equals(default_) ? Boolean.FALSE : null; 044 045 if (locale_text == null) { 046 locale_text = getLocaleText(text, text_context, null); 047 } 048 049 if (usage.values.size() < 2 && (oneValue == null || value_on.equals(oneValue) || value_off.equals(oneValue))) { 050 if (def != null && !PROP_FILL_DEFAULT.get()) { 051 // default is set and filling default values feature is disabled - check if all primitives are untagged 052 for (OsmPrimitive s : sel) { 053 if (s.hasKeys()) { 054 def = null; 055 } 056 } 057 } 058 059 // all selected objects share the same value which is either true or false or unset, 060 // we can display a standard check box. 061 initialState = value_on.equals(oneValue) || Boolean.TRUE.equals(def) 062 ? QuadStateCheckBox.State.SELECTED 063 : value_off.equals(oneValue) || Boolean.FALSE.equals(def) 064 ? QuadStateCheckBox.State.NOT_SELECTED 065 : QuadStateCheckBox.State.UNSET; 066 067 } else { 068 def = null; 069 // the objects have different values, or one or more objects have something 070 // else than true/false. we display a quad-state check box 071 // in "partial" state. 072 initialState = QuadStateCheckBox.State.PARTIAL; 073 } 074 075 final List<QuadStateCheckBox.State> allowedStates = new ArrayList<>(4); 076 if (QuadStateCheckBox.State.PARTIAL == initialState) 077 allowedStates.add(QuadStateCheckBox.State.PARTIAL); 078 allowedStates.add(QuadStateCheckBox.State.SELECTED); 079 if (!disable_off || value_off.equals(oneValue)) 080 allowedStates.add(QuadStateCheckBox.State.NOT_SELECTED); 081 allowedStates.add(QuadStateCheckBox.State.UNSET); 082 check = new QuadStateCheckBox(locale_text, initialState, 083 allowedStates.toArray(new QuadStateCheckBox.State[0])); 084 check.setPropertyText(key); 085 check.setState(check.getState()); // to update the tooltip text 086 087 p.add(check, GBC.eol()); // Do not fill, see #15104 088 return true; 089 } 090 091 @Override 092 public void addCommands(List<Tag> changedTags) { 093 // if the user hasn't changed anything, don't create a command. 094 if (def == null && check.getState() == initialState) return; 095 096 // otherwise change things according to the selected value. 097 changedTags.add(new Tag(key, 098 check.getState() == QuadStateCheckBox.State.SELECTED ? value_on : 099 check.getState() == QuadStateCheckBox.State.NOT_SELECTED ? value_off : 100 null)); 101 } 102 103 @Override 104 public MatchType getDefaultMatch() { 105 return MatchType.NONE; 106 } 107 108 @Override 109 public Collection<String> getValues() { 110 return disable_off ? Arrays.asList(value_on) : Arrays.asList(value_on, value_off); 111 } 112 113 @Override 114 public String toString() { 115 return "Check [" 116 + (locale_text != null ? "locale_text=" + locale_text + ", " : "") 117 + (value_on != null ? "value_on=" + value_on + ", " : "") 118 + (value_off != null ? "value_off=" + value_off + ", " : "") 119 + "default_=" + default_ + ", " 120 + (check != null ? "check=" + check + ", " : "") 121 + (initialState != null ? "initialState=" + initialState 122 + ", " : "") + "def=" + def + ']'; 123 } 124}