001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs.properties;
003
004import static org.openstreetmap.josm.tools.I18n.marktr;
005import static org.openstreetmap.josm.tools.I18n.tr;
006import static org.openstreetmap.josm.tools.I18n.trn;
007
008import java.awt.Color;
009import java.awt.Component;
010import java.awt.Font;
011import java.util.Map;
012import java.util.Objects;
013
014import javax.swing.JLabel;
015import javax.swing.JTable;
016import javax.swing.UIDefaults;
017import javax.swing.table.DefaultTableCellRenderer;
018
019import org.openstreetmap.josm.Main;
020import org.openstreetmap.josm.data.osm.OsmPrimitive;
021
022/**
023 * Cell renderer of tags table.
024 * @since 6314
025 */
026public class PropertiesCellRenderer extends DefaultTableCellRenderer {
027
028    private void setColors(Component c, String key, boolean isSelected) {
029        UIDefaults defaults = javax.swing.UIManager.getDefaults();
030        if (OsmPrimitive.getDiscardableKeys().contains(key)) {
031            if (isSelected) {
032                c.setForeground(Main.pref.getColor(marktr("Discardable key: selection Foreground"), Color.GRAY));
033                c.setBackground(Main.pref.getColor(marktr("Discardable key: selection Background"),
034                        defaults.getColor("Table.selectionBackground")));
035            } else {
036                c.setForeground(Main.pref.getColor(marktr("Discardable key: foreground"), Color.GRAY));
037                c.setBackground(Main.pref.getColor(marktr("Discardable key: background"), defaults.getColor("Table.background")));
038            }
039        } else {
040            c.setForeground(defaults.getColor("Table."+(isSelected ? "selectionF" : "f")+"oreground"));
041            c.setBackground(defaults.getColor("Table."+(isSelected ? "selectionB" : "b")+"ackground"));
042        }
043    }
044
045    @Override
046    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
047        Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
048        if (value == null)
049            return this;
050        if (c instanceof JLabel) {
051            String str = null;
052            if (value instanceof String) {
053                str = (String) value;
054            } else if (value instanceof Map<?, ?>) {
055                Map<?, ?> v = (Map<?, ?>) value;
056                if (v.size() != 1) {    // Multiple values: give user a short summary of the values
057                    Integer blankCount;
058                    Integer otherCount;
059                    if (v.get("") == null) {
060                        blankCount = 0;
061                        otherCount = v.size();
062                    } else {
063                        blankCount = (Integer) v.get("");
064                        otherCount = v.size()-1;
065                    }
066                    StringBuilder sb = new StringBuilder("<");
067                    if (otherCount == 1) {
068                        for (Map.Entry<?, ?> entry : v.entrySet()) { // Find the non-blank value in the map
069                            if (!Objects.equals(entry.getKey(), "")) {
070                                /* I18n: properties display partial string joined with comma, frst is count, second is value */
071                                sb.append(tr("{0} ''{1}''", entry.getValue().toString(), entry.getKey()));
072                            }
073                        }
074                    } else {
075                        /* I18n: properties display partial string joined with comma */
076                        sb.append(trn("{0} different", "{0} different", otherCount, otherCount));
077                    }
078                    if (blankCount > 0) {
079                        /* I18n: properties display partial string joined with comma */
080                        sb.append(trn(", {0} unset", ", {0} unset", blankCount, blankCount));
081                    }
082                    sb.append('>');
083                    str = sb.toString();
084                    c.setFont(c.getFont().deriveFont(Font.ITALIC));
085
086                } else {                // One value: display the value
087                    final Map.Entry<?, ?> entry = v.entrySet().iterator().next();
088                    str = (String) entry.getKey();
089                }
090            }
091            ((JLabel) c).putClientProperty("html.disable", Boolean.TRUE); // Fix #8730
092            ((JLabel) c).setText(str);
093            if (Main.pref.getBoolean("display.discardable-keys", false)) {
094                String key = null;
095                if (column == 0) {
096                    key = str;
097                } else if (column == 1) {
098                    Object value0 = table.getModel().getValueAt(row, 0);
099                    if (value0 instanceof String) {
100                        key = (String) value0;
101                    }
102                }
103                setColors(c, key, isSelected);
104            }
105        }
106        return c;
107    }
108}