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 default: 069 Main.error("Unknown decision type: "+decision.getDecisionType()); 070 } 071 } else { 072 setForeground(UIManager.getColor("Table.foreground")); 073 setBackground(UIManager.getColor("Table.background")); 074 } 075 break; 076 } 077 } 078 } 079 080 protected void renderValue(MultiValueResolutionDecision decision) { 081 model.removeAllElements(); 082 switch (decision.getDecisionType()) { 083 case UNDECIDED: 084 model.addElement(tr("Choose a value")); 085 cbDecisionRenderer.setFont(getFont().deriveFont(Font.ITALIC)); 086 cbDecisionRenderer.setSelectedIndex(0); 087 break; 088 case KEEP_ONE: 089 model.addElement(decision.getChosenValue()); 090 cbDecisionRenderer.setFont(getFont()); 091 cbDecisionRenderer.setSelectedIndex(0); 092 break; 093 case KEEP_NONE: 094 model.addElement(tr("deleted")); 095 cbDecisionRenderer.setFont(getFont().deriveFont(Font.ITALIC)); 096 cbDecisionRenderer.setSelectedIndex(0); 097 break; 098 case KEEP_ALL: 099 model.addElement(decision.getChosenValue()); 100 cbDecisionRenderer.setFont(getFont()); 101 cbDecisionRenderer.setSelectedIndex(0); 102 break; 103 } 104 } 105 106 /** 107 * Sets the text of the tooltip for both renderers, this (the JLabel) and the combobox renderer. 108 */ 109 protected void renderToolTipText(MultiValueResolutionDecision decision) { 110 String toolTipText; 111 switch (decision.getDecisionType()) { 112 case UNDECIDED: 113 toolTipText = tr("Please decide which values to keep"); 114 setToolTipText(toolTipText); 115 cbDecisionRenderer.setToolTipText(toolTipText); 116 break; 117 case KEEP_ONE: 118 toolTipText = tr("Value ''{0}'' is going to be applied for key ''{1}''", decision.getChosenValue(), decision.getKey()); 119 setToolTipText(toolTipText); 120 cbDecisionRenderer.setToolTipText(toolTipText); 121 break; 122 case KEEP_NONE: 123 toolTipText = tr("The key ''{0}'' and all its values are going to be removed", decision.getKey()); 124 setToolTipText(toolTipText); 125 cbDecisionRenderer.setToolTipText(toolTipText); 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 setToolTipText(toolTipText); 130 cbDecisionRenderer.setToolTipText(toolTipText); 131 break; 132 } 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}