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.gui.conflict.ConflictColors; 017import org.openstreetmap.josm.gui.widgets.JosmComboBox; 018import org.openstreetmap.josm.tools.ImageProvider; 019import org.openstreetmap.josm.tools.Logging; 020 021/** 022 * This is a {@link TableCellRenderer} for {@link MultiValueResolutionDecision}s. 023 * 024 */ 025public class MultiValueCellRenderer extends JLabel implements TableCellRenderer { 026 027 private final ImageIcon iconDecided; 028 private final ImageIcon iconUndecided; 029 private final DefaultComboBoxModel<Object> model; 030 private final 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 Logging.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 Logging.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 * @param decision conflict resolution decision 112 */ 113 protected void renderToolTipText(MultiValueResolutionDecision decision) { 114 String toolTipText = null; 115 switch (decision.getDecisionType()) { 116 case UNDECIDED: 117 toolTipText = tr("Please decide which values to keep"); 118 break; 119 case KEEP_ONE: 120 toolTipText = tr("Value ''{0}'' is going to be applied for key ''{1}''", 121 decision.getChosenValue(), decision.getKey()); 122 break; 123 case SUM_ALL_NUMERIC: 124 toolTipText = tr("All numeric values sumed as ''{0}'' are going to be applied for key ''{1}''", 125 decision.getChosenValue(), decision.getKey()); 126 break; 127 case KEEP_NONE: 128 toolTipText = tr("The key ''{0}'' and all its values are going to be removed", decision.getKey()); 129 break; 130 case KEEP_ALL: 131 toolTipText = tr("All values joined as ''{0}'' are going to be applied for key ''{1}''", 132 decision.getChosenValue(), decision.getKey()); 133 break; 134 } 135 setToolTipText(toolTipText); 136 cbDecisionRenderer.setToolTipText(toolTipText); 137 } 138 139 protected void reset() { 140 setFont(UIManager.getFont("Table.font")); 141 setIcon(null); 142 setText(""); 143 } 144 145 @Override 146 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 147 148 reset(); 149 if (value == null) 150 return this; 151 152 MultiValueResolutionDecision decision = (MultiValueResolutionDecision) value; 153 TagConflictResolverModel tagModel = (TagConflictResolverModel) table.getModel(); 154 boolean conflict = tagModel.getKeysWithConflicts().contains(tagModel.getKey(row)); 155 renderColors(decision, isSelected, conflict); 156 renderToolTipText(decision); 157 switch(column) { 158 case 0: 159 if (decision.isDecided()) { 160 setIcon(iconDecided); 161 } else { 162 setIcon(iconUndecided); 163 } 164 return this; 165 166 case 1: 167 setText(decision.getKey()); 168 return this; 169 170 case 2: 171 renderValue(decision); 172 return cbDecisionRenderer; 173 } 174 return this; 175 } 176}