001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.conflict.tags; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Component; 007import java.awt.Font; 008 009import javax.swing.DefaultComboBoxModel; 010import javax.swing.ImageIcon; 011import javax.swing.JLabel; 012import javax.swing.JTable; 013import javax.swing.UIManager; 014import javax.swing.table.TableCellRenderer; 015 016import org.openstreetmap.josm.Main; 017import org.openstreetmap.josm.gui.conflict.ConflictColors; 018import org.openstreetmap.josm.gui.widgets.JosmComboBox; 019import org.openstreetmap.josm.tools.ImageProvider; 020 021/** 022 * This is a {@link TableCellRenderer} for {@link MultiValueResolutionDecision}s. 023 * 024 */ 025public class MultiValueCellRenderer extends JLabel implements TableCellRenderer { 026 027 private ImageIcon iconDecided; 028 private ImageIcon iconUndecided; 029 private DefaultComboBoxModel<Object> model; 030 private JosmComboBox<Object> cbDecisionRenderer; 031 032 /** 033 * Constructs a new {@code MultiValueCellRenderer}. 034 */ 035 public MultiValueCellRenderer() { 036 setOpaque(true); 037 iconDecided = ImageProvider.get("dialogs/conflict", "tagconflictresolved"); 038 iconUndecided = ImageProvider.get("dialogs/conflict", "tagconflictunresolved"); 039 model = new DefaultComboBoxModel<>(); 040 cbDecisionRenderer = new JosmComboBox<>(model); 041 } 042 043 protected void renderColors(MultiValueResolutionDecision decision, boolean selected, boolean conflict) { 044 if (selected) { 045 setForeground(UIManager.getColor("Table.selectionForeground")); 046 setBackground(UIManager.getColor("Table.selectionBackground")); 047 } else { 048 switch (decision.getDecisionType()) { 049 case UNDECIDED: 050 setForeground(ConflictColors.FGCOLOR_UNDECIDED.get()); 051 setBackground(ConflictColors.BGCOLOR_UNDECIDED.get()); 052 break; 053 case KEEP_NONE: 054 setForeground(ConflictColors.FGCOLOR_TAG_KEEP_NONE.get()); 055 setBackground(ConflictColors.BGCOLOR_TAG_KEEP_NONE.get()); 056 break; 057 default: 058 if (conflict) { 059 switch (decision.getDecisionType()) { 060 case KEEP_ONE: 061 setForeground(ConflictColors.FGCOLOR_TAG_KEEP_ONE.get()); 062 setBackground(ConflictColors.BGCOLOR_TAG_KEEP_ONE.get()); 063 break; 064 case KEEP_ALL: 065 setForeground(ConflictColors.FGCOLOR_TAG_KEEP_ALL.get()); 066 setBackground(ConflictColors.BGCOLOR_TAG_KEEP_ALL.get()); 067 break; 068 case SUM_ALL_NUMERIC: 069 setForeground(ConflictColors.FGCOLOR_TAG_SUM_ALL_NUM.get()); 070 setBackground(ConflictColors.BGCOLOR_TAG_SUM_ALL_NUM.get()); 071 break; 072 default: 073 Main.error("Unknown decision type in renderColors(): "+decision.getDecisionType()); 074 } 075 } else { 076 setForeground(UIManager.getColor("Table.foreground")); 077 setBackground(UIManager.getColor("Table.background")); 078 } 079 break; 080 } 081 } 082 } 083 084 protected void renderValue(MultiValueResolutionDecision decision) { 085 model.removeAllElements(); 086 switch (decision.getDecisionType()) { 087 case UNDECIDED: 088 model.addElement(tr("Choose a value")); 089 cbDecisionRenderer.setFont(getFont().deriveFont(Font.ITALIC)); 090 cbDecisionRenderer.setSelectedIndex(0); 091 break; 092 case KEEP_NONE: 093 model.addElement(tr("deleted")); 094 cbDecisionRenderer.setFont(getFont().deriveFont(Font.ITALIC)); 095 cbDecisionRenderer.setSelectedIndex(0); 096 break; 097 case KEEP_ONE: 098 case KEEP_ALL: 099 case SUM_ALL_NUMERIC: 100 model.addElement(decision.getChosenValue()); 101 cbDecisionRenderer.setFont(getFont()); 102 cbDecisionRenderer.setSelectedIndex(0); 103 break; 104 default: 105 Main.error("Unknown decision type in renderValue(): "+decision.getDecisionType()); 106 } 107 } 108 109 /** 110 * Sets the text of the tooltip for both renderers, this (the JLabel) and the combobox renderer. 111 */ 112 protected void renderToolTipText(MultiValueResolutionDecision decision) { 113 String toolTipText = null; 114 switch (decision.getDecisionType()) { 115 case UNDECIDED: 116 toolTipText = tr("Please decide which values to keep"); 117 break; 118 case KEEP_ONE: 119 toolTipText = tr("Value ''{0}'' is going to be applied for key ''{1}''", 120 decision.getChosenValue(), decision.getKey()); 121 break; 122 case SUM_ALL_NUMERIC: 123 toolTipText = tr("All numeric values sumed as ''{0}'' are going to be applied for key ''{1}''", 124 decision.getChosenValue(), decision.getKey()); 125 break; 126 case KEEP_NONE: 127 toolTipText = tr("The key ''{0}'' and all its values are going to be removed", decision.getKey()); 128 break; 129 case KEEP_ALL: 130 toolTipText = tr("All values joined as ''{0}'' are going to be applied for key ''{1}''", 131 decision.getChosenValue(), decision.getKey()); 132 break; 133 } 134 setToolTipText(toolTipText); 135 cbDecisionRenderer.setToolTipText(toolTipText); 136 } 137 138 protected void reset() { 139 setFont(UIManager.getFont("Table.font")); 140 setIcon(null); 141 setText(""); 142 } 143 144 @Override 145 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 146 147 reset(); 148 if (value == null) 149 return this; 150 151 MultiValueResolutionDecision decision = (MultiValueResolutionDecision) value; 152 TagConflictResolverModel tagModel = (TagConflictResolverModel) table.getModel(); 153 boolean conflict = tagModel.getKeysWithConflicts().contains(tagModel.getKey(row)); 154 renderColors(decision, isSelected, conflict); 155 renderToolTipText(decision); 156 switch(column) { 157 case 0: 158 if (decision.isDecided()) { 159 setIcon(iconDecided); 160 } else { 161 setIcon(iconUndecided); 162 } 163 return this; 164 165 case 1: 166 setText(decision.getKey()); 167 return this; 168 169 case 2: 170 renderValue(decision); 171 return cbDecisionRenderer; 172 } 173 return this; 174 } 175}