Ticket #13050: patch-fix-13050.patch

File patch-fix-13050.patch, 13.9 KB (added by michael2402, 4 years ago)
  • new file src/org/openstreetmap/josm/gui/datatransfer/TagTransferable.java

    diff --git a/src/org/openstreetmap/josm/gui/datatransfer/TagTransferable.java b/src/org/openstreetmap/josm/gui/datatransfer/TagTransferable.java
    new file mode 100644
    index 0000000..b13f856
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.datatransfer;
     3
     4import java.awt.datatransfer.DataFlavor;
     5import java.awt.datatransfer.Transferable;
     6import java.awt.datatransfer.UnsupportedFlavorException;
     7import java.io.IOException;
     8import java.util.Map.Entry;
     9import java.util.stream.Stream;
     10
     11import org.openstreetmap.josm.gui.datatransfer.data.TagTransferData;
     12
     13/**
     14 * This is a transferable that only transfers the tags.
     15 * @author Michael Zangl
     16 * @since xxx
     17 */
     18public class TagTransferable implements Transferable {
     19    private TagTransferData data;
     20
     21    /**
     22     * Transfer the tag transfer data.
     23     * @param data The data.
     24     */
     25    public TagTransferable(TagTransferData data) {
     26        this.data = data;
     27    }
     28
     29    @Override
     30    public DataFlavor[] getTransferDataFlavors() {
     31        return new DataFlavor[] { TagTransferData.FLAVOR, DataFlavor.stringFlavor };
     32    }
     33
     34    @Override
     35    public boolean isDataFlavorSupported(DataFlavor flavor) {
     36        return Stream.of(getTransferDataFlavors()).anyMatch(f -> f.equals(flavor));
     37    }
     38
     39    @Override
     40    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
     41        if (DataFlavor.stringFlavor.equals(flavor)) {
     42            return getStringData();
     43        } else if (TagTransferData.FLAVOR.equals(flavor)) {
     44            return data;
     45        } else {
     46            throw new UnsupportedFlavorException(flavor);
     47        }
     48    }
     49
     50    private String getStringData() {
     51        StringBuilder string = new StringBuilder();
     52        for (Entry<String, String> e : data.getTags().entrySet()) {
     53            if (string.length() > 0) {
     54                string.append("\n");
     55            }
     56            string.append(e.getKey());
     57            string.append("=");
     58            string.append(e.getValue());
     59        }
     60        return string.toString();
     61    }
     62}
  • src/org/openstreetmap/josm/gui/datatransfer/data/TagTransferData.java

    diff --git a/src/org/openstreetmap/josm/gui/datatransfer/data/TagTransferData.java b/src/org/openstreetmap/josm/gui/datatransfer/data/TagTransferData.java
    index d05c010..db1fd10 100644
    a b public class TagTransferData implements Serializable { 
    3939    }
    4040
    4141    /**
     42     * Create a new {@link TagTransferData} object with the given tags.
     43     * @param tags The tags.
     44     * @since xxx
     45     */
     46    public TagTransferData(Map<String, String> tags) {
     47        this.tags.putAll(tags);
     48    }
     49
     50    /**
    4251     * Gets all tags contained in this data.
    4352     * @return The tags.
    4453     */
  • src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java

    diff --git a/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java b/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
    index 08719e1..e30b43f 100644
    a b public class HistoryBrowserModel extends ChangeNotifier implements ActiveLayerCh 
    581581
    582582        @Override
    583583        public Object getValueAt(int row, int column) {
     584            return getKeyAt(row);
     585        }
     586
     587        /**
     588         * Get the key for the given row.
     589         * @param row The row
     590         * @return The key in that row.
     591         * @since xxx
     592         */
     593        public String getKeyAt(int row) {
    584594            return keys.get(row);
    585595        }
    586596
    public class HistoryBrowserModel extends ChangeNotifier implements ActiveLayerCh 
    636646
    637647        @Override
    638648        public int getColumnCount() {
    639             return 1;
     649            return 2;
    640650        }
    641651    }
    642652
  • src/org/openstreetmap/josm/gui/history/SelectionSynchronizer.java

    diff --git a/src/org/openstreetmap/josm/gui/history/SelectionSynchronizer.java b/src/org/openstreetmap/josm/gui/history/SelectionSynchronizer.java
    index 00fa272..e60a354 100644
    a b import javax.swing.event.ListSelectionListener; 
    1212public class SelectionSynchronizer implements ListSelectionListener {
    1313
    1414    private final Set<ListSelectionModel> participants;
     15    private boolean preventRecursion = false;
    1516
    1617    /**
    1718     * Constructs a new {@code SelectionSynchronizer}.
    public class SelectionSynchronizer implements ListSelectionListener { 
    3132
    3233    @Override
    3334    public void valueChanged(ListSelectionEvent e) {
     35        if (preventRecursion) {
     36            return;
     37        }
     38        preventRecursion = true;
    3439        DefaultListSelectionModel referenceModel = (DefaultListSelectionModel) e.getSource();
    3540        int i = referenceModel.getMinSelectionIndex();
    3641        for (ListSelectionModel model : participants) {
    public class SelectionSynchronizer implements ListSelectionListener { 
    3944            }
    4045            model.setSelectionInterval(i, i);
    4146        }
     47        preventRecursion = false;
    4248    }
    4349}
  • new file src/org/openstreetmap/josm/gui/history/TagInfoTransferHandler.java

    diff --git a/src/org/openstreetmap/josm/gui/history/TagInfoTransferHandler.java b/src/org/openstreetmap/josm/gui/history/TagInfoTransferHandler.java
    new file mode 100644
    index 0000000..31b7683
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.history;
     3
     4import java.awt.datatransfer.Clipboard;
     5
     6import javax.swing.JComponent;
     7import javax.swing.JTable;
     8import javax.swing.TransferHandler;
     9import javax.swing.table.TableModel;
     10
     11import org.openstreetmap.josm.data.osm.TagMap;
     12import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
     13import org.openstreetmap.josm.gui.datatransfer.TagTransferable;
     14import org.openstreetmap.josm.gui.datatransfer.data.TagTransferData;
     15import org.openstreetmap.josm.gui.history.HistoryBrowserModel.TagTableModel;
     16
     17/**
     18 * This transfer handler allows to select and copy tags from a table with the {@link TagTableColumnModel}.
     19 * @author Michael Zangl
     20 * @since xxx
     21 */
     22public class TagInfoTransferHandler extends TransferHandler {
     23
     24    @Override
     25    public void exportToClipboard(JComponent comp, Clipboard clip, int action) throws IllegalStateException {
     26        if (comp instanceof JTable) {
     27            TableModel model = ((JTable) comp).getModel();
     28            if (model instanceof TagTableModel) {
     29                exportFromModel((JTable) comp, (TagTableModel) model);
     30            }
     31        }
     32    }
     33
     34    private void exportFromModel(JTable comp, TagTableModel model) {
     35        int[] selected = comp.getSelectedRows();
     36        TagMap tags = new TagMap();
     37        for (int row : selected) {
     38            String key = model.getKeyAt(row);
     39            String value = model.getValue(key);
     40            if (value != null) {
     41                tags.put(key, value);
     42            }
     43        }
     44        TagTransferData data = new TagTransferData(tags);
     45        ClipboardUtils.copy(new TagTransferable(data));
     46    }
     47}
  • src/org/openstreetmap/josm/gui/history/TagInfoViewer.java

    diff --git a/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java b/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java
    index d354dde..4000099 100644
    a b  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.history;
    33
     4import java.awt.event.FocusEvent;
     5import java.awt.event.FocusListener;
     6
    47import javax.swing.JTable;
    58import javax.swing.ListSelectionModel;
    69
    import javax.swing.ListSelectionModel; 
    1518 *
    1619 */
    1720public class TagInfoViewer extends HistoryViewerPanel {
     21    private static final class RepaintOnFocusChange implements FocusListener {
     22        @Override
     23        public void focusLost(FocusEvent e) {
     24            repaintSelected(e);
     25        }
     26
     27        @Override
     28        public void focusGained(FocusEvent e) {
     29            repaintSelected(e);
     30        }
     31
     32        private void repaintSelected(FocusEvent e) {
     33            // we would only need the selected rows, but this is easier:
     34            e.getComponent().repaint();
     35        }
     36    }
     37
     38    /**
     39     * Constructs a new {@code TagInfoViewer}.
     40     * @param model The history browsing model
     41     */
     42    public TagInfoViewer(HistoryBrowserModel model) {
     43        super(model);
     44    }
    1845
    1946    @Override
    2047    protected JTable buildReferenceTable() {
    public class TagInfoViewer extends HistoryViewerPanel { 
    2350                new TagTableColumnModel()
    2451        );
    2552        table.setName("table.referencetagtable");
    26         table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    27         selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
     53        setUpDataTransfer(table);
    2854        return table;
    2955    }
    3056
    public class TagInfoViewer extends HistoryViewerPanel { 
    3561                new TagTableColumnModel()
    3662        );
    3763        table.setName("table.currenttagtable");
    38         table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    39         selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
     64        setUpDataTransfer(table);
    4065        return table;
    4166    }
    4267
    43     /**
    44      * Constructs a new {@code TagInfoViewer}.
    45      * @param model The history browsing model
    46      */
    47     public TagInfoViewer(HistoryBrowserModel model) {
    48         super(model);
     68    private void setUpDataTransfer(JTable table) {
     69        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     70        selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
     71        table.setTransferHandler(new TagInfoTransferHandler());
     72        table.addFocusListener(new RepaintOnFocusChange());
    4973    }
    5074}
  • src/org/openstreetmap/josm/gui/history/TagTableCellRenderer.java

    diff --git a/src/org/openstreetmap/josm/gui/history/TagTableCellRenderer.java b/src/org/openstreetmap/josm/gui/history/TagTableCellRenderer.java
    index a773cae..d6fa655 100644
    a b import org.openstreetmap.josm.gui.util.GuiHelper; 
    1616 *
    1717 */
    1818public class TagTableCellRenderer extends JLabel implements TableCellRenderer {
    19     public static final Color BGCOLOR_SELECTED = new Color(143, 170, 255);
     19    /**
     20     * The background color for a selected row that has the focus.
     21     */
     22    public static final Color BGCOLOR_SELECTED_FOCUS = new Color(0xff8faaff);
     23    /**
     24     * The background color for a selected row while the table is not focused.
     25     */
     26    public static final Color BGCOLOR_SELECTED = new Color(0xffafc2ff);
    2027
    2128    /**
    2229     * Constructs a new {@code TagTableCellRenderer}.
    public class TagTableCellRenderer extends JLabel implements TableCellRenderer { 
    2532        setOpaque(true);
    2633    }
    2734
    28     protected void setBackgroundReadable(String key, HistoryBrowserModel.TagTableModel model, boolean isSelected, boolean isValue) {
     35    protected void setBackgroundReadable(String key, HistoryBrowserModel.TagTableModel model, boolean isSelected, boolean hasFocus, boolean isValue) {
    2936        Color bgColor = UIManager.getColor("Table.background");
    3037        if (!model.hasTag(key) && model.isCurrentPointInTime()
    3138                || !model.oppositeHasTag(key) && model.isReferencePointInTime()) {
    public class TagTableCellRenderer extends JLabel implements TableCellRenderer { 
    3744            bgColor = TwoColumnDiff.Item.DiffItemType.CHANGED.getColor();
    3845        }
    3946        if (isSelected) {
    40             bgColor = BGCOLOR_SELECTED;
     47            if (hasFocus) {
     48                bgColor = BGCOLOR_SELECTED_FOCUS;
     49            } else {
     50                bgColor = BGCOLOR_SELECTED;
     51            }
    4152        }
    4253
    4354        GuiHelper.setBackgroundReadable(this, bgColor);
    public class TagTableCellRenderer extends JLabel implements TableCellRenderer { 
    5364        String key = (String) value;
    5465        HistoryBrowserModel.TagTableModel model = getTagTableModel(table);
    5566
    56         switch(column) {
    57         case 0:
    58             // the name column
    59             setText(model.hasTag(key) ? key : "");
    60             setToolTipText(getText());
    61             setBackgroundReadable(key, model, isSelected, false);
    62             break;
    63         case 1:
    64             // the value column
    65             setText(model.hasTag(key) ? model.getValue(key) : "");
    66             setToolTipText(getText());
    67             setBackgroundReadable(key, model, isSelected, true);
    68             break;
    69         default: // Do nothing
     67        String text = "";
     68        if (model.hasTag(key)) {
     69            switch(column) {
     70            case TagTableColumnModel.COLUMN_KEY:
     71                // the name column
     72                text = key;
     73                break;
     74            case TagTableColumnModel.COLUMN_VALUE:
     75                // the value column
     76                text = model.getValue(key);
     77                break;
     78            default: // Do nothing
     79            }
    7080        }
    7181
     82        setText(text);
     83        setToolTipText(text);
     84        setBackgroundReadable(key, model, isSelected, table.hasFocus(), column == TagTableColumnModel.COLUMN_VALUE);
    7285        return this;
    7386    }
    7487
  • src/org/openstreetmap/josm/gui/history/TagTableColumnModel.java

    diff --git a/src/org/openstreetmap/josm/gui/history/TagTableColumnModel.java b/src/org/openstreetmap/josm/gui/history/TagTableColumnModel.java
    index 0c8eb16..3289439 100644
    a b import javax.swing.table.TableColumn; 
    1111 * @since 1709
    1212 */
    1313public class TagTableColumnModel extends DefaultTableColumnModel {
     14    protected static final int COLUMN_KEY = 0;
     15    protected static final int COLUMN_VALUE = 1;
    1416
    1517    /**
    1618     * Constructs a new {@code TagTableColumnModel}.