I wrote:
> Yes, I've got it. I'll post a new patch tomorrow.
Here we go. The changes since last time:
- Can be turned off by setting the advanced parameter
"tag-correction.reverse-way" to "false".
- Updated the dialog by adding a multiline label component, that I took
from a Java forum, to let the text wrap. I hope that's ok.
- The changes in the dialog are now highlighted in bold.
- The properties update now. I needed to add a public reference to
MapFrame in order to access the properties dialog to do that.
And Dirk (and everyboy else), if you've got any more remarks or
suggestions, please do go ahead.
Robin
Index: src/org/openstreetmap/josm/actions/ReverseWayAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/ReverseWayAction.java (revision 728)
+++ src/org/openstreetmap/josm/actions/ReverseWayAction.java (working copy)
@@ -15,6 +15,7 @@
import org.openstreetmap.josm.command.ChangeCommand;
import org.openstreetmap.josm.command.Command;
import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.corrector.ReverseWayTagCorrector;
import org.openstreetmap.josm.data.osm.Relation;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -46,13 +47,20 @@
tr("Please select at least one way."));
return;
}
- Collection<Command> c = new LinkedList<Command>();
- for (Way w : sel) {
- Way wnew = new Way(w);
+
+ boolean propertiesUpdated = false;
+ ReverseWayTagCorrector reverseWayTagCorrector = new
ReverseWayTagCorrector();
+ Collection<Command> c = new LinkedList<Command>();
+ for (Way w : sel) {
+ Way wnew = new Way(w);
Collections.reverse(wnew.nodes);
- c.add(new ChangeCommand(w, wnew));
- }
- Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c));
- Main.map.repaint();
+ if (Main.pref.getBoolean("tag-correction.reverse-way",
true))
+ propertiesUpdated =
reverseWayTagCorrector.execute(wnew) || propertiesUpdated;
+ c.add(new ChangeCommand(w, wnew));
+ }
+ Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"),
c));
+ if (propertiesUpdated)
+
Main.map.getPropertiesDialog().selectionChanged(Main.ds.getSelected());
+ Main.map.repaint();
}
}
Index: src/org/openstreetmap/josm/corrector/TagCorrection.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrection.java (revision 0)
+++ src/org/openstreetmap/josm/corrector/TagCorrection.java (revision 0)
@@ -0,0 +1,41 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+public class TagCorrection {
+
+ private final String oldKey;
+ private final String newKey;
+ private final String oldValue;
+ private final String newValue;
+
+ public TagCorrection(String oldKey, String oldValue, String newKey,
String newValue) {
+ this.oldKey = oldKey;
+ this.oldValue = oldValue;
+ this.newKey = newKey;
+ this.newValue = newValue;
+ }
+
+ public String getOldKey() {
+ return oldKey;
+ }
+
+ public String getOldValue() {
+ return oldValue;
+ }
+
+ public String getNewKey() {
+ return newKey;
+ }
+
+ public String getNewValue() {
+ return newValue;
+ }
+
+ public boolean isKeyChanged() {
+ return !newKey.equals(oldKey);
+ }
+
+ public boolean isValueChanged() {
+ return !newValue.equals(oldValue);
+ }
+}
Index: src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
===================================================================
--- src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
(revision 0)
+++ src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
(revision 0)
@@ -0,0 +1,63 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.openstreetmap.josm.data.osm.OsmUtils;
+import org.openstreetmap.josm.data.osm.Way;
+
+public class ReverseWayTagCorrector extends TagCorrector<Way> {
+
+ private static final Pattern leftRightStartRegex = Pattern.compile(
+ "^(left|right):.*", Pattern.CASE_INSENSITIVE);
+
+ private static final Pattern leftRightEndRegex = Pattern.compile(
+ ".*:(left|right)$", Pattern.CASE_INSENSITIVE);
+
+ @Override public boolean execute(Way way) {
+
+ ArrayList<TagCorrection> tagCorrections = new
ArrayList<TagCorrection>();
+
+ for (String key : way.keySet()) {
+ String newKey = key;
+ String value = way.get(key);
+ String newValue = value;
+
+ if (key.equals("oneway")) {
+ if (value.equals("-1"))
+ newValue = OsmUtils.trueval;
+ else {
+ Boolean boolValue =
OsmUtils.getOsmBoolean(value);
+ if (boolValue != null &&
boolValue.booleanValue()) {
+ newValue = "-1";
+ }
+ }
+ } else {
+ Matcher m = leftRightStartRegex.matcher(key);
+ if (!m.matches())
+ m = leftRightEndRegex.matcher(key);
+
+ if (m.matches()) {
+ String leftRight =
m.group(1).toLowerCase();
+
+ newKey = key.substring(0,
m.start(1)).concat(
+ leftRight.equals("left") ?
"right" : "left")
+
.concat(key.substring(m.end(1)));
+ }
+ }
+
+ if (key != newKey || value != newValue)
+ tagCorrections.add(new TagCorrection(key,
value, newKey,
+ newValue));
+ }
+
+ return applyCorrections(tagCorrections, way,
+ tr("When reverting this way, following changes to the "
+ + "properties are suggested, in order to
maintain "
+ + "data consistency."));
+ }
+}
Index: src/org/openstreetmap/josm/corrector/TagCorrectionTable.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrectionTable.java
(revision 0)
+++ src/org/openstreetmap/josm/corrector/TagCorrectionTable.java
(revision 0)
@@ -0,0 +1,67 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import java.awt.Dimension;
+import java.util.List;
+
+import javax.swing.JTable;
+import javax.swing.JLabel;
+import javax.swing.table.TableCellRenderer;
+import java.awt.Component;
+import java.awt.Font;
+
+public class TagCorrectionTable extends JTable {
+
+ public class BoldRenderer extends JLabel implements TableCellRenderer {
+
+ public Component getTableCellRendererComponent(JTable table,
+ Object value, boolean isSelected, boolean hasFocus, int
row,
+ int column) {
+
+ Font f = getFont();
+ setFont(new Font(f.getName(), f.getStyle() | Font.BOLD,
f.getSize()));
+
+ setText((String)value);
+
+ return this;
+ }
+ }
+
+ private static TableCellRenderer boldRenderer = null;
+
+ private static TagCorrectionTableModel tagCorrectionTableModel;
+
+ public static TagCorrectionTable create(List<TagCorrection>
tagCorrections) {
+
+ tagCorrectionTableModel = new
TagCorrectionTableModel(tagCorrections);
+ TagCorrectionTable table = new TagCorrectionTable(
+ tagCorrectionTableModel);
+ int lines = tagCorrections.size() > 10 ? 10 :
tagCorrections.size();
+ table.setPreferredScrollableViewportSize(new Dimension(400,
lines * table.getRowHeight()));
+ table.getColumnModel().getColumn(4).setPreferredWidth(40);
+ table.setRowSelectionAllowed(false);
+
+ return table;
+ }
+
+ public TableCellRenderer getCellRenderer(int row, int column) {
+ TagCorrection tagCorrection =
tagCorrectionTableModel.tagCorrections
+ .get(row);
+ if ((column == 2 && tagCorrection.isKeyChanged())
+ || (column == 3 && tagCorrection.isValueChanged())) {
+ if (boldRenderer == null)
+ boldRenderer = new BoldRenderer();
+ return boldRenderer;
+ }
+ return super.getCellRenderer(row, column);
+ }
+
+ private TagCorrectionTable(TagCorrectionTableModel
tagCorrectionTableModel) {
+ super(tagCorrectionTableModel);
+ }
+
+ public TagCorrectionTableModel getTagCorrectionTableModel() {
+ return tagCorrectionTableModel;
+ }
+
+}
Index: src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java
(revision 0)
+++ src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java
(revision 0)
@@ -0,0 +1,85 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.table.AbstractTableModel;
+
+public class TagCorrectionTableModel extends AbstractTableModel {
+
+ List<TagCorrection> tagCorrections;
+
+ private boolean[] apply;
+
+ public TagCorrectionTableModel(List<TagCorrection> tagCorrections) {
+ this.tagCorrections = tagCorrections;
+ apply = new boolean[this.tagCorrections.size()];
+ Arrays.fill(apply, true);
+ }
+
+ @Override public int getColumnCount() {
+ return 5;
+ }
+
+ @Override public Class<?> getColumnClass(int columnIndex) {
+ if (columnIndex == 4)
+ return Boolean.class;
+ return String.class;
+ }
+
+ @Override public String getColumnName(int colIndex) {
+ switch (colIndex) {
+ case 0:
+ return tr("Old key");
+ case 1:
+ return tr("Old value");
+ case 2:
+ return tr("New key");
+ case 3:
+ return tr("New value");
+ case 4:
+ return tr("Apply?");
+ }
+ return null;
+ }
+
+ @Override public int getRowCount() {
+ return tagCorrections.size();
+ }
+
+ @Override public Object getValueAt(int rowIndex, int colIndex) {
+
+ TagCorrection tagCorrection = tagCorrections.get(rowIndex);
+
+ switch (colIndex) {
+ case 0:
+ return tagCorrection.getOldKey();
+ case 1:
+ return tagCorrection.getOldValue();
+ case 2:
+ return tagCorrection.getNewKey();
+ case 3:
+ return tagCorrection.getNewValue();
+ case 4:
+ return apply[rowIndex];
+ }
+ return null;
+ }
+
+ @Override public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return columnIndex == 4;
+ }
+
+ @Override public void setValueAt(Object aValue, int rowIndex,
+ int columnIndex) {
+ if (columnIndex == 4 && aValue instanceof Boolean)
+ apply[rowIndex] = (Boolean)aValue;
+ }
+
+ public boolean getApply(int i) {
+ return apply[i];
+ }
+}
Index: src/org/openstreetmap/josm/corrector/TagCorrector.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrector.java (revision 0)
+++ src/org/openstreetmap/josm/corrector/TagCorrector.java (revision 0)
@@ -0,0 +1,67 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Dimension;
+import java.awt.GridBagLayout;
+import java.util.List;
+
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.JMultilineLabel;
+import org.openstreetmap.josm.tools.GBC;
+
+public abstract class TagCorrector<P extends OsmPrimitive> {
+
+ public abstract boolean execute(P primitive);
+
+ protected boolean applyCorrections(List<TagCorrection> tagCorrections,
+ P primitive, String description) {
+
+ boolean updated = false;
+
+ if (tagCorrections != null && tagCorrections.size() > 0) {
+
+ final TagCorrectionTable table = TagCorrectionTable
+ .create(tagCorrections);
+ final JScrollPane scrollPane = new JScrollPane(table);
+
+ final JPanel p = new JPanel(new GridBagLayout());
+
+ final JMultilineLabel label1 = new
JMultilineLabel(description);
+ label1.setMaxWidth(400);
+ p.add(label1, GBC.eop());
+
+ final JMultilineLabel label2 = new
JMultilineLabel(tr("Please select which property changes you want to apply."));
+ label2.setMaxWidth(400);
+ p.add(label2, GBC.eop());
+ p.add(scrollPane, GBC.eol());
+
+ int answer = JOptionPane.showConfirmDialog(Main.parent,
p,
+ tr("Automatic tag correction"),
+ JOptionPane.OK_CANCEL_OPTION);
+
+ if (answer == JOptionPane.OK_OPTION) {
+ for (int i = 0; i < tagCorrections.size(); i++)
{
+ if
(table.getTagCorrectionTableModel().getApply(i)) {
+ TagCorrection tagCorrection =
tagCorrections.get(i);
+ if
(tagCorrection.isKeyChanged())
+
primitive.remove(tagCorrection.getOldKey());
+
primitive.put(tagCorrection.getNewKey(), tagCorrection
+ .getNewValue());
+ updated = true;
+ }
+ }
+ }
+ }
+
+ return updated;
+ }
+
+}
Index: src/org/openstreetmap/josm/gui/JMultilineLabel.java
===================================================================
--- src/org/openstreetmap/josm/gui/JMultilineLabel.java (revision 0)
+++ src/org/openstreetmap/josm/gui/JMultilineLabel.java (revision 0)
@@ -0,0 +1,115 @@
+// License: GPL. For details, see LICENSE file.
+
+// This class was taken from
+// http://forum.java.sun.com/thread.jspa?threadID=459705&messageID=2104021
+// - Removed hardcoded margin
+// - Added constructor
+
+package org.openstreetmap.josm.gui;
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineBreakMeasurer;
+import java.awt.font.TextAttribute;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.awt.font.TextLayout;
+
+import javax.swing.JComponent;
+
+
+public class JMultilineLabel extends JComponent {
+ private String text;
+ private int maxWidth = Integer.MAX_VALUE;
+ private boolean justify;
+ private final FontRenderContext frc = new FontRenderContext(null, false,
false);
+
+ public JMultilineLabel(String description) {
+ super();
+ setText(description);
+ }
+
+ private void morph() {
+ revalidate();
+ repaint();
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ String old = this.text;
+ this.text = text;
+ firePropertyChange("text", old, this.text);
+ if ((old == null) ? text!=null : !old.equals(text))
+ morph();
+ }
+
+ public int getMaxWidth() {
+ return maxWidth;
+ }
+
+ public void setMaxWidth(int maxWidth) {
+ if (maxWidth <= 0)
+ throw new IllegalArgumentException();
+ int old = this.maxWidth;
+ this.maxWidth = maxWidth;
+ firePropertyChange("maxWidth", old, this.maxWidth);
+ if (old != this.maxWidth)
+ morph();
+ }
+
+ public boolean isJustified() {
+ return justify;
+ }
+
+ public void setJustified(boolean justify) {
+ boolean old = this.justify;
+ this.justify = justify;
+ firePropertyChange("justified", old, this.justify);
+ if (old != this.justify)
+ repaint();
+ }
+
+ public Dimension getPreferredSize() {
+ return paintOrGetSize(null, getMaxWidth());
+ }
+
+ public Dimension getMinimumSize() {
+ return getPreferredSize();
+ }
+
+ protected void paintComponent(Graphics g) {
+ super.paintComponent(g);
+ paintOrGetSize((Graphics2D)g, getWidth());
+ }
+
+ private Dimension paintOrGetSize(Graphics2D g, int width) {
+ Insets insets = getInsets();
+ width -= insets.left + insets.right;
+ float w = insets.left + insets.right;
+ float x = insets.left, y=insets.top;
+ if (width > 0 && text != null && text.length() > 0) {
+ AttributedString as = new AttributedString(getText());
+ as.addAttribute(TextAttribute.FONT, getFont());
+ AttributedCharacterIterator aci = as.getIterator();
+ LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
+ float max = 0;
+ while (lbm.getPosition() < aci.getEndIndex()) {
+ TextLayout textLayout = lbm.nextLayout(width);
+ if (g != null && isJustified() &&
textLayout.getVisibleAdvance() > 0.80 * width)
+ textLayout = textLayout.getJustifiedLayout(width);
+ if (g != null)
+ textLayout.draw(g, x, y + textLayout.getAscent());
+ y += textLayout.getDescent() + textLayout.getLeading() +
textLayout.getAscent();
+ max = Math.max(max, textLayout.getVisibleAdvance());
+ }
+ w += max;
+ }
+ return new Dimension((int)Math.ceil(w), (int)Math.ceil(y) +
insets.bottom);
+ }
+}
\ No newline at end of file
Index: src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapFrame.java (revision 728)
+++ src/org/openstreetmap/josm/gui/MapFrame.java (working copy)
@@ -66,6 +66,7 @@
public final ButtonGroup toolGroup = new ButtonGroup();
+ private PropertiesDialog propertiesDialog;
public MapFrame() {
setSize(400,400);
@@ -94,7 +95,7 @@
toggleDialogs.setLayout(new BoxLayout(toggleDialogs,
BoxLayout.Y_AXIS));
addToggleDialog(new LayerListDialog(this));
- addToggleDialog(new PropertiesDialog(this));
+ addToggleDialog(propertiesDialog = new PropertiesDialog(this));
addToggleDialog(new HistoryDialog());
addToggleDialog(new SelectionListDialog());
addToggleDialog(new UserListDialog());
@@ -187,4 +188,8 @@
if (statusLine != null)
panel.add(statusLine, BorderLayout.SOUTH);
}
+
+ public final PropertiesDialog getPropertiesDialog() {
+ return propertiesDialog;
+ }
}
_______________________________________________
josm-dev mailing list
[email protected]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev