001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.preferences.display; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.GridBagLayout; 007 008import javax.swing.BorderFactory; 009import javax.swing.Box; 010import javax.swing.JCheckBox; 011import javax.swing.JLabel; 012import javax.swing.JPanel; 013import javax.swing.JScrollPane; 014 015import org.openstreetmap.josm.actions.ExpertToggleAction; 016import org.openstreetmap.josm.data.preferences.BooleanProperty; 017import org.openstreetmap.josm.gui.autofilter.AutoFilterManager; 018import org.openstreetmap.josm.gui.autofilter.AutoFilterRule; 019import org.openstreetmap.josm.gui.layer.OsmDataLayer; 020import org.openstreetmap.josm.gui.preferences.PreferenceSetting; 021import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory; 022import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane; 023import org.openstreetmap.josm.gui.preferences.SubPreferenceSetting; 024import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting; 025import org.openstreetmap.josm.gui.util.GuiHelper; 026import org.openstreetmap.josm.gui.widgets.JosmComboBox; 027import org.openstreetmap.josm.spi.preferences.Config; 028import org.openstreetmap.josm.tools.GBC; 029 030/** 031 * Map drawing preferences. 032 */ 033public class DrawingPreference implements SubPreferenceSetting { 034 035 /** 036 * Factory used to create a new {@code DrawingPreference}. 037 */ 038 public static class Factory implements PreferenceSettingFactory { 039 @Override 040 public PreferenceSetting createPreferenceSetting() { 041 return new DrawingPreference(); 042 } 043 } 044 045 /** 046 * Property controlling whether to draw boundaries of downloaded data 047 * @since 14648 048 */ 049 public static final BooleanProperty SOURCE_BOUNDS_PROP = new BooleanProperty("draw.data.downloaded_area", true); 050 051 private GPXSettingsPanel gpxPanel; 052 private final JCheckBox directionHint = new JCheckBox(tr("Draw Direction Arrows")); 053 private final JCheckBox headArrow = new JCheckBox(tr("Only on the head of a way.")); 054 private final JCheckBox onewayArrow = new JCheckBox(tr("Draw oneway arrows.")); 055 private final JCheckBox segmentOrderNumber = new JCheckBox(tr("Draw segment order numbers")); 056 private final JCheckBox segmentOrderNumberOnSelectedWay = new JCheckBox(tr("Draw segment order numbers on selected way")); 057 private final JCheckBox sourceBounds = new JCheckBox(tr("Draw boundaries of downloaded data")); 058 private final JCheckBox virtualNodes = new JCheckBox(tr("Draw virtual nodes in select mode")); 059 private final JCheckBox inactive = new JCheckBox(tr("Draw inactive layers in other color")); 060 private final JCheckBox discardableKeys = new JCheckBox(tr("Display discardable keys")); 061 private final JCheckBox autoFilters = new JCheckBox(tr("Use auto filters")); 062 private final JLabel lblRule = new JLabel(tr("Rule")); 063 private final JosmComboBox<AutoFilterRule> autoFilterRules = new JosmComboBox<>( 064 AutoFilterManager.getInstance().getAutoFilterRules().toArray(new AutoFilterRule[] {})); 065 066 // Options that affect performance 067 private final JCheckBox useHighlighting = new JCheckBox(tr("Highlight target ways and nodes")); 068 private final JCheckBox drawHelperLine = new JCheckBox(tr("Draw rubber-band helper line")); 069 private final JCheckBox useAntialiasing = new JCheckBox(tr("Smooth map graphics (antialiasing)")); 070 private final JCheckBox useWireframeAntialiasing = new JCheckBox(tr("Smooth map graphics in wireframe mode (antialiasing)")); 071 private final JCheckBox outlineOnly = new JCheckBox(tr("Draw only outlines of areas")); 072 private final JCheckBox hideLabelsWhileDragging = new JCheckBox(tr("Hide labels while dragging the map")); 073 074 @Override 075 public void addGui(PreferenceTabbedPane gui) { 076 gpxPanel = new GPXSettingsPanel(); 077 gui.addValidationListener(gpxPanel); 078 JPanel panel = gpxPanel; 079 080 JScrollPane scrollpane = new JScrollPane(panel); 081 scrollpane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); 082 GuiHelper.setDefaultIncrement(scrollpane); 083 gui.getDisplayPreference().addSubTab(this, tr("GPS Points"), scrollpane); 084 panel = new JPanel(new GridBagLayout()); 085 panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 086 087 // directionHint 088 directionHint.addActionListener(e -> { 089 if (directionHint.isSelected()) { 090 headArrow.setSelected(Config.getPref().getBoolean("draw.segment.head_only", false)); 091 } else { 092 headArrow.setSelected(false); 093 } 094 headArrow.setEnabled(directionHint.isSelected()); 095 }); 096 directionHint.setToolTipText(tr("Draw direction hints for way segments.")); 097 directionHint.setSelected(Config.getPref().getBoolean("draw.segment.direction", false)); 098 099 // only on the head of a way 100 headArrow.setToolTipText(tr("Only on the head of a way.")); 101 headArrow.setSelected(Config.getPref().getBoolean("draw.segment.head_only", false)); 102 headArrow.setEnabled(directionHint.isSelected()); 103 104 // draw oneway arrows 105 onewayArrow.setToolTipText(tr("Draw arrows in the direction of oneways and other directed features.")); 106 onewayArrow.setSelected(Config.getPref().getBoolean("draw.oneway", true)); 107 108 // segment order number 109 segmentOrderNumber.setToolTipText(tr("Draw the order numbers of all segments within their way.")); 110 segmentOrderNumber.setSelected(Config.getPref().getBoolean("draw.segment.order_number", false)); 111 segmentOrderNumberOnSelectedWay.setToolTipText(tr("Draw the order numbers of all segments within their way.")); 112 segmentOrderNumberOnSelectedWay.setSelected(Config.getPref().getBoolean("draw.segment.order_number.on_selected", false)); 113 114 // downloaded area 115 sourceBounds.setToolTipText(tr("Draw the boundaries of data loaded from the server.")); 116 sourceBounds.setSelected(SOURCE_BOUNDS_PROP.get()); 117 118 // virtual nodes 119 virtualNodes.setToolTipText(tr("Draw virtual nodes in select mode for easy way modification.")); 120 virtualNodes.setSelected(Config.getPref().getInt("mappaint.node.virtual-size", 8) != 0); 121 122 // background layers in inactive color 123 inactive.setToolTipText(tr("Draw the inactive data layers in a different color.")); 124 inactive.setSelected(Config.getPref().getBoolean("draw.data.inactive_color", true)); 125 126 // antialiasing 127 useAntialiasing.setToolTipText(tr("Apply antialiasing to the map view resulting in a smoother appearance.")); 128 useAntialiasing.setSelected(Config.getPref().getBoolean("mappaint.use-antialiasing", true)); 129 130 // wireframe mode antialiasing 131 useWireframeAntialiasing.setToolTipText(tr("Apply antialiasing to the map view in wireframe mode resulting in a smoother appearance.")); 132 useWireframeAntialiasing.setSelected(Config.getPref().getBoolean("mappaint.wireframe.use-antialiasing", false)); 133 134 // highlighting 135 useHighlighting.setToolTipText(tr("Hightlight target nodes and ways while drawing or selecting")); 136 useHighlighting.setSelected(Config.getPref().getBoolean("draw.target-highlight", true)); 137 138 drawHelperLine.setToolTipText(tr("Draw rubber-band helper line")); 139 drawHelperLine.setSelected(Config.getPref().getBoolean("draw.helper-line", true)); 140 141 // outlineOnly 142 outlineOnly.setToolTipText(tr("This option suppresses the filling of areas, overriding anything specified in the selected style.")); 143 outlineOnly.setSelected(Config.getPref().getBoolean("draw.data.area_outline_only", false)); 144 145 // hideLabelsWhileDragging 146 hideLabelsWhileDragging.setToolTipText(tr("This option hides the textual labels of OSM objects while dragging the map.")); 147 hideLabelsWhileDragging.setSelected(OsmDataLayer.PROPERTY_HIDE_LABELS_WHILE_DRAGGING.get()); 148 149 // discardable keys 150 discardableKeys.setToolTipText(tr("Display keys which have been deemed uninteresting to the point that they can be silently removed.")); 151 discardableKeys.setSelected(Config.getPref().getBoolean("display.discardable-keys", false)); 152 153 // auto filters 154 autoFilters.setToolTipText(tr("Display buttons to automatically filter numeric values of a predefined tag")); 155 autoFilters.setSelected(AutoFilterManager.PROP_AUTO_FILTER_ENABLED.get()); 156 autoFilters.addActionListener(e -> { 157 lblRule.setEnabled(autoFilters.isSelected()); 158 autoFilterRules.setEnabled(autoFilters.isSelected()); 159 }); 160 autoFilterRules.setToolTipText("Rule defining which tag will provide automatic filters, below a certain zoom level"); 161 autoFilterRules.setSelectedItem(AutoFilterManager.getInstance().getAutoFilterRule(AutoFilterManager.PROP_AUTO_FILTER_RULE.get())); 162 163 JLabel performanceLabel = new JLabel(tr("Options that affect drawing performance")); 164 165 panel.add(new JLabel(tr("Segment drawing options")), 166 GBC.eop().insets(5, 10, 0, 0)); 167 panel.add(directionHint, GBC.eop().insets(20, 0, 0, 0)); 168 panel.add(headArrow, GBC.eop().insets(40, 0, 0, 0)); 169 panel.add(onewayArrow, GBC.eop().insets(20, 0, 0, 0)); 170 panel.add(segmentOrderNumber, GBC.eop().insets(20, 0, 0, 0)); 171 panel.add(segmentOrderNumberOnSelectedWay, GBC.eop().insets(20, 0, 0, 0)); 172 173 panel.add(new JLabel(tr("Select and draw mode options")), 174 GBC.eop().insets(5, 10, 0, 0)); 175 panel.add(virtualNodes, GBC.eop().insets(20, 0, 0, 0)); 176 panel.add(drawHelperLine, GBC.eop().insets(20, 0, 0, 0)); 177 178 panel.add(performanceLabel, GBC.eop().insets(5, 10, 0, 0)); 179 panel.add(useAntialiasing, GBC.eop().insets(20, 0, 0, 0)); 180 panel.add(useWireframeAntialiasing, GBC.eop().insets(20, 0, 0, 0)); 181 panel.add(useHighlighting, GBC.eop().insets(20, 0, 0, 0)); 182 panel.add(outlineOnly, GBC.eol().insets(20, 0, 0, 0)); 183 panel.add(hideLabelsWhileDragging, GBC.eol().insets(20, 0, 0, 0)); 184 185 panel.add(new JLabel(tr("Other options")), 186 GBC.eop().insets(5, 10, 0, 0)); 187 panel.add(sourceBounds, GBC.eop().insets(20, 0, 0, 0)); 188 panel.add(inactive, GBC.eop().insets(20, 0, 0, 0)); 189 panel.add(discardableKeys, GBC.eop().insets(20, 0, 0, 0)); 190 panel.add(autoFilters, GBC.eop().insets(20, 0, 0, 0)); 191 panel.add(lblRule, GBC.std().insets(40, 0, 0, 0)); 192 panel.add(autoFilterRules, GBC.eop().fill(GBC.HORIZONTAL).insets(5, 0, 0, 0)); 193 194 ExpertToggleAction.addVisibilitySwitcher(performanceLabel); 195 ExpertToggleAction.addVisibilitySwitcher(useAntialiasing); 196 ExpertToggleAction.addVisibilitySwitcher(useWireframeAntialiasing); 197 ExpertToggleAction.addVisibilitySwitcher(useHighlighting); 198 ExpertToggleAction.addVisibilitySwitcher(outlineOnly); 199 ExpertToggleAction.addVisibilitySwitcher(hideLabelsWhileDragging); 200 ExpertToggleAction.addVisibilitySwitcher(discardableKeys); 201 202 panel.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.BOTH)); 203 scrollpane = new JScrollPane(panel); 204 scrollpane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); 205 GuiHelper.setDefaultIncrement(scrollpane); 206 gui.getDisplayPreference().addSubTab(this, tr("OSM Data"), scrollpane); 207 } 208 209 @Override 210 public boolean ok() { 211 boolean restart = gpxPanel.savePreferences(); 212 OsmDataLayer.PROPERTY_HIDE_LABELS_WHILE_DRAGGING.put(hideLabelsWhileDragging.isSelected()); 213 Config.getPref().putBoolean("draw.data.area_outline_only", outlineOnly.isSelected()); 214 Config.getPref().putBoolean("draw.segment.direction", directionHint.isSelected()); 215 Config.getPref().putBoolean("draw.segment.head_only", headArrow.isSelected()); 216 Config.getPref().putBoolean("draw.oneway", onewayArrow.isSelected()); 217 Config.getPref().putBoolean("draw.segment.order_number", segmentOrderNumber.isSelected()); 218 Config.getPref().putBoolean("draw.segment.order_number.on_selected", segmentOrderNumberOnSelectedWay.isSelected()); 219 SOURCE_BOUNDS_PROP.put(sourceBounds.isSelected()); 220 Config.getPref().putBoolean("draw.data.inactive_color", inactive.isSelected()); 221 Config.getPref().putBoolean("mappaint.use-antialiasing", useAntialiasing.isSelected()); 222 Config.getPref().putBoolean("mappaint.wireframe.use-antialiasing", useWireframeAntialiasing.isSelected()); 223 Config.getPref().putBoolean("draw.target-highlight", useHighlighting.isSelected()); 224 Config.getPref().putBoolean("draw.helper-line", drawHelperLine.isSelected()); 225 Config.getPref().putBoolean("display.discardable-keys", discardableKeys.isSelected()); 226 AutoFilterManager.PROP_AUTO_FILTER_ENABLED.put(autoFilters.isSelected()); 227 AutoFilterManager.PROP_AUTO_FILTER_RULE.put(((AutoFilterRule) autoFilterRules.getSelectedItem()).getKey()); 228 int vn = Config.getPref().getInt("mappaint.node.virtual-size", 8); 229 if (virtualNodes.isSelected()) { 230 if (vn < 1) { 231 vn = 8; 232 } 233 } else { 234 vn = 0; 235 } 236 Config.getPref().putInt("mappaint.node.virtual-size", vn); 237 return restart; 238 } 239 240 @Override 241 public boolean isExpert() { 242 return false; 243 } 244 245 @Override 246 public TabPreferenceSetting getTabPreferenceSetting(final PreferenceTabbedPane gui) { 247 return gui.getDisplayPreference(); 248 } 249}