001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.gui.conflict.pair.relation;
003    
004    import java.awt.Color;
005    import java.awt.Component;
006    import java.util.ArrayList;
007    import java.util.Collections;
008    
009    import javax.swing.BorderFactory;
010    import javax.swing.JLabel;
011    import javax.swing.JTable;
012    import javax.swing.border.Border;
013    import javax.swing.table.TableCellRenderer;
014    
015    import org.openstreetmap.josm.data.osm.Node;
016    import org.openstreetmap.josm.data.osm.OsmPrimitive;
017    import org.openstreetmap.josm.data.osm.RelationMember;
018    import org.openstreetmap.josm.gui.DefaultNameFormatter;
019    import org.openstreetmap.josm.gui.conflict.ConflictColors;
020    import org.openstreetmap.josm.gui.conflict.pair.ListMergeModel;
021    import org.openstreetmap.josm.tools.ImageProvider;
022    
023    /**
024     * This is the {@link TableCellRenderer} used in the tables of {@link RelationMemberMerger}.
025     *
026     */
027    public  class RelationMemberTableCellRenderer extends JLabel implements TableCellRenderer {
028        private  Border rowNumberBorder = null;
029    
030        /**
031         * constructor
032         */
033        public RelationMemberTableCellRenderer() {
034            setIcon(null);
035            setOpaque(true);
036            rowNumberBorder = BorderFactory.createEmptyBorder(0,4,0,0);
037        }
038    
039        public String buildToolTipText(OsmPrimitive primitive) {
040            StringBuilder sb = new StringBuilder();
041            sb.append("<html>");
042            sb.append("<strong>id</strong>=")
043            .append(primitive.getId())
044            .append("<br>");
045            ArrayList<String> keyList = new ArrayList<String>(primitive.keySet());
046            Collections.sort(keyList);
047            for (int i = 0; i < keyList.size(); i++) {
048                if (i > 0) {
049                    sb.append("<br>");
050                }
051                String key = keyList.get(i);
052                sb.append("<strong>")
053                .append(key)
054                .append("</strong>")
055                .append("=");
056                String value = primitive.get(key);
057                while(value.length() != 0) {
058                    sb.append(value.substring(0,Math.min(50, value.length())));
059                    if (value.length() > 50) {
060                        sb.append("<br>");
061                        value = value.substring(50);
062                    } else {
063                        value = "";
064                    }
065                }
066            }
067            sb.append("</html>");
068            return sb.toString();
069        }
070    
071        /**
072         * reset the renderer
073         */
074        protected void reset() {
075            setBackground(ConflictColors.BGCOLOR.get());
076            setForeground(ConflictColors.FGCOLOR.get());
077            setBorder(null);
078            setIcon(null);
079            setToolTipText(null);
080        }
081    
082        protected void renderBackground(ListMergeModel<Node>.EntriesTableModel model, RelationMember member, int row, int col, boolean isSelected) {
083            Color bgc = ConflictColors.BGCOLOR.get();
084            if (col == 0) {
085                if (model.getListMergeModel().isFrozen()) {
086                    bgc = ConflictColors.BGCOLOR_FROZEN.get();
087                } else if (model.isParticipatingInCurrentComparePair()) {
088                    bgc = ConflictColors.BGCOLOR_PARTICIPAING_IN_COMPARISON.get();
089                } else if (isSelected) {
090                    bgc = ConflictColors.BGCOLOR_SELECTED.get();
091                }
092            } else {
093                if (model.getListMergeModel().isFrozen()) {
094                    bgc = ConflictColors.BGCOLOR_FROZEN.get();
095                } else if (member == null) {
096                    bgc = ConflictColors.BGCOLOR_EMPTY_ROW.get();
097                } else if (isSelected) {
098                    bgc = ConflictColors.BGCOLOR_SELECTED.get();
099                } else {
100                    if (model.isParticipatingInCurrentComparePair()) {
101                        if (model.isSamePositionInOppositeList(row)) {
102                            bgc = ConflictColors.BGCOLOR_SAME_POSITION_IN_OPPOSITE.get();
103                        } else if (model.isIncludedInOppositeList(row)) {
104                            bgc = ConflictColors.BGCOLOR_IN_OPPOSITE.get();
105                        } else {
106                            bgc = ConflictColors.BGCOLOR_NOT_IN_OPPOSITE.get();
107                        }
108                    }
109                }
110            }
111            setBackground(bgc);
112        }
113    
114        protected void renderForeground(ListMergeModel<Node>.EntriesTableModel model, RelationMember member, int row, int col, boolean isSelected) {
115            Color fgc = ConflictColors.FGCOLOR.get();
116            if (col == 0 && model.isParticipatingInCurrentComparePair() && ! model.getListMergeModel().isFrozen()) {
117                fgc = ConflictColors.FGCOLOR_PARTICIPAING_IN_COMPARISON.get();
118            }
119            setForeground(fgc);
120        }
121    
122        protected void renderRole(RelationMember member) {
123            setText(member.getRole());
124            setToolTipText(member.getRole());
125        }
126    
127        protected void renderPrimitive(RelationMember member) {
128            String displayName = member.getMember().getDisplayName(DefaultNameFormatter.getInstance());
129            setText(displayName);
130            setToolTipText(buildToolTipText(member.getMember()));
131            setIcon(ImageProvider.get(member.getDisplayType()));
132        }
133    
134        /**
135         * render the row id
136         * @param row the row index
137         * @param isSelected
138         */
139        protected  void renderRowId(int row) {
140            setBorder(rowNumberBorder);
141            setText(Integer.toString(row+1));
142        }
143    
144        protected void renderEmptyRow() {
145            setIcon(null);
146            setBackground(ConflictColors.BGCOLOR_EMPTY_ROW.get());
147            setText("");
148        }
149    
150        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
151                int row, int column) {
152    
153            RelationMember member = (RelationMember)value;
154            reset();
155            if (member == null) {
156                renderEmptyRow();
157            } else {
158                renderBackground(getModel(table), member, row, column, isSelected);
159                renderForeground(getModel(table), member, row, column, isSelected);
160                switch(column) {
161                case 0:
162                    renderRowId(row);
163                    break;
164                case 1:
165                    renderRole(member);
166                    break;
167                case 2:
168                    renderPrimitive(member);
169                    break;
170                default:
171                    // should not happen
172                }
173            }
174            return this;
175        }
176    
177        /**
178         * replies the model
179         * @param table  the table
180         * @return the table model
181         */
182        @SuppressWarnings("unchecked")
183        protected ListMergeModel<Node>.EntriesTableModel getModel(JTable table) {
184            return (ListMergeModel.EntriesTableModel)table.getModel();
185        }
186    }