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}''", decision.getChosenValue(), decision.getKey()); 120 break; 121 case SUM_ALL_NUMERIC: 122 toolTipText = tr("All numeric values sumed as ''{0}'' are going to be applied for key ''{1}''", decision.getChosenValue(), decision.getKey()); 123 break; 124 case KEEP_NONE: 125 toolTipText = tr("The key ''{0}'' and all its values are going to be removed", decision.getKey()); 126 break; 127 case KEEP_ALL: 128 toolTipText = tr("All values joined as ''{0}'' are going to be applied for key ''{1}''", decision.getChosenValue(), decision.getKey()); 129 break; 130 } 131 setToolTipText(toolTipText); 132 cbDecisionRenderer.setToolTipText(toolTipText); 133 } 134 135 protected void reset() { 136 setFont(UIManager.getFont("Table.font")); 137 setIcon(null); 138 setText(""); 139 } 140 141 @Override 142 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 143 144 reset(); 145 if (value == null) 146 return this; 147 148 MultiValueResolutionDecision decision = (MultiValueResolutionDecision)value; 149 TagConflictResolverModel tagModel = (TagConflictResolverModel) table.getModel(); 150 boolean conflict = tagModel.getKeysWithConflicts().contains(tagModel.getKey(row)); 151 renderColors(decision, isSelected, conflict); 152 renderToolTipText(decision); 153 switch(column) { 154 case 0: 155 if (decision.isDecided()) { 156 setIcon(iconDecided); 157 } else { 158 setIcon(iconUndecided); 159 } 160 return this; 161 162 case 1: 163 setText(decision.getKey()); 164 return this; 165 166 case 2: 167 renderValue(decision); 168 return cbDecisionRenderer; 169 } 170 return this; 171 } 172}