001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.gui.tagging;
003    
004    import java.awt.Component;
005    
006    import javax.swing.AbstractCellEditor;
007    import javax.swing.BorderFactory;
008    import javax.swing.JTable;
009    import javax.swing.table.TableCellEditor;
010    
011    import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingTextField;
012    import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
013    import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
014    
015    /**
016     * This is the table cell editor for the tag editor dialog.
017     *
018     */
019    @SuppressWarnings("serial")
020    public class TagCellEditor extends AbstractCellEditor implements TableCellEditor{
021    
022        protected AutoCompletingTextField editor = null;
023        protected TagModel currentTag = null;
024    
025        /** the cache of auto completion items derived from the current JOSM data set */
026        protected AutoCompletionManager autocomplete = null;
027    
028        /** user input is matched against this list of auto completion items */
029        protected AutoCompletionList autoCompletionList = null;
030    
031        /**
032         * constructor
033         */
034        public TagCellEditor() {
035            editor = new AutoCompletingTextField();
036            editor.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
037        }
038    
039        /**
040         * initializes  the auto completion list when the table cell editor starts
041         * to edit the key of a tag. In this case the auto completion list is
042         * initialized with the set of standard key values and the set of current key
043         * values from the current JOSM data set. Keys already present in the
044         * current tag model are removed from the auto completion list.
045         *
046         * @param model  the tag editor model
047         * @param currentTag  the current tag
048         */
049        protected void initAutoCompletionListForKeys(TagEditorModel model, TagModel currentTag) {
050    
051            if (autoCompletionList == null)
052                return;
053            autoCompletionList.clear();
054    
055            // add the list of keys in the current data set
056            //
057            autocomplete.populateWithKeys(autoCompletionList);
058    
059            // remove the keys already present in the current tag model
060            //
061            for (String key : model.getKeys()) {
062                if (! key.equals(currentTag.getName())) {
063                    autoCompletionList.remove(key);
064                }
065            }
066            autoCompletionList.fireTableDataChanged();
067        }
068    
069        /**
070         * initializes the auto completion list when the cell editor starts to edit
071         * a tag value. In this case the auto completion list is initialized with the
072         * set of standard values for a given key and the set of values present in the
073         * current data set for the given key.
074         *
075         * @param forKey the key
076         */
077        protected void initAutoCompletionListForValues(String forKey) {
078            if (autoCompletionList == null) {
079                return;
080            }
081            autoCompletionList.clear();
082            autocomplete.populateWithTagValues(autoCompletionList, forKey);
083        }
084    
085        /**
086         * replies the table cell editor
087         */
088        public Component getTableCellEditorComponent(JTable table,
089                Object value, boolean isSelected, int row, int column) {
090            currentTag = (TagModel) value;
091    
092            // no autocompletion for initial editor#setText()
093            if(autoCompletionList != null) {
094                autoCompletionList.clear();
095            }
096            if (column == 0) {
097                editor.setText(currentTag.getName());
098                TagEditorModel model = (TagEditorModel)table.getModel();
099                initAutoCompletionListForKeys(model, currentTag);
100                return editor;
101            } else if (column == 1) {
102    
103                if (currentTag.getValueCount() == 0) {
104                    editor.setText("");
105                } else if (currentTag.getValueCount() == 1) {
106                    editor.setText(currentTag.getValues().get(0));
107                } else {
108                    editor.setText("");
109                }
110                initAutoCompletionListForValues(currentTag.getName());
111                return editor;
112            } else {
113                return null;
114            }
115        }
116    
117        public Object getCellEditorValue() {
118            return editor.getText();
119        }
120    
121        /**
122         * replies the {@link AutoCompletionList} this table cell editor synchronizes with
123         *
124         * @return the auto completion list
125         */
126        public AutoCompletionList getAutoCompletionList() {
127            return autoCompletionList;
128        }
129    
130        /**
131         * sets the {@link AutoCompletionList} this table cell editor synchronizes with
132         * @param autoCompletionList the auto completion list
133         */
134        public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
135            this.autoCompletionList = autoCompletionList;
136            editor.setAutoCompletionList(autoCompletionList);
137        }
138    
139        public void setAutoCompletionManager(AutoCompletionManager autocomplete) {
140            this.autocomplete = autocomplete;
141        }
142    
143        public void autoCompletionItemSelected(String item) {
144            editor.setText(item);
145            editor.selectAll();
146            editor.requestFocus();
147        }
148    
149        public AutoCompletingTextField getEditor() {
150            return editor;
151        }
152    }